Gulp.js事件流合并顺序

30

我正在尝试将CSS和SCSS文件合并到一个名为main.css的目录中。虽然它能够工作,但是顺序不正确。 SCSS文件中的样式属性需要位于main.css文件底部,以便它们覆盖其他样式。

我的Gulp任务如下:

    //CSS
gulp.task('css', function () {
    var cssTomincss = gulp.src(['dev/css/reset.css', 'dev/css/style.css','dev/css/typography.css',    'dev/css/sizes.css']);

    var cssFromscss = gulp.src(['dev/css/*.scss'])
        .pipe(sass());

    return es.merge(cssTomincss, cssFromscss)
        .pipe(concat('main.css'))
        .pipe(minifyCSS())
        .pipe(gulp.dest('build/css'))
});

我首先使用变量定义资源。我使用gulp-sass插件将scss文件转换为普通的css文件(.pipe(sass)),然后使用es.merge函数将两个文件合并并将它们连接到main.css文件中。

问题是样式属性在.scss文件中的位置最终出现在main.css文件的顶部,而我需要它们在底部。因此,它们需要在底部进行连接。

有什么方法可以实现这一点吗?

4个回答

56

试试streamqueue

var streamqueue = require('streamqueue');

gulp.task('css', function () {
    return streamqueue({ objectMode: true },
            gulp.src(['dev/css/reset.css', 'dev/css/style.css', 'dev/css/typography.css', 'dev/css/sizes.css']),
            gulp.src(['dev/css/*.scss']).pipe(sass())
        )
        .pipe(concat('main.css'))
        .pipe(minifyCSS())
        .pipe(gulp.dest('build/css'))
});

这份备忘单能为您提供帮助。 PDF版本在这里。


2
好的,太棒了。它起作用了!我研究了一下,现在我明白了。非常感谢!! - Jabba Da Hoot
嗨!我正在使用streamqueue,感谢您的建议...但遇到了问题:(能否帮忙看一下?http://stackoverflow.com/questions/28522916/how-to-order-the-compiling-of-javascript-files-in-gulp - Leon Gaban
streamqueue总是抛出“现在无法切换到旧模式”的错误。但使用merge-stream然后gulp-order可以解决这个问题。 - user764754
它没有按正确的顺序连接它们 :( 即使我在streamqueue中倒转顺序,它仍然以相同(错误)的方式输出。这甚至是怎么回事...? - Neithan Max

5
我尝试了使用 gulp-order,但没有成功:排序好像没有被考虑进去。
对我有用的解决方案是使用 stream-series,由 Aperçu 提到。
return streamSeries(
    cssTomincss,
    cssFromscss)
    .pipe(concat('main.css'))
    .pipe(minifyCSS())
    .pipe(gulp.dest('build/css'));

5
似乎插件 gulp-order 在您的情况下非常适用。它允许您根据自己的 glob 模式重新排序传递的 stream,例如基于您的代码:
return es.merge(cssTomincss, cssFromscss)
    .pipe(order([
      'dev/css/reset.css',
      'dev/css/style.css',
      'dev/css/typography.css',
      'dev/css/sizes.css',
      'dev/css/*.css',
    ]))
    .pipe(concat('main.css'))
    .pipe(minifyCSS())
    .pipe(gulp.dest('build/css'))

这种方法的一个缺点是您必须重新声明您的“globs”,但您可以通过将您的“globs”分配给一个值,然后在您的“order”管道中连接它们来解决这个问题,这样更加清晰简洁。如果文件没有正确排序,您可能需要按照 gulp-order 的Readme中所述将选项 base 设置为“。”。
另一种方法是使用stream-series,与event-stream基本相同,但您的流的顺序被保留,并且您不必重写您的“globs”。

有时候它不能按预期选择路径。使用.pipe(order[path1, path2], { base: '.' })解决了这个问题。 - Valerio
1
哦,这些文件在不同的文件夹里吗?我会在我的回答中加上这个信息,谢谢。 - Preview
很棒的答案 - 只是提醒那些跟随这个答案的人,你需要通过npm安装gulp-order并在gulp文件的顶部导入它。 - rhysclay

1

我试过所有提供的答案,但它们都产生了一些静默错误。最终merge2对我有效(似乎原来有gulp-merge,后来项目更名为merge2)。我不确定为什么需要streamify插件,例如使用Rollup创建的流可能会在使用gulp-concatgulp-uglifygulp-insert时产生"stream-not-supported-errors"。

const mergeStreams = require('merge2');
const streamify = require('streamify');
...
gulp.task('build', () => {
    const streams = sources.map(createJSFile);
    return mergeStreams(...streams)
        .pipe(streamify(concat('bundle.js')))
        .pipe(streamify(uglify()))
        .pipe(gulp.dest('./dist'));
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接