2015-03-30 17 views
8

Attualmente sto usando Polymer come framework di sviluppo front-end. Adoro SASS. Ora capisco che posso creare un file Sass e importarlo come farei normalmente.Come utilizzare Sass all'interno di un componente Polymer

Tuttavia, ho davvero preso l'abitudine di utilizzare i tag di stile all'interno dei miei componenti web.

Fondamentalmente il flusso di lavoro che sto cercando è quello di poter semplicemente definire un tag di script all'interno del mio componente Web, magari aggiungendo type = 'sass; ad esso. Quindi far passare il grunt e compilare tutto il mio SASS all'interno di quei tag prima di inviare i file alla mia directory .tmp.

È qualcosa del genere realizzabile con qualcosa come Grunt o Gulp? Se sì, quali sono i migliori moduli per aiutarmi a raggiungere questo obiettivo?

+0

Hai controllato la mia risposta? La domanda era tempo fa ma volevo condividerla con te! –

+0

Si potrebbe ottenere ciò che si sta facendo con molto meno lavoro. Il punto di questa domanda era di non avere un foglio di stile separato. – endy

+0

@endy Come hai risolto il problema? Per favore, condividi con noi! – falsarella

risposta

9

La mia implementazione si basa sulla sostituzione di un tag all'interno del file html Polymer. Sto usando gulp ma potrebbe essere cambiato per usare semplicemente fs.

La struttura dei file dovrebbe essere come questo esempio:

app-view 
|- app-view.html 
|- app-view.scss 

app-view.html:

<dom-module id="app-view"> 
    <template> 
     <style> 
      <!-- inject{scss} --> 
     </style> 
    </template> 
</dom-module> 

app-view.scss:

:host{ 
    margin-top: 50px; 
    justify-content: center; 
    display: flex; 
} 
#container{ 
    font-size: 12px; 
    h1{ 
     font-size: 20px; 
    } 
} 

gulpfile.js:

var gulp = require('gulp'); 
var nodeSass = require('node-sass'); 
var path = require('path'); 
var fs = require('fs'); 
var map = require('map-stream'); 
var srcPath = 'src/'; 
var buildPath = 'build/'; 
var buildSrcPath = path.join(buildPath, 'target'); 

gulp.task('processComponents', function() { 
    return gulp.src([srcPath + '/components/**/*.html']) 
     .pipe(map(function (file, cb) { 
      var injectString = '<!-- inject{scss} -->'; 
      // convert file buffer into a string 
      var contents = file.contents.toString(); 
      if (contents.indexOf(injectString) >= 0) { 
       //Getting scss 
       var scssFile = file.path.replace(/\.html$/i, '.scss'); 
       fs.readFile(scssFile, function (err, data) { 
        if (!err && data) { 
         nodeSass.render({ 
          data: data.toString(), 
          includePaths: [path.join(srcPath, 'style/')], 
          outputStyle: 'compressed' 
         }, function (err, compiledScss) { 
          if (!err && compiledScss) { 
           file.contents = new Buffer(contents.replace(injectString, compiledScss.css.toString()), 'binary'); 
          } 
          return cb(null, file); 
         }); 
        } 
        return cb(null, file); 
       }); 
      } else { 
       // continue 
       return cb(null, file); 
      } 
     })) 
     .pipe(gulp.dest(path.join(buildSrcPath, 'components'))); 
}); 

RISULTATO:

<dom-module id="app-view"> 
    <template> 
     <style> 
      :host{margin-top:50px;justify-content:center;display:flex}#container{font-size:12px}#container h1{font-size:20px} 
     </style> 
    </template> 
</dom-module> 
+0

il primo ** return cb (null, file); ** restituisce solo dal callback nodeSass.render, il secondo ** return cb (null, file); ** must essere dentro un altro blck o sarà anche chiamato. – sergimassaneda

+0

@sergimassaneda: ho notato quello che hai detto, e la cosa incredibile è che se lo rimuoviamo, il file non viene analizzato! Alla fine della giornata questo script restituisce ogni file alla pipe e sostituisce ogni HTML !!! –

+0

@sergimassaneda: sono tornato. Pubblicherò con un aggiornamento. Ho modificato la soluzione di David Vega. È più pulito in questo modo. Abbiamo bisogno infatti di restituire cb() o copierà il file !! –

2

Prima di tutto, un milione di Grazie e gratitudine va a David Vega per mostrare come è fatto! Ho apportato alcuni adattamenti e ottimizzato il codice un po '.

Ecco il github per il file! https://github.com/superjose/polymer-sass/tree/master

Bene, mi ci è voluto un po '. Eccolo!

Versione libera polimero 1.1. From its website:

Nota: i moduli di stile sono stati introdotti in Polymer 1.1; sostituiscono il supporto sperimentale per fogli di stile esterni.

Al contrario, ora supportano "stili condivisi".

Quindi questo significa che possiamo importare file .html con contenuto css. Il problema è che non possiamo fare .assolutamente.

