【问题标题】:Only compile sass if a file has changed using gulp仅当文件已使用 gulp 更改时才编译 sass
【发布时间】:2016-01-22 05:50:27
【问题描述】:

我正在尝试重建我的 gulp 文件以提高效率,但我无法让我的 styles 任务仅在文件已更改时进行编译。

我找到了this question,但答案似乎对我不起作用。

假设我的仓库是这样组织的:

/dev
  /assets
    /styles
      all.css
/src
  /assets
    /styles
      all.scss
      _header.scss
gulpfile.js
package.json

如果我的任何一个 Sass 文件发生了更改,我只想覆盖 all.css。因此,如果我将 _header.scss 保存在哪里,但没有进行任何更改,并运行我的 styles 任务,它应该意识到代码没有更改并且不会覆盖 all.css

根据我上面链接的问题,我正在查看gulp-cached,但这似乎对我不起作用。这是最基本的任务:

var gulp = require("gulp"),
    cached = require("gulp-cached"),
    sass = require("gulp-sass");

gulp.task("styles", function() {
    return gulp.src(src + "/assets/styles/all.scss")
        .pipe(sass().on("error", sass.logError))
        .pipe(cached("sass_compile")) // should skip the dest if cache is the same
        .pipe(gulp.dest(dev + "/assets/styles"));
});

cached 管道在这种情况下似乎不起作用。我运行gulp styles,它仍然覆盖 all.css,即使没有进行任何更改,即使我什至没有重新保存文件。

我最终想使用的更复杂的任务是:

var gulp = require("gulp"),
    cached = require("gulp-cached"),
    sourcemaps = require("gulp-sourcemaps"),
    sass = require("gulp-sass"),
    autoprefixer = require("gulp-autoprefixer"),

    // set up environment paths
    src = "./src",
    dev = "./dev",
    dist = "./dist";

gulp.task("styles", function() {
    return gulp.src(src + "/assets/styles/all.scss")
        .pipe(sourcemaps.init())
        .pipe(sass().on("error", sass.logError))
        .pipe(autoprefixer("last 2 version", "ie 8", "ie 9"))
        .pipe(sourcemaps.write())
        .pipe(cached("sass_compile")) // should skip the dest if cache is the same
        .pipe(gulp.dest(dev + "/assets/styles"));
});

非常感谢您对此提供一些指导。非常感谢。


编辑 1:请注意,此演示中的 all.scss 仅包含 @import "_header";


编辑 2: 好的,我刚刚发现 gulp-cached 似乎在 watch 任务中工作正常。所以修改了问题:我怎样才能在监视任务之外获得这种相同类型的功能?

【问题讨论】:

    标签: node.js sass gulp gulp-sass gulp-cached


    【解决方案1】:

    gulp-newer 解决了这个问题,它可以检查导入的文件。太棒了!这是我的最终样式任务:

    // styles task, compiles & prefixes SCSS
    gulp.task("styles", function () {
        "use strict";
    
        // development CSS directory
        var cssDirectory = dev + "/assets/styles";
    
        // production CSS directory (if --dist is passed)
        if (argv.dist) {
            cssDirectory = dist + "/assets/styles";
        }
    
        // clean directory if --clean is passed
        if (argv.clean) {
            del(cssDirectory + "**/*");
        }
    
        // compile all SCSS in the root styles directory
        return gulp.src(src + "/assets/styles/*.scss")
            // check if source is newer than destination
            .pipe(newer(cssDirectory + "/all.css"))
            // initialize sourcemap
            .pipe(sourcemaps.init())
            // compile SCSS (compress if --dist is passed)
            .pipe(gulpif(argv.dist, sass({outputStyle: "compressed"}).on("error", sass.logError), sass().on("error", sass.logError)))
            // prefix CSS
            .pipe(autoprefixer("last 2 version", "ie 8", "ie 9"))
            // write the sourcemap (if --dist isn't passed)
            .pipe(gulpif(!argv.dist, sourcemaps.write()))
            // output to the compiled directory
            .pipe(gulp.dest(cssDirectory));
    });
    

    【讨论】:

      【解决方案2】:

      改用gulp-changed。我相信这适用于文件的last modified date,这听起来像你想要的。

      【讨论】:

      • 我认为我看过这个并遇到了问题,但我会再试一次并报告。感谢您的建议。
      • 认为你可以把它变成你需要的东西。您可能需要在管道中更早地使用 changed,因此您可以将 src all.scss 上次更改日期与 dest all.scss 上次更改日期进行比较。 IIRC 它根据文件名进行比较,因此如果您正在进行任何额外的重命名/连接或类似的操作,它可能会出现问题。就个人而言,我总是在监视任务中使用gulp-cached 之类的东西,但无论如何我更喜欢监视任务。
      • 所以从那个描述听起来changed 没有看到导入文件的变化,对吗?这个周末我会做一些研究。我想我可以只依靠 watch 任务;我只是希望能够在某些情况下手动运行我的默认任务(运行所有任务)。
      • 我认为它的设计目的是在单个源文件和同名的单个目标文件之间进行一对一的比较。比较方法可以不同,但​​默认应该是最后修改日期——所以如果它看到源文件的最后修改日期比目标文件更新,那么它应该允许源文件通过管道。
      • 是的,这看起来很有希望——很高兴他们能够将多个 src 文件与单个 dest 文件(在缩小的情况下)进行比较。
      猜你喜欢
      • 2016-01-30
      • 1970-01-01
      • 1970-01-01
      • 2014-07-04
      • 2018-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多