在编译过程中,可能会出现不必要的编译,我们希望只对修改过的文件进行编译,即 增量编译。
目前,用于增量编译的插件有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