Gulp是JS的代码构建工具,常见的还有Grunt,不过Gulp以其插件化和流式操作渐渐挤占市场.

安装

安装跟着gulp官网来就好。

福利

gulp cheatsheet
gulp cheatsheet part1
gulp cheatsheet part2

创建 gulpfile

在我们正是编写代码之前,需要了解的一点是gulp仅仅只有5个方法。所有的5个方法如下:task、run、watch、src以及dest。
你只需要用这5个方法就可以编写所有的任务。

注意: 必须有一个默认的 default 任务

gulp.task 定义一个gulp任务

task方法有两个参数,第一个是任务名,第二个是任务函数。在任务函数中,使用gulp模块的src方法,
指定所要处理的文件,然后使用pipe方法,将上一步的输出转为当前的输入,进行链式处理。

gulp.src 设置源文件,产生读取流

js/app.js: 指定确切的文件名。
js/*.js: 某个目录所有后缀名为js的文件。
js/**/*.js: 某个目录及其所有子目录中的所有后缀名为js的文件。
!js/app.js: 除了js/app.js以外的所有文件。
*.+(js|css):匹配项目根目录下,所有后缀名为js或css的文件。

gulp.dest 设置写入文件,产生写入流

gulp.run 运行定义的gulp任务

gulp.watch 监视文件的变化,并调用相应的方法

1
2
3
4
5
//watch任务:侦听js文件执行 build 任务
gulp.task('watch', function () {
gulp.watch('src/*.js', ['build']);//侦听js文件执行 build 任务
});

例如下面为改变db.js文件中的分号然后保存后报错的watch任务

1
2
3
4
5
6
7
8
9
10
11
$ gulp watch
[17:37:12] Working directory changed to ~/Desktop/LearnNode/NodeJS开发指南/chapter5/microblog
[17:37:14] Using gulpfile ~/Desktop/LearnNode/NodeJS开发指南/chapter5/microblog/gulpfile.js
[17:37:14] Starting 'watch'...
[17:37:14] Finished 'watch' after 13 ms
gulp.run() has been deprecated. Use task dependencies or gulp.watch task triggering instead.
[17:37:32] Starting 'lint'...
[17:37:32] Finished 'lint' after 21 ms
/Users/Calvin/Desktop/LearnNode/NodeJS开发指南/chapter5/microblog/models/db.js: line 4, col 39, Missing semicolon.
1 error

运行

  • gulp 等价于gulp default,运行我们在default中定义的所有任务
  • gulp sass,运行我们定义的任何任务

例如运行gulp lint任务

1
2
3
4
5
6
7
➜ /Users/Calvin/Desktop/LearnNode/NodeJS开发指南/chapter5/microblog git:(master) ✗>gulp lint
[16:53:17] Using gulpfile ~/Desktop/LearnNode/NodeJS开发指南/chapter5/microblog/gulpfile.js
[16:53:17] Starting 'lint'...
[16:53:17] Finished 'lint' after 15 ms
/Users/Calvin/Desktop/LearnNode/NodeJS开发指南/chapter5/microblog/models/db.js: line 4, col 39, Missing semicolon.
1 error

完成的任务

在实际的项目中,我们的老板可能会让我们做以下这些事情:

  • 检查JavaScript代码错误
  • 编译Sass文件
  • 拼接JavaScript文件
  • 精简并且重命名拼接后的文件

引入需要用到的库

1
2
3
4
5
6
7
var gulp = require('gulp');
var jshint = require('gulp-jshint');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');

定义文件路径(optional)

当文件分散在多个地方,用一个变量来存会比较好,如

1
2
3
4
var paths = {
serverjs: ['models/*.js', 'routes/*.js','./*.js'],
webjs :['public/javascripts/*.js']
};

Lint任务

Lint任务用来检查我们的js文件有没有错误

1
2
3
4
5
gulp.task('lint',function () {
gulp.src(paths.serverjs)
.pipe(jshint())
.pipe(jshint.reporter('default'));
});

Sass任务

Sass任务编译我们的scss/文件夹下的任何Sass文件到.css文件并将它们存储在css/文件夹下

1
2
3
4
5
gulp.task('sass',function () {
gulp.src('./scss/*.scss')
.pipe(sass())
.pipe(gulp.dest('./css'));
});

Scripts任务

Scripts任务拼接所有位于js/文件夹下的JavaScript文件并将结果输出到我们的dist/文件夹下。
接着gulp将会精简这个拼接文件,重命名并将它存储在dist/文件夹下。

