【问题标题】:Gulp - want to inject SCSS variable into another fileGulp - 想要将 SCSS 变量注入另一个文件
【发布时间】:2017-03-21 12:03:37
【问题描述】:

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

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

我认为这是两个步骤:

  1. Gulp SCSS _variables.scss 文件,以便我可以访问该变量

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

我被困在第 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)代码文件中,进行简单的字符串替换。如果有更简单的方法来实现我的最终目标,我会全力以赴......

【问题讨论】:

    标签: gulp gulp-sass


    【解决方案1】:

    我最近遇到了类似的问题,虽然我没有使用 gulp。

    我搜索了可以完成此任务的 npm 包(从 SCSS 中提取变量),但我发现的这对夫妇不合格。

    所以,我最终编写了自己的库 (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 选项。

    【讨论】:

      【解决方案2】:

      我还为这种用例编写了一个库,它使用本机 sass 编译器功能来提取名为 sass-extract 的变量值,根据用例的不同,它还附带 webpack loaderbabel plugin

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

      如果你愿意使用 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 管道集成。

      【讨论】:

        【解决方案3】:

        这是我的解决方案 - 你需要有 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 文件中。

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

        【讨论】:

          猜你喜欢
          • 2017-10-08
          • 1970-01-01
          • 2019-12-06
          • 2016-03-13
          • 2021-06-22
          • 2019-05-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多