Fortunatamente ecco una soluzione più semplice.

Quello che fa il seguente script è che ottiene i file .scss, li analizza e li inserisce nello stile condiviso .html.

Ecco il codice. Sotto di essa, è passo dopo passo su come usare e configurare:

var gulp = require('gulp'); 
var nodeSass = require('node-sass'); 
var path = require('path'); 
var fs = require('fs'); 
var map = require('map-stream'); 
var basePath = "app/"; 
var excludeDir = basePath+"bower_components/"; 
var ext = "**/*.html"; 

/** 
* We need to specify to nodeSass the include paths for Sass' @import 
* command. These are all the paths that it will look for it. 
* 
* Failing to specify this, will NOT Compile your scss and inject it to 
* your .html file. 
* 
*/ 
var includePaths = ['app/elements/**/']; 

gulp.task('watchSass', function(){ 
    gulp.watch(['app/**/*.scss', '!app/bower_components/**/*.scss'], ["injectSass"]); 
}); 




//This is currently not used. But you can enable by uncommenting 
// " //return gulp.src([basePath+ext,...excludeDirs])" above the return. 
var excludeDirs = [`!${basePath}/bower_components/${ext}`,`!${basePath}/images/${ext}`] 
/** 
* 
* Enable for advanced use: 
* 
* 
*/ 

gulp.task('injectSass', function() { 
    /* Original creator: David Vega. I just modified 
    * it to take advantage of the Polymer 1.1's shared styles. 
    * 
    * This will look all the files that are inside: 
    * app/elements folder. You can change this to match 
    * your structure. Note, this gulp script uses convention 
    * over configuration. This means that if you have a file called 
    * my-element-styles.html you should have a file called 
    * my-element-styles.scss 
    * 
    * Note #2: 
    * We use "!" (Exclamation Mark) to exclude gulp from searching these paths. 
    * What I'm doing here, is that Polymer Starter Kit has inside its app folder 
    * all the bower dependencies (bower_components). If we don't specify it to 
    * exclude this path, this will look inside bower_components and will take a long time 
    * (around 7.4 seconds in my machine) to replace all the files. 
    */ 
    //Uncomment if you want to specify multiple exclude directories. Uses ES6 spread operator. 
    //return gulp.src([basePath+ext,...excludeDirs]) 
    return gulp.src([basePath+ext, '!'+excludeDir+ext]) 
     .pipe(map(function (file, cb) { 
      //This will match anything between the Start Style and End Style HTML comments. 
      var startStyle = "<!-- Start Style -->"; 
      var endStyle = "<!-- End Style -->"; 
      //Creates the regEx this ways so I can pass the variables. 
      var regEx = new RegExp(startStyle+"[\\s\\S]*"+endStyle, "g"); 

      // Converts file buffer into a string 
      var contents = file.contents.toString(); 


      //Checks if the RegEx exists in the file. If not, 
      //don't do anything and return. 

      //Rewrote the if for reduced nesting. 
      if (!regEx.test(contents)) { 
       //Return empty. if we return cb(null, file). It will add 
       //the file that we do not want to the pipeline!! 
       return cb(); 
      } 
      /** 
      * Getting scss 
      * This will get the .html file that matches the current name 
      * This means that if you have my-app.component.html 
      * this will match my-app.component.scss. Replace with .sass if you 
      * have .sass files instead. 
      */ 
       var scssFile = file.path.replace(/\.html$/i, '.scss'); 

       fs.readFile(scssFile, function (err, data) { 

        //Rewrote the if for reduced nesting. 
        //If error or there is no Sass, return null. 
        if (err || !data) { 
         return cb(); 
        } 
        nodeSass.render({ 
          data: data.toString(), 
          includePaths: [path.join('app', 'style/'), ...includePaths], 
          outputStyle: 'compressed' 
         }, function (err, compiledScss) { 


          //Rewrote the if for reduced nesting. 
          //If error or there is no Sass, return null. 
          if (err || !compiledScss) 
           return cb(); 
           /** 
           * What we are doing here is simple: 
           * We are re-creating the start and end placeholders 
           * that we had and inject them back to the .html file 
           * 
           * This will allow us to re-inject any changes that we 
           * do to our .scss or files. 
           * 
           */ 
           var injectSassContent = startStyle + 
            "<style>" + 
            compiledScss.css.toString() + 
            "</style>" + 
            endStyle; 

           //This is going to replace everything that was between the <!-- Start Style --> and 
           // "<!-- End Style -->" 
           file.contents = new Buffer(contents.replace(regEx, injectSassContent), 'binary'); 
           //This return is necessary, or the modified map will not be modified! 
           return cb(null,file); 
        }); 
       }); 
      })) 
     .pipe(gulp.dest(basePath)); 
}); //Ends 

1) Imposta il tuo elemento:

Supponiamo di avere un elemento chiamato "eroe-torneo":

