使用Browserify打包js時如果項目變得越來越大,編譯時間就會相應變得越來越長。使用官方的插件watchify是個比較有效的提高速度方案。
提速原理
watchify的用法和gulp的watch方法比較類似,都是監控文件的改動來觸發一些操作。在gulp中我們可以把一個完整的任務拆分成很多個局部任務,然后使用gulp.watch對這些局部任務進行監聽,例如:
gulp.task('build-js1', ...);
gulp.task('build-js2', ...);
gulp.task('build-all-js', ['build-js1', 'build-js2']);
gulp.task('watch-js1', function () {
gulp.watch('./src/models/**/*.js', ['build-js1']);
});
gulp.task('watch-js2', function () {
gulp.watch('./src/views/**/*.js', ['build-js2']);
});
//gulp.task('watch-js', function () {
// gulp.watch('./src/**/*.js', ['build-all-js']);
//});
如上例所示,在監測不同局部位置的js文件發生改動后,則只會自動執行相應的build-js1或build-js2等局部任務;而如果直接監測所有的js文件,就必須每次執行build-all-js任務了。
watchify
的提速原理和這個思路有點類似,它可以監測個別文件的改動,從而觸發只將需要更新的文件打包。它須要先執行一次完整的打包,首次打包的速度和正常速度是一樣的;然后每次用戶改變某個和browserify
關聯的js文件時,會自動執行打包,而這次打包的速度卻非常快。
具體實例
watchify
結合gulp
的實例如下:
var gulp = require('gulp'),
browserify = require('browserify'),
source = require('vinyl-source-stream'),
buffer = require('vinyl-buffer'),
watchify = require('watchify'),
concat = require('gulp-concat'),
gulpif = require('gulp-if'),
argv = require('yargs').argv,
...;
function getJsLibName() {
...
}
//初始化browserify
var b = browserify({
entries: './src/base.js'
})
.plugin(...)
.transform(...);
//執行打包js
function bundle() {
var jsLibName = getJsLibName();
return b.bundle()
.pipe(source(jsLibName))
.pipe(buffer())
.pipe(gulp.dest('./dist/js').on('end', function() { //打包js后繼續進行一些后續操作
gulp.src(['./vendor/babelHelpers.js', './dist/js/' + jsLibName])
.pipe(concat(jsLibName))
.pipe(gulpif(argv.min, uglify()))
.pipe(gulp.dest('./dist/js'))
}));
}
//定義打包js任務
gulp.task('build-all-js', bundle);
//啟動watchify監測文件改動
gulp.task('watch-js', function() {
b.plugin(watchify); //設置watchify插件
b.on('update', function(ids) { //監測文件改動
ids.forEach(function(v) {
console.log('bundle changed file:' + v); //記錄改動的文件名
});
gulp.start('build-all-js'); //觸發打包js任務
});
return bundle(); //須要先執行一次bundle
});
-
例中可以在gulpfile.js中將
browserify
的實例定義在全局,這樣在browserify
實例的update事件中就可以正常調用到bundle方法了。 -
定義通常的打包js任務build-all-js,例如需要整個項目打包執行它即可。
-
單獨定義監測文件改動的任務watch-js,使用
gulp
啟動這個任務后,就可以啟動watchify
的文件改動監測功能了。需要為browserify
實例注冊update事件,在該事件中觸發build-all-js任務即可。另外在這個任務中須要先執行一次browserify
實例的bundle方法,但這次打包的速度和直接執行build-all-js是一樣的。
關於
watchify
的更多細節大家可以參考官方文檔及這篇文章:Fast browserify builds with watchify
測試打包速度
首先在啟動watch-js任務時,會執行首次打包:
本次打包共花費了6.2秒。
然后在用戶改動某個browserify
關聯的js文件時,都會自動觸發build-all-js任務:
可以看出,這次打包只花費了203毫秒,速度提高了很多。
更多細節大家可參考實例的源代碼。