gulp4增量編譯

漸漸君發表於2019-03-03

更多內容歡迎來到部落格 :https://imjianjian.github.io

在任何構建工具中增量編譯都是一個必不可少的優化方式。即在編譯過程中僅編譯那些修改過的檔案,可以減少許多不必要的資源消耗,也能減少編譯時常。而且gulp是一個配置簡單,學習價效比很高的工具。

外掛

在gulp官方推薦了四個外掛用於增量編譯:

  • gulp-changed – only pass through changed files
  • gulp-newer – pass through newer source files only, supports many:1 source:dest
  • gulp-cached – in-memory file cache, not for operation on sets of files
  • gulp-remember – pairs nicely with gulp-cached

增量編譯

gulp.lastRun()

gulp4提供了lastRun函式用於獲取上次執行任務的時間。

可以使用gulp.src函式的since和gulp.lastRun函式,在執行兩次任務之間過濾掉未更改的檔案:

var imgSrc = `src/img/**`;
var imgDest = `build/img`;

//壓縮圖片
function images() {
  return gulp.src(imgSrc, {since: gulp.lastRun(images)})
    .pipe(imagemin({optimizationLevel: 5}))
    .pipe(gulp.dest(imgDest));
}

function watch() {
  gulp.watch(imgSrc, images);
}

gulp.task(`watch`,watch);
複製程式碼

watch任務執行時會將檔案儲存在記憶體中,並且在watch任務退出時刪除。所以這隻會在watch任務執行期間節省images任務的時間。

如果想要比較兩次修改之間的變化,那麼就需要使用gulp-changed和gulp-newer兩個外掛。兩者的區別就是gulp-changed通過比較檔案的生成和修改的時間,只會將修改過的檔案發往下個流,如果後續存在檔案合併則會出現檔案缺失。所以gulp-changed只適合一對一的操作。而如果有多對一的情況,則需要使用gulp-newer。

gulp-changed

function images() {
  return gulp.src(imgSrc)
    .pipe(changed(imgDest))  //只把發生改變或新新增的圖片檔案發向下個流
    .pipe(imagemin({optimizationLevel: 5}))
    .pipe(gulp.dest(imgDest));
}
複製程式碼

如果檔案輸出的型別有所不同(sass===>css)需要加上extension引數{extension:`.css`}
gulp-changed是基於檔案的更改,所以不一定需要使用gulp.watch(),連續使用gulp images命令效果是一樣的。
gulp-changed只支援一對一的檔案更新,類似gulp-concat這樣合併檔案的操作,會有檔案內容缺失。

gulp-newer

1:1輸出

function images() {
  return gulp.src(imgSrc)
    .pipe(newer(imgDest))  
    .pipe(imagemin({optimizationLevel: 5}))
    .pipe(gulp.dest(imgDest));
}
複製程式碼

many:1輸出

類似gulp-concat這樣的外掛將多個檔案合併成一個。在這種情況下,gulp-newer會把流通過所有檔案,如果任何一個檔案被更新,gulp-newer就會把他輸出到下個流。

gulp.task(`concat`, function() {
  return gulp.src(`lib/*.js`)
      .pipe(newer(`dist/all.js`))
      .pipe(concat(`all.js`))
      .pipe(gulp.dest(`dist`));
});
複製程式碼

gulp-cached

function images() {
  return gulp.src(imgSrc)
    .pipe(cache(`imageMin`))
    .pipe(imagemin({optimizationLevel: 5}))
    .pipe(gulp.dest(imgDest));
}

function watch() {
  gulp.watch(imgSrc, images);
}

gulp.task(`watch`,watch);
複製程式碼

gulp-cached基於儲存在記憶體裡的資料的對比,關閉了gulp.watch()就沒辦法對比檔案更新。
gulp-cached只會把發生改變的檔案發往下個流,如果在流的後期需要對所有檔案進行操作,那麼就需要gulp-remember的配合。

gulp-remember

gulp-remember可以將儲存在記憶體中的所有檔案都發向下個流
gulp-remember配合使用gulp-cached,可以方便處理當你只想重建那些改變了的檔案,但仍然需要對流中的所有檔案進行操作的情況。

下面這個案例就是將所有檔案合併成一個檔案的情況,流的前期用gulp-cached匯出那些被修改的檔案,後期使用gulp-remember將所有檔案導向下個流進行合併操作。

var gulp = require(`gulp`),
    header = require(`gulp-header`),
    footer = require(`gulp-footer`),
    concat = require(`gulp-concat`),
    cache = require(`gulp-cached`),
    remember = require(`gulp-remember`);

var scriptsGlob = `src/**/*.js`;

function scripts(){
  return gulp.src(scriptsGlob)
      .pipe(cache(`scripts`)) // 只通過發生改變的檔案
      .pipe(header(`(function () {`)) // 在檔案頭部新增程式碼`(function () {`
      .pipe(footer(`})();`)) // 在檔案尾部新增程式碼`})();`
      .pipe(remember(`scripts`)) // 將所有檔案‘召喚’回這個流,其中一些已經被header和footer處理過
      .pipe(concat(`app.js`)) // 合併檔案
      .pipe(gulp.dest(`public/`))
}

function watch(){
  var watcher = gulp.watch(scriptsGlob, scripts); 
  watcher.on(`change`, function (event) {
    if (event.type === `deleted`) { 
      delete cache.caches[`scripts`][event.path];
      remember.forget(`scripts`, event.path);
    }
  });
}

gulp.task(`watch`,watch);
複製程式碼

使用效果

未開啟增量編譯

[18:35:26] Using gulpfile D:loggulpfile.js
[18:35:26] Starting `default`...
[18:35:26] Starting `minifyJS`...
[18:35:26] Starting `minifyHtml`...
[18:35:26] Starting `minifyCss`...
[18:35:26] Starting `minifyImgs`...
[18:35:28] Finished `minifyJS` after 2.2 s
[18:35:29] gulp-imagemin: Minified 17 images (saved 0 B - 0%)
[18:35:29] Finished `minifyImgs` after 3.32 s
[18:35:29] Finished `minifyCss` after 3.66 s
[18:35:30] Finished `minifyHtml` after 4.44 s
[18:35:30] Finished `default` after 4.45 s
複製程式碼

開啟增量編譯

[18:41:27] Using gulpfile D:loggulpfile.js
[18:41:27] Starting `default`...
[18:41:27] Starting `minifyJS`...
[18:41:27] Starting `minifyHtml`...
[18:41:27] Starting `minifyCss`...
[18:41:27] Starting `minifyImgs`...
[18:41:28] Finished `minifyJS` after 879 ms
[18:41:28] gulp-imagemin: Minified 0 images
[18:41:28] Finished `minifyImgs` after 889 ms
[18:41:28] Finished `minifyCss` after 897 ms
[18:41:28] Finished `minifyHtml` after 912 ms
[18:41:28] Finished `default` after 916 ms
複製程式碼

相關文章