<dom-module id="hero-tournament"> 
    <template> 
    <style> 

    </style> 

    </template> 

    <script> 
    (function() { 
     'use strict'; 

     Polymer({ 
     is: 'hero-tournament', 
     }); 
    })(); 
    </script> 
</dom-module> 

E si desidera iniettare il file .scss in esso.

Creare Oltre esso due nuovi file:

hero-tournament-style.html 
hero-tournament-style.scss 

All'interno del primo file, eroe-torneo-style.html scrivere il seguente:

<!-- hero-tournament-style.html --> 
<dom-module id="hero-tournament-style"> 
    <template> 
    <!-- Start Style --> 
<style> 
</style> 
<!-- End Style --> 
    </template> 
</dom-module> 

Nota del:

<!-- Start Style --> <!-- End Style --> 

commenti?

Questi sono SUPER importante, poiché tutti i CSS andranno all'interno di questi. Sono sensibili al maiuscolo/minuscolo, ma non sono sensibili alla posizione. Assicurati di includerli nello all'interno dei tag e all'esterno dei tag di stile.

Poi sul vostro file eroe-torneo-style.scss, inserisci la tua sass' css: (Esempio)

.blank{ 
     display: none; 
    } 

2) Eseguire Gulp:

gulp watchSass 

Bam! Vedrai che il tuo file "hero-tournament-style.scss" verrà sovrascritto con i tuoi css !!!

<!-- -hero-tournament-style.html --> 
<dom-module id="-hero-tournament-style"> 
    <template> 
<!-- Start Style --> 
<style>.blank{display:none} 
</style><!-- End Style --> 
    </template> 
</dom-module> 

Ora puoi fare riferimento a quel file ovunque !!! Ricorda il tuo primo elemento, quello originale ("hero-tournament.html")? Effettuare le seguenti operazioni ad esso:

<!-- import the module --> 
<link rel="import" href="../path-to-my-element/.html"> 
<dom-module id="hero-tournament"> 
    <template> 
    <!-- include the style module by name --> 
<style include="hero-tournament-styles"></style> 

    </template> 

    <script> 
    (function() { 
     'use strict'; 

     Polymer({ 
     is: 'hero-tournament', 
     }); 
    })(); 
    </script> 
</dom-module> 

Alcune ultime note:

Uso SASS Importazioni Utilizzando importazioni Sass è facile, solo bisogno di guardare fuori per i seguenti:

Nel gulpfile c'è una variabile chiamata: "includePaths". È una matrice in cui nodeSass cercherà tutte le importazioni. Se non si specifica la propria importazione in uno dei luoghi menzionati, lo impedirà al file di iniettare e compilare. Di default, nello script c'è una directory 'app/style' che la cercherà.

Struttura cartella La struttura delle cartelle è importante e può essere adattata a proprio piacimento. Questo presuppone che gli elementi sono all'interno di una "app" fratello cartella sul gulpfile (nella stessa gerarchia):

-gulpfile.js 
/app 
    /element 
     /hero-tournament 
      -hero-tournament.html 
      -hero-tournament-styles.html 
      -hero-tournament-styles.scss 
    /maybe-other-folder 

Se si desidera cambiare la struttura delle cartelle, modificare la variabile "basePath". Assicurati di controllare la presenza di "/" in modo da non rovinare la tua struttura!

Come si esegue il mio gulpfile? È facile: Chiama il metodo "watchSass" per la visione o "injectSass" per usarlo una volta.

gulp watchSass 

gulp injectSass 

Ulteriori informazioni nella pagina Github !!!

+0

È aggiornato? Ho provato e non ha funzionato. Forse è stata colpa mia. –

+0

@AndreaSantana: Helo! Qual è il tuo problema attuale? Quale versione di Polymer stai usando? E stai usando un linter per verificare eventuali errori? –

+0

Ehi, scusa, ero di fretta e ho finito per usare qualcos'altro. Non ricordo i dettagli però. Sto usando Poymer CLI 0.18.1. –

0

In Polymer 2.0 è anche possibile importare solo un foglio di stile all'interno modello dell'elemento del genere:

<dom-module id="your-module-name"> 
    <template> 
     <style><!-- you can also add additional styling in here --></style> 
     <link rel="stylesheet" href="link_to_stylesheet.css"> 
     <!-- your template in here --> 
    </template> 
    <script> 
    //your element class + registration here 
    </script> 
</dom-module> 

All'interno del foglio di stile è possibile lo stile suo sito web, proprio come nello stile-tag. Gli stili influenzano solo l'elemento e il suo contenuto. Se si desidera utilizzare SASS, Stylus, LESS o qualcosa del genere, è sufficiente utilizzare un middleware (HOWTO: Stack Overflow) in Express che esegue il rendering del codice SASS in CSS su ogni richiesta. Preferisco questa soluzione rispetto all'attività GULP/GRUNT, perché ritengo sia molto più semplice, perché non è sempre necessario eseguire l'attività, poiché il middleware si sta compilando automaticamente ogni volta che è necessario.

Spero che ti aiuti

Problemi correlati