1
2
3
4
5
6
7
8
gulp.task('scripts',function () {
gulp.src(paths.webjs)
.pipe(concat('all.js'))
.pipe(gulp.dest('./dist'))
.pipe(rename('all.min.js'))
.pipe(uglify()).
.pipe(gulp.dest('./dist'));
});

default任务

最后,我们设置了default任务,它基本上是将前面设置的任务进行了一个包装。
它使用.run()方法来引用并运行我们在上面定义的任务。
.watch()方法用来持续的检查指定文件夹中的文件是否发生了变化。
如果是,它将运行我们在它内部指定的所有任务。

1
2
3
4
5
6
7
8
9
10
11
12
13
gulp.task('default',function () {
// 将你的默认的任务代码放在这
gulp.run('lint','scripts');
gulp.watch(paths.serverjs,function () {
gulp.run('lint','scripts');
});
gulp.watch(paths.webjs,function () {
gulp.run('lint','scripts');
});
});

常用插件

安装

1
npm install gulp-jshint gulp-sass gulp-concat gulp-uglify gulp-rename --save-dev

gulp-uglify 压缩源码

1
2
3
4
5
6
7
8
var uglify = require('gulp-uglify');
//压缩代码并存储
gulp.task('default', function() {
gulp.src('./src/*.js')
.pipe(uglify())
.pipe(gulp.dest('./build/'));
});

gulp-rename 重命名

1
2
3
4
5
6
7
8
9
10
11
var rename = require('gulp-rename');
//将压缩过的代码重新命名为扩展名`.min.js`,然后存到build文件夹
gulp.task('default', function() {
gulp.src('./src/iNotify.js')
.pipe(uglify())
.pipe(rename({
extname:'.min.js'
}))
.pipe(gulp.dest('./build/'));
});

gulp-jshint 检查js文件的语法

1
2
3
4
5
6
7
var jshint = require('gulp-jshint');
gulp.task('js', function () {
return gulp.src('js/*.js')
.pipe(plugins.jshint())
.pipe(plugins.jshint.reporter('default'));
});

关于reporter,默认可以使用’defautl’来输出,也可以使用外置的模块来格式化输出,例如jshint-stylish,

1
2
3
4
5
var stylish = require('jshint-stylish');
stuff
.pipe(jshint())
.pipe(jshint.reporter(stylish))

或者

1
2
3
stuff
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish'));

更多的请查看github

gulp-sass 编译sass文件

gulp-concat 拼接文件

1
2
3
4
5
6
var concat = require('gulp-concat');
gulp.task('scripts',function () {
gulp.src(paths.webjs)
.pipe(concat('all.js'))
...

gulp-load-plugins 加载package.json中所有的gulp插件

1
2
3
4
5
6
7
8
9
10
11
var gulpLoadPlugins = require('gulp-load-plugins'),
plugins = gulpLoadPlugins();
gulp.task('js', function () {
return gulp.src('js/*.js')
.pipe(plugins.jshint())
.pipe(plugins.jshint.reporter('default'))
.pipe(plugins.uglify())
.pipe(plugins.concat('app.js'))
.pipe(gulp.dest('build'));
});

gulp官网的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
var gulp = require('gulp');
var coffee = require('gulp-coffee');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var imagemin = require('gulp-imagemin');
var sourcemaps = require('gulp-sourcemaps');
var del = require('del');
var paths = {
scripts: ['client/js/**/*.coffee', '!client/external/**/*.coffee'],
images: 'client/img/**/*'
};
// Not all tasks need to use streams
// A gulpfile is just another node program and you can use any package available on npm
gulp.task('clean', function() {
// You can use multiple globbing patterns as you would with `gulp.src`
return del(['build']);
});
gulp.task('scripts', ['clean'], function() {
// Minify and copy all JavaScript (except vendor scripts)
// with sourcemaps all the way down
return gulp.src(paths.scripts)
.pipe(sourcemaps.init())
.pipe(coffee())
.pipe(uglify())
.pipe(concat('all.min.js'))
.pipe(sourcemaps.write())
.pipe(gulp.dest('build/js'));
});
// Copy all static images
gulp.task('images', ['clean'], function() {
return gulp.src(paths.images)
// Pass in options to the task
.pipe(imagemin({optimizationLevel: 5}))
.pipe(gulp.dest('build/img'));
});
// Rerun the task when a file changes
gulp.task('watch', function() {
gulp.watch(paths.scripts, ['scripts']);
gulp.watch(paths.images, ['images']);
});
// The default task (called when you run `gulp` from cli)
gulp.task('default', ['watch', 'scripts', 'images']);

参考