如何在Polymer组件中使用Sass

时间:2015-03-30 19:16:07

标签: css sass gruntjs gulp polymer

我目前正在使用Polymer作为我的前端开发框架。我喜欢SASS。 现在我明白我可以像往常一样创建一个Sass文件并导入它。

但是,我已经养成了在我的网络组件中使用样式标签的习惯。

基本上我正在寻找的工作流程是能够在我的Web组件中简单地定义一个脚本标签,可以添加type =' sass;它。然后让grunt通过并在将这些文件输出到我的.tmp目录之前编译我的所有SASS。

像Grunt或Gulp这样的东西是可以实现的吗?如果是这样,那么帮助我实现这一目标的最佳模块是什么?

2 个答案:

答案 0 :(得分:2)

首先,我要感谢David Vega一百万的感谢和感谢,以表明它是如何完成的!我做了一些调整并对代码进行了一些优化。

这是文件的github! https://github.com/superjose/polymer-sass/tree/master

嗯,这花了我一段时间。在这里!

Polymer unleashed version 1.1。 From its website

  

注意:样式模块在Polymer 1.1中引入;他们取代了   外部样式表的实验支持。

相反,他们现在支持"共享样式"。

这意味着我们可以使用css内容导入.html文件。问题在于我们不能正常地做到这一点。

幸运的是,这是一个更简单的解决方案。

以下脚本的作用是获取.scss文件,解析它们并将它们注入共享样式.html。

这是代码。在它下面,它是如何使用和设置的一步一步:

    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)设置您的元素:

假设您有一个名为&#34; hero-tournament&#34;的元素:

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

    </style>

  </template>

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

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

并且您想要将.scss文件注入其中。

除此之外创建两个新文件:

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

在第一个文件中,hero-tournament-style.html编写以下内容:

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

请注意:

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

评论?

这些非常重要,因为所有的css都会进入这些内部。这些区分大小写,但不区分位置敏感。请务必在样式标记之外添加 标记。

然后在你的hero-tournament-style.scss文件中,加入你的sass&#39; CSS: (实施例)

 .blank{
      display: none;
    }

2)运行Gulp:

gulp watchSass

的Bam!你会看到你的&#34; hero-tournament-style.scss&#34;文件将被你的css覆盖!!!

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

现在,您可以在任何地方推荐该文件!记住你的第一个元素,原始元素(&#34; hero-tournament.html&#34;)?执行以下操作:

<!-- 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>

最后一些注意事项:

使用SASS Imports 使用Sass导入很简单,只需要注意以下几点:

在gulpfile中有一个名为:&#34; includePaths&#34;的变量。它是一个数组,nodeSass将在其中查找所有导入。如果未在上述任何位置指定导入,将阻止您的文件注入和编译。默认情况下,在脚本中有一个&#39; app / style&#39;将寻找它的目录。

文件夹结构 文件夹结构很重要,可以根据自己的喜好进行调整。 这假设您的元素位于&#34; app&#34;文件夹兄弟到你的gulpfile(在同一层次结构中):

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

如果要更改文件夹结构,请更改&#34; basePath&#34;变量。一定要检查领先&#34; /&#34;所以你不要弄乱你的结构!

如何运行gulpfile? 这很简单: 拨打&#34; watchSass&#34;用于观看的方法,或者&#34; injectSass&#34;使用它一次。

gulp watchSass

gulp injectSass

github页面中的更多信息!!!

答案 1 :(得分:0)

在Polymer 2.0中,也可以像这样在元素模板中导入样式表:

<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>

在样式表的内部,您可以像在样式标记中一样设置内容的样式。样式仅影响元素及其内容。 如果您想使用SASS,Stylus,LESS或类似的东西,您只需在Express中使用中间件(HOWTO:Stack Overflow),在每次请求时将SASS代码呈现为CSS。我更喜欢这个解决方案而不是GULP / GRUNT任务,因为我认为它更容易,因为你不必总是运行任务,因为中间件它会在需要时自动编译。

我希望能帮到你