gulp使用经验谈…各种坑

为何要用构建工具?
一句话:自动化。对于需要反复重复的任务,例如压缩(minification)、编译、单元测试、linting等,自动化工具可以减轻你的劳动,简化你的工作。当你正确配置好了任务,任务运行器就会自动帮你或你的小组完成大部分无聊的工作。

上面这段话摘自grunt官网翻译,解释了为何要使用grunt这类自动化构建工具。其实很早以前类似的工具就有了,java、php版都有,当然相比于现在的grunt,可能部分方面还有缺失。而一些IDE工具,甚至 sublime、vim也都有实现类似功能的插件。

我之前一直项目中用的是一个基于php的合并压缩工具,除了自动刷新浏览器这个不支持(应该想的话也是可以的),其它使用起来都还好。grunt前年、去年都有试着去配置一下用,当时因为没认真了解过nodejs,感觉配置起来好麻烦,虽然有教程或者别人配置好的,但是我一直奉行弄懂了原理机制才敢放心大胆去用,而且别人配置好的不一定是适合我的,我可能要改变自己的编码习惯,这也是我所不愿意的。

正好前一阵没事去看了下nodejs相关的一些东西,了解了下模块加载、包管理相关的东西,正好也看到别人提到了gulp这个东西,看了下配置,觉得比grunt容易很多,很容易上手。

Gulp官网 Gulp插件

于是边学边用,经过几周的上手,终于配置了一套适合自己的工具。当然,这之前也从对gulp的一知半解到后来可以根据自己需求修改、编写插件,也遇到了不少的坑,所以今天就是来分享这些填坑经验的。
gulp-2x

1. 了解node中文件路径配置

gulp内建的.src .dest .watch等方法,传入的文件路径的解析是通过glob这个模块处理的,所以可以先去了解下这个路径字串格式的配置方法,这样子对自由组织选取文件操作很有帮助。

例如想要通过文件名排除某些文件的时候,就可以这样:

1
gulp.src('css/**/!(_)*'); //排除以_开头的文件

node-glob

2. .watch方法路径不要用 './xx'

'./xx' 开头作为当前路径开始,会导致无法监测到新增文件,所以直接省略掉 './' 即可。'./images/*' === 'images/*'

3. .watch使用change事件来同步删除情况

网上看到的很多教程只有文件改变或者新增来自动处理这部分文件,但是删除了源文件,输出文件夹里的对应文件却没有相应的自动删除。其实可以通过change事件来检测删除情况。

1
2
3
4
var watcher = gulp.watch('js/**/*.js', ['uglify','reload']);
watcher.on('change', function(event) {
  console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
});

event.type==deleted 时就可以对应处理删除情况,这里不再赘述删除文件的处理。

4. 使用gulp-changed来过滤变动的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var gulp = require('gulp');
var changed = require('gulp-changed');
var ngmin = require('gulp-ngmin'); // just as an example 
 
var SRC = 'src/*.js';
var DEST = 'dist';
 
gulp.task('default', function () {
    return gulp.src(SRC)
        .pipe(changed(DEST))
        // ngmin will only get the files that 
        // changed since the last time it was run 
        .pipe(ngmin())
        .pipe(gulp.dest(DEST));
});

changed的参数中输出文件夹这一参数不能省,而且不能和源文件夹相同。gulp-watch 也可以实现类似效果,而且不需要指定输出文件夹,但是首次使用文件变动它无法正确处理到。

gulp-changed

5. 使用gulp-plumber来捕获处理任务中的错误

在gulp的管道流任务处理中,如果某个环节出了错,会导致整个任务中断,包括watch任务,这很麻烦。所以gulp-plumber来了。

1
2
3
4
5
6
7
var plumber = require('gulp-plumber');
var less= require('gulp-less');
 
gulp.src('./src/*.ext')
    .pipe(plumber())
    .pipe(less())
    .pipe(gulp.dest('./dist'));

gulp-plumber

6. 多个合并文件任务的处理方法

简单的项目中可能只需要合并处理一个js、css文件,但是复杂项目中需要合并处理的文件可能不止一个。css好说,好多合并插件都可以处理 @import ,而js该怎么处理呢?

一种办法是写死任务,有几个合并需求就在gulpfile.js里配置几个任务。我讨厌这种方法。

另一种就是我在用的方法, 将js合并的配置写到package.json里,比如我放到 minjs 这个字段下,我的gulpfule.js中关于js合并部分的代码如下:

1
2
3
4
5
6
7
8
9
var minijs=require("./package.json").minijs;
var concat=require("gulp-concat");
Object.keys(minijs).forEach(function(name){//合并压缩package.json里指定的文件
    gulp.task(name+'js', function() {
        return gulp.src(minijs[name])
            .pipe(concat(name+'.js'))
            .pipe(gulp.dest('dist/js'));
    });
});

有任何问题或者其它经验交流欢迎下面评论。

本文已经有 12 条评论,继续盖楼啦!

  1. html5的发展html5的发展html5的发展html5的发展html5的发展html5的发展html5的发展html5的发展html5的发展html5的发展html5的发展html5的发展html5的发展html5的发展html5的发展html5的发展html5的发展html5的发展html5的发展html5的发展html5的发展html5的发展html5的发展html5的发展html5的发展

  2. 您好,我现在遇到一些问题,就是我新增的html文件一直不会再浏览器中刷新,我已经试过了2方法,但是还是不行,感觉好像是自己哪里写错了,希望得到帮助,谢谢。这个是我企鹅578767687

发表评论 取消回复