先贴出原文「基于 gulp 的前端构建」和代码「gulp-project」。
项目目录如下:
├─ gulp/ # gulp配置目录
├─ tasks # 任务配置目录
├─ image.js # 图片配置
├─ other.js # 其它配置
├─ script.js # 脚本配置
├─ style.js # 样式配置
└─ view.js # 页面配置
└─ config # gulp配置文件
├─ src/ # 开发目录
├─ html/ # 存放html的目录
├─ app/ # 可提取复用的页面模块
└─ page/ # 各页面入口文件
├─ images/ # 存放图片的目录
├─ single/ # 不需要合并的图片
└─ sprite/ # 需要合并的图片
├─ js/ # 存放js的目录
├─ app/ # 可提取复用的脚步模块
├─ lib/ # 第三方js库
├─ page/ # 各页面入口脚本文件
└─ config.js # RequireJs的配置文件
└─ sass/ # 存放sass的目录
├─ app/ # 可提取复用的样式模块
└─ page/ # 各页面入口样式文件
├─ .jshintrc # jshint参数配置文件
├─ gulpfile.js # gulp入口配置文件
└─ package.json # npm包管理文件
其中专门创建一个 gulp 目录用来存放 gulp 代码,为了能够将任务更加细化,职责单一,方便日后的维护更新。
└─ gulp/ # gulp配置目录
├─ tasks # 任务配置目录
├─ image.js # 图片配置
├─ other.js # 其它配置
├─ script.js # 脚本配置
├─ style.js # 样式配置
└─ view.js # 页面配置
└─ config # gulp配置文件
配置的命令如下:
$ gulp help # 说明帮助
$ gulp sass # sass本地编译
$ gulp jshint # js语法检测
$ gulp include # html包含依赖编译
$ gulp dev # 开发监控,浏览器不自动刷新
$ gulp serve # 开发监控,浏览器自动刷新
$ gulp build # 打包上线
在开发阶段,执行 gulp dev 命令,gulp 会进行一系列构建操作,最后在 dist 目录下生成可运行文件,并实时监听源文件,一旦源文件改动会执行相应的操作。
// 开发监控,浏览器不自动刷新
gulp.task('dev', function(cb) {
runSequence(
'clean:dist',
'clean:tmp',
['copy:img', 'sass', 'jshint', 'copy:js', 'include'],
'watch',
cb
);
});
执行 gulp serve 命令,gulp 会执行跟 gulp dev 一样的操作并监听源文件,唯一不同的是它在执行后会监听某个端口,一旦有文件改动它会帮你自动刷新浏览器,帮你省下了按 F5 的力气。当然在同时开上多个浏览器测试页面时它将会很有帮助。
// 开发监控,浏览器自动刷新
gulp.task('serve', function(cb) {
runSequence(
'clean:dist',
'clean:tmp',
['copy:img', 'sass', 'jshint', 'copy:js', 'include'],
'reload',
cb
);
});
在上线打包阶段,通过以下代码一个大体知道,上线打包主要是对图片样式脚本进行打包处理。所以接下来的工作就是职责分工,独立完成各自的构建工作。
gulp.task('build', function(cb) {
runSequence(
'clean:dist',
'clean:tmp',
'build:img',
'build:css',
'build:js',
'build:html',
'clean:tmp',
cb
);
});
第一个步骤主要是对图片进行处理,包括图片合并压缩 hash 戳等。其中对 css 代码处理是为了替换合并后的图片路径。
// 打包图片
gulp.task('build:img', function(cb) {
runSequence(
'sass:tmp',
'copy:tmpImg',
'autoSprite',
'imagemin',
'rev:img',
cb
)
});
第二个步骤主要是对 css 文件进行处理,其中还包括替换已经 hash 的图片资源,并生成 hash 戳。
// 打包css文件
gulp.task('build:css', function(cb) {
runSequence(
'usemin:css',
'sass:dist',
'rev:css',
cb
);
});
第三个步骤是 js 文件的打包,打包 RequireJs 代码可以根据依赖进行 js 文件的合并压缩,最终每个页面都打包一个 js 文件为单入口。
// 打包js文件
gulp.task('build:js', function(cb) {
runSequence(
'requirejs',
'uglify:config',
'rev:js',
'copy:js',
cb
);
});
第四个步骤是 html 文件的打包,替换掉前面已经 hash 的静态资源即可。
// 打包html文件
gulp.task('build:html', function(cb) {
runSequence(
'include',
'usemin:html',
cb
);
});
最终生成的代码依然在 dist 目录下,也就是说在开发阶段与上线打包阶段构建生成的代码都在同一个目录下,只不过在开发阶段代码是未进行合并压缩,上线打包阶段代码是经过合并压缩打上 hash 戳的。所以建议该目录下的代码不需要添加到版本控制中。
未解决的问题是对 RequireJs 的路径配置(config.js 与 gulp 中的配置)感到困惑迷糊,多创建一个目录就路径不匹配打包不成功。还有RequireJS 若添加第三方库,需要手动修改 gulp 代码,个人感觉比较麻烦。