在編譯過程中,可能會出現不必要的編譯,我們希望只對修改過的文件進行編譯,即 增量編譯。
目前,用於增量編譯的插件有gulp-changed
,gulp-newer
,gulp-cached+gulp-remember
。
接下來,就來試試上述插件。
首先,筆者測試使用的文件目錄如下:
接着,在gulpfile.js
文件中進行如下定義
const {task, src, watch, series, parallel, dest} = require('gulp');
const concat = require('gulp-concat');
const debug = require('gulp-debug');
const changed = require('gulp-changed');
const newer = require('gulp-newer');
const cached = require('gulp-cached');
const remember = require('gulp-remember');
const destDir = './dist';
1)use gulp-changed
實現增量編譯
該插件默認是通過比較源文件和生成文件的修改時間來判斷是否將文件傳入下一個pipe
流,僅傳遞那些源文件對比相應的生成文件有更新更改的文件。
task('changed', () => {
return src('./src/*.js')
.pipe(changed(destDir))
.pipe(debug({title:'編譯: '}))
.pipe(concat('all.js'))
.pipe(dest(destDir));
});
修改src/a.js
,在終端中執行gulp changed
可看到
可以看出,若changed()
後有concat()
操作,那麼changed()
會將所有源文件傳入下一個pipe
流,那麼changed()
等於做了無用功。因此,gulp-changed只適合1:1 source:dest mapping
。
2)use gulp-newer
實現增量編譯
與gulp-changed
類似,該插件也是通過對比文件的修改時間。
2.1)Using newer
with 1:1 source:dest mappings
如下例子,在babel()
之前使用newer()
來確保只有修改過的文件纔會被babel()
。需要注意的是,此時newer
插件配置的生成文件路徑只需到文件目錄,eg.newer('./dest')
。
task('newer', () => {
return src('./src/*.js')
.pipe(debug({title:'all: '}))
.pipe(newer(destDir))
.pipe(debug({title:'newer: '}))
.pipe(babel())
.pipe(dest(destDir));
});
修改src/a.js
,在終端中執行gulp newer
可看到newer()
只將修改過的a.js
傳入下一個pipe
流。
2.2)Using newer
with many:1 source:dest mappings
類似gulp-concat
這種將多個源文件經過處理生成單一文件,只要源文件中有一個文件比生成文件更新,那麼newer
流會將所有源文件傳入下一個pipe
流。需要注意的是,此時newer
插件配置的生成文件路徑需具體到文件名,eg.newer('./dest/all.js')
。
task('newer', () => {
return src('./src/*.js')
.pipe(debug({title:'all: '}))
.pipe(newer(destDir + '/all.js'))
.pipe(debug({title:'newer: '}))
.pipe(concat('all.js'))
.pipe(dest(destDir));
});
修改src/a.js
,在終端中執行gulp newer
可看到
3) use gulp-cached
實現增量編譯
和gulp-changed
基於文件的對比不同,gulp-cached
可以將第一次傳遞給它的文件內容保存在內存中,如果之後再次執行task
,它會將傳遞給它的文件和內存中的文件進行對比,如果內容相同,就不再將該文件繼續向後傳遞,從而做到了只對修改過的文件進行增量編譯。
注意,gulp-cached
必須要開啓gulp watch
,保存內存中存在副本,才能進行比較。
task('cached', () => {
return src('./src/*.js')
.pipe(cached('caching'))
.pipe(debug({title:'cached: '}))
// .pipe(remember('caching'))
// .pipe(debug({title:'rememeber: '}))
// .pipe(concat('all.js'))
.pipe(dest(destDir));
});
const watcher = () => {
watch('./src/*.js', series('cached'));
};
task('cachedCompile', series('cached', watcher));
在終端中執行gulp cachedCompile
,後修改src/a.js
可看到
4)use gulp-remember
實現增量編譯
task('remember', () => {
return src('./src/*.js')
.pipe(remember('caching'))
.pipe(debug({title:'rememeber: '}))
.pipe(dest(destDir));
});
在終端中執行gulp remember
,可看到
src/
下新增d.js
,在終端中執行gulp remember
,可看到
gulp-remember
同樣可以在內存中緩存所有曾經傳遞給它的文件,但是它和gulp-cached
的區別是,在之後的task
中,gulp-cached
會過濾掉未經修改的文件不再向下傳遞,而gulp-remember
則會將未傳遞給它的文件進行補足從而能夠繼續向下傳遞。因此通過gulp-cached
和gulp-remember
的結合使用,既能做到只對修改過的文件進行編譯,又能做到當相關聯的文件任意發生改變時,編譯所有相關文件。
task('cached', () => {
return src('./src/*.js')
.pipe(cached('caching'))
.pipe(debug({title:'cached: '}))
.pipe(remember('caching'))
.pipe(debug({title:'rememeber: '}))
.pipe(concat('all.js'))
.pipe(dest(destDir));
});
const watcher = () => {
watch('./src/*.js', series('cached'));
};
task('cachedCompile', series('cached', watcher));
在終端中執行gulp cached
,後修改src/a.js
可看到
本文參考:
glup-changed npm
gulp-newer npm
gulp-cached npm
gulp中的增量編譯
gulp-newer-vs-gulp-changed