起因我就不说了、我就不说那个傻瓜打包工具有多弱爆了、我就不说那个工具叫koala了...
一、先从安装gulp开始
sudo npm install -g gulp
npm install gulp
既要全局安装,因为一会儿要用到gulp命令行;也要在项目中本地安装,因为代码中要引用gulp模块。
现在我们还不能使用gulp,因为还没给它写配置文件
二、接着说gulpfile.js
gulpfile.js应该是gulp的默认配置文件吧,执行gulp命令时、它就会自己去找当前目录中的gulpfile.js。
通常我把它放在项目根目录下、那么里面所提及的文件路径也都是相对于根目录的相对路径。
三、执行第一个gulp任务
gulp的工作模式就是你定义好任务,然后用gulp命令去执行任务。任务中可能处理各种各样的问题、比如打包js、编译less等,那么就有很多相应的gulp插件去处理这些问题,比如gulp-less, gulp-concat。
gulp的常见任务让它必须有监控和自动执行的能力,比如监控某个文件夹的变化、然后执行某个task,这个用的是gulp-watch。
通常我们会用gulp去定义很多个task,那么这些task之间如果有依赖关系,也可以在gulp配置文件中定义,这样便能保证所依赖的task一定在你的task之前执行完成。
现在我们来定义并执行第一个任务:
gulpfile.js:
var gulp = require('gulp');
gulp.task('default', function(){
console.log('第一个gulp任务完成啦');
});
这个任务的名字叫default, 做的事情就是在控制台打印一个日志。
执行default任务
gulp default
//或者
gulp
2
你懂的,如果省略任务名字,那么gulp会默认执行default任务。另外, gulp也可以执行多个任务:
gulp task1 task2 task3
四、用gulp编译less
我项目下有一个common.less文件,其中引用了./common中的两个less文件。我想把这个文件编译成同级目录下的common.min.css,这顺便也会把引用的less打包进来。
3
其中common.less文件:
@import (less) "./common/common.less";
@import (less) "./common/smarttable.less";
/* 搜索条 */
.isea-search-container {
padding: 15px 10px;
background: #fff;
...
}
}
gulpfile.js代码如下:
var gulp = require('gulp');
var rename = require("gulp-rename");
var less = require("gulp-less");
/**
* 编译less
* 输入:resources/css/common.less
* 输出:resources/css/common.min.css
*/
gulp.task('less_common', function(){
console.log('编译resources/css/common.less -> resources/css/common.min.css');
gulp.src('resources/css/common.less')
.pipe(less())
.pipe(rename({
basename: "common.min",
extname: ".css"
}))
.pipe(gulp.dest('resources/css/'));
});
当然这里用到了两个插件:
gulp install gulp-less
gulp install gulp-rename
其中gulp-less编译less,gulp-rename用来给输出文件重命名。
gulp.src()
gulp.src()接口用来制定输入的文件流,参数可以是一个字符串、也可以是字符串数组。字符串中可以带通配符,这里就不展开了。
这里的路径一定不能搞错——都是相对于gulp命令执行环境的相对路径。
gulp.dest()
gulp.dest()接口用来制定文件输出的路径。通常你不能把输出文件跟输入文件路径指定成一个,因为输出文件名跟输入的文件名是一模一样的。
gulp.pipe()
很显然,gulp接口是链式调用的。在输出和输入之间,可以用pipe指定任意的插件去处理你的文件。
less()
less()最基本的使用,就是没有参数的调用一下。
rename()
rename()用来重命名输出的文件、不让它跟源文件名一模一样。它接收一个对象参数。其中basename是文件名,extname是后缀。basename中可以直接指定子路径(基于dest中的路径)、子路径会被自动创建。我们现在通过这个插件把输出文件指定为common.min.css了。
当输出文件是多个时,这个rename要怎样去使用我还不知道。
现在执行这个less_common任务
gulp less_common
4
五、用gulp打包js文件
在开发的时候、js代码通常是不同模块或组件写到单独的文件中。但如果在页面中单独加载、会给加载速度带来负担。所以要把很多js打包成一个js文件。
比如我现在要把./common/下的所有js文件打包成一个./common.min.js文件:
有点多、是真的~~、
gulpfile.js代码:
/**
* 打包js
* 输入:controls/common/*.js
* 输出:controls/common.min.js
*/
gulp.task('control_common', function(){
console.log('打包controls/common/*.js -> controls/common.min.js');
gulp.src([
'./controls/common/utils.js', //第一个
'./controls/common/Components.js',
'./controls/common/MarkWidget/MarkManager.js',
...
'./controls/common/MarkWidget/MarkWidget.js', //有依赖
])
.pipe(concat('common.min.js'))
.pipe(gulp.dest('controls/'));
});
我之所以没有写成gule.src('./controls/common/*') 是因为我的文件之间有依赖关系、要保证一些文件先执行。而我的模块文件中并没有指定依赖关系,所以这样写最为保险。
但这也带来一个恶心的问题、就是每次我新增一个文件到文件夹中、都要手动改这个task。所以、依赖问题还有待更好的方案。
这里用到了gulp-concat插件:
npm install gulp-concat
concat()
concat()用来把源文件连接起来,可以有一个参数指定输出文件的名字。这样就不需要rename()了。但这个命令不能用于less打包中代替rename(),只用用雨js打包,我也百思不得姐。。
执行control_common
gulp control_common
就会得到common.min.js, 不会错的~!
六、指定一个任务,一次性调用所有任务
没错,这个任务名叫default:
gulp.task('default', [
'less_common',
'control_common'
],
function () {
console.log('static项目的构件开始啦!');
});
我是通过任务依赖列表来实现这个目的的。执行gulp
它就会把刚才的两个任务都跑一边啦。
七、监控文件修改、并自动执行任务
当./common/.less修改时,应该自动执行less_common任务,当./common/*.js修改时,应该自动执行control_common任务:
/* 监控并执行任务 */
gulp.task('default', [
'less_common',
'control_common'
],
function () {
console.log('static项目的构件开始啦!');
gulp.watch(['resources/css/common/*.less'], ['less_common']);
gulp.watch(['controls/common/*.js'], ['control_common']);
});
gulp.watch()
gulp.watch()第一个参数是监控的文件列表,第二个参数是执行的任务列表。很方便是吧、一看就会。
要注意gulp.watch()接口调用后后并不会立即执行后面的任务,而是第一次检测到文件变化时才执行。所以立即执行的能力还是依赖于前面的依赖列表。
现在,重新执行gulp
, 每次修改less或js都会自动重编译这两个文件的。到这里、我最基本的问题已经解决了、又可以无忧无虑地改Bug了,啦啦啦~
6终于把koala退出啦...
八、写个命令执行所有gulp任务
实际工作中我有两个项目用到了gulp打包,为了每次能更方便的执行gulp任务,我准备写个脚本来启动所有gulp任务
1.先写一个gulp.sh脚本
(/Users/wangxiaokuai/Coding/bash/gulp.sh):
cd /Users/wangxiaokuai/Overseas/superboss-overseas-static;
gulp &
cd /Users/wangxiaokuai/Overseas/oversea2;
gulp &
其中 &代表后台执行的意思。这样客户端不会被服务阻塞住。这样执行即可:
sh /Users/wangxiaokuai/Coding/bash/gulp.sh
2.用alias自定义一个gulpall命令
但这个命令参数太长、根本没法记住。所以在命令行执行这句话:
alias gulpall="sh /Users/wangxiaokuai/Coding/bash/gulp.sh"
然后就可以直接敲gulpall
来启动脚本了~
alias命令只对当前shell窗口有效,关闭或重启后都无效。所以你应该把它添加到/etc/bashrc中去。这样每次开机都会自动执行、而且全局有效。
3.开机自动执行gulpall
我不喜欢这样做,如果像、那就在/etc/bashrc中添上一句:
gulpall
九、Gulp下一步
gul还有几个问题没解决
- gulp编译报错信息完全没有、出错的时候根本无法调试
- 代码压缩
- 更轻松的模块依赖关系
- 代码映射...
如果这几个问题能解决,我的gulp打包就比较专业了。那我就有点厉害了、、、、
网友评论
如果是不想打包、想“原样输出”的话、直接把concat去掉就行啦
gulp.task('test', function(){
gulp.src('./controls/common/**/*.js')
.pipe(gulp.dest('output/'));
});