Gulp - 想要将SCSS变量注入另一个文件

时间:2017-03-21 12:03:38

标签: gulp gulp-sass

更新 - 请参阅下面的其他信息,于3月22日添加...

我想用我的Gulp进程将SCSS变量注入到代码文件中。

我认为这是两个步骤:

  1. 吞下SCSS _variables.scss文件以便我可以访问变量

  2. 只需做一个简单的gulp.replace来做一个字符串替换并删除 变量值到我的文件中(如答案here

  3. 我坚持第1步。这就是我所拥有的...我能说的最好,没有大量记录的gulp-sass-variables插件应该将变量从SCSS文件中提取到argv对象中。所以我按照该插件页面上的示例进行了尝试:

    gulp.task('test', function () {
        gulp.src('sass/*')
            .pipe(plugins.print())
            .pipe(plugins.sassVariables({
                $foundIt: argv.testSassVar
            }))
    
        console.log(argv);
    
    });
    

    print()调用只是为了确认它正在读取我的SCSS文件(它是)。但它在我的SCSS代码中找不到$testSassVar,正如您可以从此错误消息中看到的那样:

    [12:53:04] Using gulpfile ~/dev/project/gulpfile.js
    [12:53:04] Starting 'test'...
    [12:53:04] 'test' errored after 15 ms
    [12:53:04] ReferenceError: testSassVar is not defined
        at Gulp.<anonymous> (...)
    [12:53:04] sass/_mixins.scss        <- this line and all below are from print()
    [12:53:04] sass/_normalize.scss
    [12:53:04] sass/_variables.scss
    [12:53:04] sass/footer
    [12:53:04] sass/header
    [12:53:04] sass/landing
    [12:53:04] sass/landing-style.scss
    [12:53:04] sass/site
    [12:53:04] sass/style.scss
    

    我尝试删除$foundIt赋值,只是尝试填充argv对象,但最终会输出一个空数组:

    [13:00:57] Using gulpfile ~/dev/project/gulpfile.js
    [13:00:57] Starting 'test'...
    { _: [ 'test' ], '$0': 'gulp' }
    [13:00:57] Finished 'test' after 41 ms
    

    我有什么想法可以完成我想要做的事情?!

    3月22日编辑

    看起来我可以通过不同的路线并使用gulp-sass-json插件来部分实现这一目标:

    gulp.task('sass-json', function () {
        return gulp
            .src(scss_base + '*')
            .pipe(plugins.sassJson())
            .pipe(gulp.dest(tmp + 'sass-vars.json'));
    });
    

    这将文件写入/tmp,并将我的SCSS变量编译为JSON文件。然后我想,好吧,我可以在gulp中加载JSON文件并从那里解析它。不幸的是,这个插件不能解析第二级变量(即引用变量的变量),所以你会得到这样的结果:

     {
         # variables parsed from SCSS to JSON by gulp-sass-json
    
         # these are ok
         "font__main": "'Open Sans', sans-serif",
         "font__heading": "'Open Sans', sans-serif",
         "font__line-height-body": "1.5",
         "testSassVar": "123",
         "color__nbar": "#ffffff",
         "color__nbar_bg": "#50B107",
         "size_border-radius": "3px"
    
         # these variables reference other variables, not parsed, ouch
         "color__background-body": "$color__nbar",
         "color__background-screen": "$color__nbar",
    
         # and this is even worse, the SCSS function isn't parsed, double ouch
         "color_test": "lighten($color__nbar, 50%)",
     }
    

    正如你所看到的那样,对其他变量进行简单引用的变量可能会用一些Javascript修复来解析它们,但是一旦你进入SASS函数,那个想法就会崩溃。

    理想情况下,SCSS编译器可以解析非静态值的变量。这是可能的(还是开始真正进入杂草来解决这个问题)?

    我唯一的另一个想法是将所有变量移动到JSON文件,然后使用向另一个方向移动的gulp插件 - JSON到SASS变量。但是,我不会得到让SCSS编译器运行函数,解析变量等的优势,然后将这些值返回给我的gulp文件。

    由于我的目标是让(已解析的)变量中的SASS值可用于我的gulp文件,因此我可以将其转换为另一个(HTML或PHP)代码文件,执行简单的字符串替换。如果有一个更简单的方法来实现我的最终目标,我会全力以赴......

3 个答案:

答案 0 :(得分:1)

我最近有一个类似的问题,虽然我没有使用gulp。

我搜索了可以完成这项任务的npm软件包(从SCSS中提取变量),但是我找到的这对夫妇是次要的。

所以,我最终编写了自己的lib(extract-scss-variables)。 我们在生产中使用它,它经过了基础和其他一些常见用途的测试。

我真的不记得如何制作一个gulp插件了,但这个库本身不应该很难集成。

在你的具体情况下,我会做类似的事情:

var extractScssVariables = require('extract-scss-variables');
var variables = extractScssVariables({
  entryPoint: 'path/to/sass/style.scss',
  files: [
    'path/to/sass/_mixins.scss',
    'path/to/sass/_normalize.scss',
    'path/to/sass/_variables.scss',
  ],
  sassOptions: { 
    includePaths: ['path/to/libraries/to/include.scss'],
  },
});

其中entryPoint是提取变量的上下文(例如,如果覆盖_mixins.scss中声明的变量,则使用entryPoint的变量);
files是从中提取SCSS变量的文件数组;
sassOptions是您已经使用的任何命令行sass选项。

答案 1 :(得分:1)

我还为这种用例创建了一个库,该用例使用本机sass编译器功能来提取名为sass-extract的变量值,该变量值还带有webpack loaderbabel plugin取决于关于用例。

好处是基于本机sass类型系统,因此支持各种sass功能,如函数,mixins,列表,映射等。它还按预期处理导入,覆盖,默认等。

如果您愿意使用webpack,只需导入sass文件:

const style = require('sass-extract-loader!./style.scss'); 

获取变量,这将是最简单的选择。否则,您可以直接使用核心库:

const sassExtract = require('sass-extract');

sassExtract.render({
  file: 'path/to/my/styles.scss'
})
.then(rendered => {
  console.log(rendered.vars);
});

还有一个可用的同步版本可用于与您的gulp管道集成。

答案 2 :(得分:0)

以下是我的解决方案 - 您需要gulp-inject

main.scss档案

...
/* inject:scss */
/* endinject */
...

gulpfile.js档案

var gulpInject = require('gulp-inject');

...

gulp.src('...your/main/scss/file.scss')
.pipe(
    gulpInject(gulp.src('...your/partial/scss/**/*.scss'), {
        relative: true,
        transform: function (filePath) {
            var fileWithoutExtension = filePath.replace('.scss', '');
            return '@import \'' + fileWithoutExtension + '\';';
        }
    })
)
.pipe(...)
...

上面的示例将部分SCSS文件注入主SCSS文件。

希望我的代码会有所帮助。