1.任务分离
当使用gulpfile.js进行任务自动化的时候,对于习惯了模块化结构的人来说,把大量的工作写在同一个gulpfile.js是一种折磨,为了坚持一个文件处理好一件事,趁着有空,便探索了下gulp的使用技巧:分离任务到多个文件中
在gulpfile.js下加如下代码
var requireDir = require('require-dir'); // 就是这个插件
var dir = requireDir('./tasks');
gulp.task('default',["sometask"]); // 直接注入dir下的目录任务模块就好了
以下是结构目录
gulpfile.js
tasks/
├── script.js
├── css.js
└── test.js
这样就可以一个任务用来处理js压缩,一个用来处理css压缩,一个处理sass转化和视图刷新,当然还可以ftp上传啦!
2.每个文件夹压缩成一个文件
写angularjs的时候,由于模块化分离,会有多个文件夹,虽然最后的做法是将所有文件压缩成一个min文件(减少请求),但是习惯性的将合并后的代码先保存一份到debug文件夹下,这样程序出错时便于调试
目录如下:
js/
├── controller/
│ ├── index_ctrl.js
│ └── test_crl.js
│
├── sevice/
│ ├── index_sv.js
│ └── test_sv.js
│
├── filter/
│ └── filter.js
│
├── debug/
│ ├── controller.debug.js
│ ├── service.debug.js
│ └── filter.debug.js
│
└── app.min.js
文件代码如下
var fs = require('fs');
var del = require('del'); // 用于删除debug文件夹生成的文件
var path = require('path');
var merge = require('merge-stream');
var gulp = require('gulp');
var scriptsPath = './js';
var scriptsDebugPath = './js/debug'
// 获取文件夹
function getFolders(dir) {
return fs.readdirSync(dir)
.filter(function(file) {
return fs.statSync(path.join(dir, file)).isDirectory();
});
}
gulp.task('scripts', function() {
var folders = getFolders(scriptsPath);
var tasks = folders.map(function(folder) {
return gulp.src(path.join(scriptsPath, folder, '/*.js'))
// 这里执行任务
.pipe(gulp.dest(scriptsDebugPath)) // 保存一份到debug
});
return merge(tasks);
});
gulp.task('delete:debug',['scripts'],function(cb){
del([
'./js/debug.min.js' // 删除生成的debug
], cb);
})
3.上传FTP
公司的工作需要将修改的代码提交后台服务器才能通过在线测试环境查看效果,sublime有对应的ftp上传插件,如果使用gulp,我需要压缩完,或者合并后的debug上传得每次压缩完了就手动上传,这不符合自动化管理,于是我找到了gulp-ftp工具
代码如下
var gulp = require('gulp');
var gutil = require('gulp-util');
var ftp = require('gulp-ftp');
gulp.task('upload', function () {
return gulp.src('src/*')
.pipe(ftp({
host: 'website.com',
port: '80',
user: 'test',
pass: '1234',
remotePath: '/vhost/myproject/js/'
}))
// you need to have some kind of stream after gulp-ftp to make sure it's flushed
// this can be a gulp plugin, gulp.dest, or any kind of stream
// here we use a passthrough stream
.pipe(gutil.noop());
});
注意: 使用版本管理器的时候不要把ftp的配置都上传到公有环境中了哦,这里提供两种方法:
一是在配置中使用命令行传入参数填充(不知能不能读取环境变量)
二是创建一个ftp.default.js的文件代替上传,而填有配置的ftp.js文件在.gitignore(git为例)中不上传.
4.网页刷新
页面刷新需得配合浏览器的插件, 在chrome来说插件是LiveReload, 其它浏览器未知, 该刷新有个好处是当改变css的时候, 并不是真正意义上的全体刷新, 而是触发了一次重绘(不重新加载文件), 只有监听的是html或者js时才会重新加载文件
启用步骤:
- var livereload = require('gulp-livereload'); // 引用模块
- var reload = livereload(); // 开启livereload
-
点击浏览器插件使其运作
- 在watch文件中执行
reload.changed(event.path);
来刷新浏览器
代码如下:
var livereload = require('gulp-livereload');
var reload = livereload(); // 执行该语句后,点击插件则才会成功
gulp.watch('./html/rebuild-js/**/*.js',function(event){
console.log(event.path);
reload.changed(event.path); // 刷新浏览器
})
5.自动化(watch监听)
有了各个处理功能后, 就可以进行监听文件的改变来自动化执行以上操作, gulp.watch()接收一个数组来监听里面的内容, 数组中的字符串有点像正则表达式
如:
- 监听 js 文件夹下的所有.js文件:
"js/*.js"
- 不监听js文件夹下的.min.js文件:
"!js/*.min.js"
一个完整监听(监听所有js文件夹下的非.min.js文件的js文件)
gulp.watch(["js/*.js", "!js/*.min.js"],function(event){
// pass
})
6.最终代码(js处理)
var fs = require('fs');
var path = require('path');
var merge = require('merge-stream');
var gulp = require('gulp');
var gutil = require('gulp-util');
var ftp = require('gulp-ftp');
var livereload = require('gulp-livereload');
var srcPath = './html/rebuild-js';
var destPaht = './html/js/'
var destDebugPath = './html/js/debug'
// 获取文件夹
function getFolders(dir) {
return fs.readdirSync(dir)
.filter(function(file) {
return fs.statSync(path.join(dir, file)).isDirectory();
});
}
gulp.task('js.min', function(){
var folders = getFolders(srcPath);
var tasks = folders.map(function(folder){
dealJs(path.join(srcPath, folder, '/*.js'));
})
return merge(tasks);
});
function dealJs(_src) {
return gulp.src()
.pipe(ngAnnotate()) // 生成angular注入声明
.pipe(concat(_objJs.name)) // 合并
.pipe(rename({suffix: '.debug'})) // 加debug.js小后缀
.pipe(gulp.dest(destDebugPath)) // 未压缩的用于debug
.pipe(uglify().on('error',function(e){ // 压缩
console.log(e);
}))
.pipe(rename({suffix: '.min'})) // rename压缩后的文件名
.pipe(gulp.dest(destPaht))
.pipe(ftp({ // 写入ftp配置
host: '.....',
port: '.......',
user: '...',
pass: '.......',
remotePath: '..........'
}))
.pipe(gutil.noop()); // 上传ftp
};
// 检测改动过后的文件,并压缩上传
gulp.task('watchJs',['scripts','upload'],function(){
var reload = livereload();
gulp.watch('./html/rebuild-js/**/*.js',function(event){
console.log(event.path);
dealJs(event.path);
reload.changed(event.path); // 刷新浏览器
})
})
写在结束
好了,我的任务总算能流水线的工作了(上面js为例)
1.当我修改js文档保存的时候
2.程序自动将每个js下的文件夹合并,并各自生成一份debug文件供调试用
3.将合并的js文件全部丑陋化和压缩生成xx.min.js
4.将xx.min.js上传到ftp上
5.刷新视图