前端构建工具Gulp.js
最近一个网站项目,开发人员准备直接把前端的代码拷贝到生产环境来部署,而且使用Ant来执行拷贝,这样就可以前后端一起部署了。这是传统后端开发人员的思维。这样做固然可行,但是当前端代码越来越庞大时,就不好管理了。如同Java的Ant,C++的Make,前端开发也有其构建工具,这里就介绍一个超简单的构建工具Gulp.js。
熟悉Ant等的构建工具的朋友们知道,一个基本的构建工具,就是能够解析你写的构建脚本(也可以是配置文件),如Ant中的build.xml,Make中的makefile。然后根据你脚本中的步骤,来执行构建任务。而这个构建脚本的内容,就是定义了一个个任务,以及任务之间的依赖关系。我们来看看Gulp.js的构建脚本怎么写。
工具安装
作为前端开发人员,相信你的机器上NodeJS, NPM这些都已经装上了吧(没有?那你得先学习下再回来)。你可以全局安装Gulp
$ npm install gulp -g
也可以在当前工程下,作为开发依赖安装
$ npm install gulp --save-dev
我个人喜欢后者,不污染全局环境。
创建任务
Gulp的构建脚本默认写在文件”gulpfile.js”里,一般把这个文件放在项目根目录下。一个基本的任务代码如下:
var gulp = require('gulp'); // Get Gulp
gulp.task('default', function() {
// Task code
});
然后在命令行运行:
$ gulp taskname
即可执行指定名称的任务,如果不给”taskname”,则执行名为”default”的任务,如上例。
假如你的任务有依赖关系,则在task()
方法第二个参数中列出其依赖的任务名:
gulp.task('default', ['script', 'css'], function() {
// Task code
});
这样当执行”default”任务时,gulp会先执行”script”和”css”任务。
编写任务
Gulp任务中的逻辑,就是对数据作流式处理。简单的说,就是读取文件数据流,然后进入管道操作。一个管道执行完,将结果传入下一个管道,最后写入目标地址。
看一个例子吧:
var uglify = require('gulp-uglify'); // Get uglify module
// Compress JS files, run 'gulp script' in command line
gulp.task('script', function() {
// set JS source folder
gulp.src('js/**/*.js')
// compress files
.pipe(uglify())
// save the compressed files to dest folder
.pipe(gulp.dest('dist/js'));
});
解释一下,”script”任务通过gulp.src()
方法来获取文件数据流,方法中的参数指定了待获取文件的路径,本例中就是”js”目录下所有扩展名为”js”的文件(包括子目录)。pipe()
方法定义了管道,可以定义多个,上一个pipe()
的输出就是下一个pipe()
的输入。gulp.dest()
方法是将结果写入到指定的路径中,参数定义了写的目标路径。uglify()
方法是将JS文件混淆(俗称”丑化”),稍后会再介绍。
上面就是一个完整的任务步骤,读->管道处理->写。是不是跟Ant非常类似?注意,文件写入也是在一个管道里,也就是说写入以后还可以添加其他管道,再做后续操作。
插件工具
Gulp提供了相当多的插件(据说好几百个)来对文件作处理。上例中的JS文件混淆uglify()
就是一个插件。此外常用的还有CSS压缩,图片压缩,Less/Sass编译,代码规范检查等等。使用插件之前,你需先安装插件模块,并在”gulpfile.js”文件中引入。上面有了JS混淆的例子,这里我们就拿CSS压缩来举例子。首先,安装插件:
$ npm install gulp-minify-css --save-dev
然后编写”css”任务:
var minifyCss = require('gulp-minify-css'); // Get minify-css module
var notify = require('gulp-notify'); // Get notify module
// Compress CSS files, run 'gulp css' in command line
gulp.task('css', function() {
// set CSS source folder
gulp.src('css/**/*.css')
// compress files
.pipe(minifyCss())
// save the compressed files to dest folder
.pipe(gulp.dest('dist/css'))
// Sent notification
.pipe(notify({ message: 'css task complete' }));
});
通过require()
方法导入CSS压缩模块gulp-minify-css
,然后在管道中执行该模块方法即可。
本例还引入了gulp-notify
模块,在文件写入完成后,发出通知。在Mac下运行时,会调用系统通知,很酷吧。
文件监听
有时候开发人员比较懒,希望修改完文件后就自动构建。Gulp提供了一个强大的功能就是监听指定的文件,当这些文件发生修改时,就自动执行任务。
// Listening the changes, run 'gulp auto' in command line
gulp.task('auto', function() {
// Listen to the changes in CSS source folder, run 'css' task when change happens
gulp.watch('css/**/*.css', ['css']);
// Listen to the changes in templates source folder, log event when change happens
gulp.watch('templates/**/*.html', function (event) {
console.log('Event type: ' + event.type); // added, changed, or deleted
console.log('Event path: ' + event.path); // The path of the modified file
});
});
结合上面的例子,当有任何”css”子目录下的CSS文件改动时,Gulp会自动执行”css”任务。而当”templates”子目录下HTML改动时,则执行后面的回调函数。
上面的部分已经涵盖了Gulp所有的基本功能,很简单吧。其他的内容主要就是插件了。你可以在这里下载一个常用的Gulp例子。