首页 > 解决方案 > 依赖源文件的 Gulp 插件的条件设置

问题描述

该插件gulp-pug允许通过data属性将全局变量传递给 pug 文件。如果我们不需要每个.pug文件中的完整数据集怎么办?要实现条件数据注入,我们需要访问vinyl内部的当前文件实例,pipe(this.gulpPlugins.pug({})或者至少要知道源文件的绝对路径。可能的?

const dataSetForTopPage = {
    foo: "alpha",
    bar: "bravo"
};

const dataSetForAboutPage = {
    baz: "charlie",
    hoge: "delta"
};


gulp.src(sourceFileGlobsOrAbsolutePath)
    .pipe(gulpPlugins.pug({
      data: /* 
       if path is 'top.pug' -> 'dataSetForTopPage',  
       else if path is 'about.pug' -> 'dataSetForAboutPage'
       else -> empty object*/
    }))
    .pipe(Gulp.dest("output"));

我正在使用gulp-intercept插件。但是如何同步呢gulpPlugins.pug

gulp.src(sourceFileGlobsOrAbsolutePath)
    .pipe(this.gulpPlugins.intercept(vinylFile => {
      // I can compute conditional data set here
      // but how to execute gulpPlugins.pug() here?
    }))
    // ...

这只是一个例子,但是当需要其他 gulp 插件的条件插件选项时,我们也会处理同样的问题。例如:

.pipe(gulpPlugins.htmlPrettify({ 
  indent_char: " ", 
  indent_size: // if source file in 'admin/**' -> 2, else if in 'auth/**' -> 3 else 4
}))

标签: node.jsgulpnode-streams

解决方案


您需要手动修改流 - through2可能是为此目的最常用的包。在 through2 回调中,您可以将流传递给您的 gulp 插件(只要它们的转换函数被公开)并有条件地传递它们选项。例如,这是一个任务:

pugtest = () => {
    const dataSet = {
        'top.pug': {
            foo: "alpha",
            bar: "bravo"
        },
        'about.pug': {
            foo: "charlie",
            bar: "delta"
        }
    };

    return gulp.src('src/**/*.pug')
        .pipe(through2.obj((file, enc, next) => 
            gulpPlugins.pug({
                // Grab the filename, and set pug data to the value found in dataSet by that name
                data: dataSet[file.basename] || {}
            })._transform(file, enc, next)
        ))
        .pipe(through2.obj((file, enc, next) => {
            const options = {
                indent_char: ' ',
                indent_size: 4
            };

            if(file.relative.match(/admin\//)) {
                options.indent_size = 2;
            } else if(file.relative.match(/auth\//)) {
                options.indent_size = 3;
            }

            file.contents = new Buffer.from(html.prettyPrint(String(file.contents), options), enc);
            next(null, file);
        }))
        .pipe(gulp.dest('output'));
}

对于 pug 步骤,我们调用through2.obj并创建 pug 插件,向其传递从我们的对象字面量中获取的数据,在本示例中按文件名索引。所以现在传递给编译器的数据来自那个对象字面量。

对于您提到的 html 步骤,gulp-html-prettify没有公开其转换功能,因此我们无法进入它并将转换传递回流。但在这种情况下,没关系,如果您查看源代码,它只是htmlprettyPrint包中的包装器。这就是它所做的一切。所以我们可以使用 through2 来完成我们的步骤来做同样的事情,但是根据乙烯基文件的相对路径来改变我们的选项。

而已!有关工作示例,请参阅此 repo:https ://github.com/joshdavenport/stack-overflow-61314141-gulp-pug-conditional


推荐阅读