Appearance
构建工具gulp
元信息
- 目标:理解"构建/打包"要做什么(转译、压缩、合并、校验),掌握 gulp 用管道流串联任务流的自动化方式(历史地位,思路被后世工具继承)
- 关键概念:构建、打包、任务流、管道、gulp插件、gulpfile
- 关联阶段:cp3
- 常见误区:以为构建工具是浏览器提供的(gulp 等工具自身是 Node 服务端程序,产物才跑在浏览器);以为打包只是合并文件(含转译压缩、tree-shaking、代码分割等);以为 gulp 与 webpack 是同类竞品(gulp 是任务流自动化,webpack 是模块打包器)
问题
即使暂不考虑构建,页面中也需要引用多个第三方库和自己的脚本,譬如:
html
<head>
<script type="text/javascript" src="js/jquery/jquery.js"></script>
<script type="text/javascript" src="js/bootstrap/bootstrap.js"></script>
......
</head>可否有一种工具,能够帮我们自动将上述多个第三方库打包成一个文件,形如:
html
<head>
<script type="text/javascript" src="dist/app.js"></script>
</head>打包与构建
- 构建 build :在发布之前,需要执行的各种预处理工作,如各种HTML\CSS\JS的转译工作等
- 开发时引用带注释的代码版本或source map版本(易于阅读和调试),部署时则对代码进行压缩(提高运行效率)
- 自动对项目中的scss文件进行转译
- 对html、css、javascript等代码做校验(validate)或检查(lint)
- 对项目所引用的图片进行压缩和优化,提高加载效率
- 打包 bundle:一是将后端的模块转换为前端的格式,二是将分散的多个前端资源组成适合部署的形式(早期为单个文件,故名为打包),以及其它优化任务
- tree-shaking
- lazy-loading
- chunk splitting
构建工具
构建工具是帮助开发自动完成上述各类任务的软件工具,前端常见的工具如:
它们大同小异,各有所长,我们这里将以 gulp 为例
安装 gulp
bash
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 文件,首先引用所需要到的插件
javascript
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'))
);
});构建任务与构建相关工具
要运行这个构建脚本,首先需要在当前系统中安装所需的各个插件包,即:
bash
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.task()写法是 gulp 3 时代的经典风格,便于理解任务注册的概念。gulp 4+ 推荐exports风格:把任务函数赋值给module.exports的属性即可,如exports.compress = function () { ... },并以gulp.series()/gulp.parallel()组合任务。
执行构建任务
命令行下输入,将执行所有gulp任务
bash
gulp或者,显示的指定任务的名称
bash
gulp compress如执行成功,则会发现dist/app.js被创建,并且正好包含了所有js的压缩版本
辨析
- gulp 等构建工具及其插件,自身都是服务端程序(需要读写磁盘),必须运行于node环境下
- 下载基于npm包管理,保存在node_modules目录下
- 编写构建脚本时(服务端程序),可使用
require语句引入各类gulp plugin
- 而被构建的 js/css/html 等前端资源,是客户端程序,未来将运行在浏览器中
- 构建产物(如 dist/app.js)在页面中以
<script>等方式引入
- 构建产物(如 dist/app.js)在页面中以
借助服务端的工具链,简化客户端应用的开发——这正是"前端工程化"的起点