gulp
问题
使用bower可以很方便管理多个第三方库,但是仍然需要在页面中引用,譬如:
<head>
<script type="text/javascript" src="js/jquery/jquery.js"></script>
<script type="text/javascript" src="js/bootstrap/bootstrap.js"></script>
......
</head>
可否有一种工具,能够帮我们自动将上述多个第三方库打包成一个文件,形如:
<head>
<script type="text/javascript" src="dist/app.js"></script>
</head>
构建
实际上,在前端项目的开发过程中,有许多类似的需求,它们通常发生成阶段性开发完成,需要交付部署或下一阶段的时机,故称之为构建(build)
- 将多个js或css文件合并成一个文件
- 开发时引用带注释的代码版本或source map版本(易于阅读和调试),部署时则对代码进行压缩(提高运行效率)
- 自动对项目中的scss文件进行转译
- 对html、css、javascript等代码做校验(validate)或检查(lint)
- 对项目所引用的图片进行压缩和优化,提高加载效率
- ...
构建工具
构建工具是帮助开发自动完成上述各类任务的软件工具,前端常见的工具如:
它们大同小异,各有所长,我们这里将以 gulp 为例
安装 gulp
npm install --global gulp-cli
cd your-project
npm init # 将在项目根目录下创建package.json文件,用于记录所依赖的包的安装信息
npm install --save-dev gulp
gulp --version # 查看到版本号,安装成功
如何使用gulp执行构建任务
- 如果是前端开发中常见的任务,gulp社区一般提供有现成的插件,只需要引用和执行即可
- 如果的一个构建过程需要串联执行多个任务,gulp提供类似管道机制,允许你安装其先后顺序
- 如果没有现在插件,则gulp提供一些构建活动常用的api,供你自定义开发
编写构建脚本
在项目根目录下,创建一个 gulpfile.js 文件,首先引用所需要到的插件
var gulp = require('gulp'),
uglify = require('gulp-uglify'),
concat = require('gulp-concat')
gulp.task('compress', function () {
return gulp.src('./js/*.js')
.pipe(uglify())
.pipe(concat('app.js'))
.pipe(gulp.dest('./dist'))
);
});
构建任务与构建相关工具
要运行这个构建脚本,首先需要在当前系统中安装所需的各个插件包,即:
npm install --save-dev gulp-uglify gulp-concat
- uglify是一个对js代码进行压缩的库,concat则是合并多个文本文件的库。gulp-uglify等是gulp插件,将uglify这个js库引入到gulp构建过程中,并执行相应的任务
require()
则是node.js环境下用于引用或引入第三方包的语法
gulp.task()
gulp.task()
方法表示注册了一个名为compress
的任务,该任务的流程是:
- 遍历读取
js
目录下的所有js
文件 - 将这些文件依次压缩,即去掉注释、空格、简化变量名或函数名等
- 将所有这些文件合并为
app.js
- 然后将
app.js
保存至dist
目录下 - 最后,给出一个信息通知,告知该任务已经完成
注意pipe()
这个函数,它接收一个stream,同时也返回一个stream,从而串联成一个流水线,依次执行。详情请参考官方手册
执行构建任务
命令行下输入,将执行所有gulp任务
gulp
或者,显示的指定任务的名称
gulp compress
如执行成功,则会发现dist/app.js
被创建,并且正好包含了所有js的压缩版本
与bower结合
bower可以与gulp配合使用,前者解决客户端依赖包的下载,后者解决软件包的合并。
但上述代码存在一个问题,即bower_components目录下的文件布局通常比较复杂,难以使用类似gulp.src('js/*.js')
这类方法表达,针对这类问题,gulp社区提供了main-bower-files 插件
var gulp = require('gulp');
var mainBowerFiles = require('main-bower-files');
gulp.task('compress', function() {
return gulp.src('./bower.json')
.pipe(mainBowerFiles( ))
.pipe( uglify() )
.pipe( concat('app.js') )
.pipe( gulp.dest('./dist') )
});
辨析
- gulp、bower等工具及其插件,自身都是服务端程序(需要读写磁盘),必须运行于node环境下
- 下载基于npm包管理,保存在node_modules目录下
- 编写构建脚本时(服务端程序),可使用
require
语句引入各类gulp plugin
- bower所下载的js库,都是客户端程序(客户端应用项目所依赖),未来将运行在浏览器中
- 下载通过bower这类服务端工具,保存在bower_componenents目录下
- 客户端项目中使用时,需要使用
<script>
的方式引入
结合上述两者工具,即通过一个构建过程,则可借助服务端的工具,简化客户端应用的开发