基于 gulp 的前端构建
目录结构
├─ 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 目录
参考:「前端 | 重构 gulpfile.js」。其中专门创建一个 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 代码。
thanks
@zhangwanli09 这个 issue 已经关闭了,详情请戳这里,谢谢~
你好 ,我有个问题, 如果开发环境和生产环境在同一个dist内 ,就意味着不能同时存在。如果项目总体没有完成但是有部分需求已经实现需要先提交,就意味着需要先清空dist 然后启动生产build。然后提交后再清除dist转入生产环境。如果多人配合完成项目这是个问题。
谢谢。哦 刚看到最后的一句了。不适合添加到版本控制
@zhangwanli09 只要有 src 和 gulp 的代码,就可以通过命令生成 dist,所以 dist 不需要添加到版本控制中。
嗯 ,最近要引入webpack到我目前的gulp流里,因为是多页面的。所有看到这里了。谢谢你的回复。
@zhangwanli09 不客气,有问题可以找我交流。
老兄,这份年代有点远,还能用吗?
@sinner77 可以啊,这只是一个思路,用 grunt 或 gulp 都可以。
哈哈。谢谢。正在学习中
@sinner77 不客气,祝元旦快乐。
哈哈。元旦快乐。
想问下为什么需要一个tmp目录,是一个临时文件夹?起到什么作用
@sinner77 有些步骤无法一次完成,比如说 css 要编译 sass,要替换已经 hash 的图片,最后还要压缩打 hash 戳。如果将这些中间生成的 css 文件放在 src 和 dist 的话打包完成后删除会比较繁琐,所以专门添加一个 tmp 临时文件夹来存放,打包完成后直接删了 tmp 就行。
明白
请问下目录结构是怎么生成的?md没有这种语法呀 感谢
@sinner77 目录结构是自己手动敲上去的。
呀 原来这样 这有点工作量 哈哈哈