Skip to content

构建工具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> 等方式引入

借助服务端的工具链,简化客户端应用的开发——这正是"前端工程化"的起点

参考