之前做过一个项目,是一种无线设备,由于设备本身的内存容量比较小,为了节约内存使用,选择了gulp这种工具,可以将前端的代码进行打包发布,并能在项目中正常运行,较之之前的代码量有了量的突破,还是不错的。后来接触的项目几乎无一例外的都是用到打包这种工具。我们知道在html中引入js才能让我们的事件起到效果,那么使用gulp这种工具的好处就在于,编译或者压缩之后的js文件完全可以替代之前传统意义上的js文件,不管你目录怎样?他都能编译后被浏览器识别,被程序识别。
当然这么做的唯一坏处就是不太容易debug,在开发环境中是很容易debug的,因为在开发环境中随时可以替换自己的代码去debug问题,当然各有利弊。在测试环境中我们还是可以保留源码,通过双引入(引入压缩js文件和非压缩文件),来测试复现定位BUG。
工欲善其事必先利其器,想要使用gulp组件打包,需要安装gulp。安装gulp,就不得不讲到另外一个----Node.js.它可以提供世界上最全的开源库生态。
https://nodejs.org/zh-cn/ 官网推荐下载地址。下载之后,没啥好说的,双击安装,全默认设置,一直下一步。
命令执行没有问题,就算安装好了。接着我们需要通过node通过的npm命令来执行一系列的依赖js包安装。
切到工作目录下执行npm install -g
将会执行一段时间,他其实是在为你下载依赖库文件,生成一个叫node_modules的文件夹,这个文件夹下的便
时所有的依赖包了。
往下拉,我们能够看到打包工具所对应的gulp一系列的包文件
到目前为止,我们就是使用nodejs安装好我们所需要的打包工具gulp,下面我们就来看看怎么使用gulp来实现
打包功能。
// Include gulp
var gulp = require('gulp');
require:引入gulp资源文件,类似于java中import作用
var connect = require('gulp-connect');
var gulpDocs = require('gulp-ngdocs');
这两条命令的意识是引入docs文件,使用gulp可以生成自定义的dos类型的API文档,这个比较高级了。我们的自定义组件都有自己对应的API文档,方便我们自己使用。如果你也有自己API文档不放参考gulp的官方文档,这里不做说明(都是机密 )
// Include Our Plugins
var plugins = require('gulp-load-plugins')({pattern: ['*']});
var wmaApp = 'src/main/webapp/app';
var wmaTemplatePath = '';
var wmaModule = 'am';
自定义项目路径和module模块。
gulp.task("one", function () {
});
gulp.task("two", function () {
});
那么这两个任务回一起执行,当然gulp也会支持先后执行,这个需要你做特殊的声明。我们来看看官网是怎么给出支持的。
// 在 shell 中执行一个命令
var exec = require('child_process').exec;
gulp.task('jekyll', function(cb) {
// 编译 Jekyll
exec('jekyll build', function(err) {
if (err) return cb(err); // 返回 error
cb(); // 完成 task
});
});
返回一个stream或者promise:
gulp.task('somename', function() {
var stream = gulp.src('client/**/*.js')
.pipe(minify())
.pipe(gulp.dest('build'));
return stream;
});
var Q = require('q');
gulp.task('somename', function() {
var deferred = Q.defer();
// 执行异步的操作
setTimeout(function() {
deferred.resolve();
}, 1);
return deferred.promise;
});
当需要批量执行一个序列化的任务时,我们需要让下一个任务知道他需要在谁之后执行:(以下内容来自官网)
对于这个例子,让我们先假定你有两个 task,"one" 和 "two",并且你希望它们按照这个顺序执行:
在 "one" 中,你加入一个提示,来告知什么时候它会完成:可以再完成时候返回一个 callback,或者返回一个 promise 或 stream,这样系统会去等待它完成。
在 "two" 中,你需要添加一个提示来告诉系统它需要依赖第一个 task 完成。
因此,这个例子的实际代码将会是这样:
var gulp = require('gulp');
// 返回一个 callback,因此系统可以知道它什么时候完成
gulp.task('one', function(cb) {
// 做一些事 -- 异步的或者其他的
cb(err); // 如果 err 不是 null 或 undefined,则会停止执行,且注意,这样代表执行失败了
});
// 定义一个所依赖的 task 必须在这个 task 执行之前完成
gulp.task('two', ['one'], function() {
// 'one' 完成后
});
gulp.task('default', ['one', 'two']);
// Concatenate & Minify JS
gulp.task('script-build', function () {
var javascriptStream = gulp.src(wmaApp + '/**/*.js');
var htmlStream = gulp.src(wmaApp + '/**/*.html')
.pipe(plugins.htmlmin({collapseWhitespace: true}))
.pipe(plugins.angularTemplatecache('templateCache.js', {module: wmaModule, root: wmaTemplatePath}));
return plugins.eventStream.merge(javascriptStream, htmlStream)
.pipe(plugins.angularFilesort())
.pipe(plugins.concat('ham.min.js'))
.pipe(plugins.uglify())
.pipe(gulp.dest('build/scripts'));
});
// Concatenate & Minify CSS
gulp.task('css-build', function () {
return gulp.src(wmaApp + '/**/*.css')
.pipe(plugins.concat('ham.min.css'))
.pipe(plugins.minifyCss())
.pipe(gulp.dest('build/styles/css'));
});
// Clean existed build
gulp.task('clean', function () {
return gulp.src(
[
'build/*'
])
.pipe(plugins.clean({force: true}));
});
// Build all
gulp.task('build', function () {
plugins.runSequence('clean', 'script-build', 'css-build');
});
就是依次执行这三个任务,关于runSequence这个方法在下面这个文件中有定义,感兴趣的可以看看源码。