简介

自动化构建是前端工程化当中一个非常重要的组成部分,那在具体学习之前我们先来解读一下这一个开发行业当中经常提起的名词。

自动化实际上就是指的是我们通过机器去代替手工完成一些工作,构建呢可以理解为转换,就是把一个东西换转换成另外的一些东西。

那总的来说开发行业的自动化构建就是把我们开发阶段写出来的源代码自动化的去转换成生产环境当中可以运行的代码或者程序。

那一般我们会把这样一个转换的过程称之为自动化构建工作流,他的作用就是让我们尽可能去脱离运行环境的种种问题,去在开发阶段去使用一些提高效率的语法、规范和标准。

最典型的应用场景呢就是我们去开发网页应用时我们就可以使用ECMAScript最新标准去提高编码效率和质量。

利用Sass去增强css的可编程性,然后借助模板引擎去抽象页面当中重复的html。

那这些用法在浏览器当中是没有办法直接被支持的,那这种情况下自动化构建工具就可以派上用场了,我们通过自动化构建的方式将这些不被支持的代码特性转换成能够直接运行的代码。

这样我们就可以尽情在我们开发过程当中通过这些方式去提高我们编码效率了。

自动化构建初体验

接下来我们通过一个小案例来体会一下自动化工具的便捷之处,在这个案例中我们一开始使用的是直接使用css的方式去编写网站的样式。但是我们通过saas去增强css的编程性。

具体的实现方式呢就是在开发时我们添加一个构建的环节,这样让我们在开发环节就可以通过sass编写样式再通过工具将sass去构建为css。

我们看下如何操作,我们新建一个scss文件,在这个文件中我们可以按照sass的语法去编写我们的网页样式,相对于css,sass的编程能力肯定要更强一些。

$body-bg: #f8f9fb;
$body-color: #333;

body {
    margin: 0 auto;
    padding: 20px;
    background-color: $body-bg;
    color: $body-color;
}

但是呢sass并不能在我们的浏览器环境中直接去使用,所以我们需要在开发阶段通过一个工具去把他转换成css。

这里我们要使用的就是sass官方提供的一个sass模块,我们需要安装这个模块。

yarn add sass --dev

安装完成过后我们node_modules中会出现一个.bin的目录,这个目录下就会有一个sass的命令文件,我们执行这个命令会打印出一些帮助信息。在这个帮助信息的一开始就给出了这个命令的具体用法。

./node_modules/.bin/sass

具体的就是我们要指定一个sass的输入路径和css的输出路径,输入路径我们是main.scss, 输出路径是style.css。再次执行他就可以把我们的sass文件转换成css了。

./node_modules/.bin/sass main.scss style.css

不仅如此,他还帮我们添加了对应的source-map文件,这样的话我们在调试阶段就可以定位到我们代码中源代码的位置了。

但是这样也有一个比较麻烦的地方,那就是我们每次都要重复的去输出这些复杂的命令,而且在别人接收你的项目过后他也不知道如何去运行这些构件的任务。

所以说我们需要去做一些额外的事情,去解决这些在项目开发阶段重复去执行的命令。

npm scripts

那npm scripts主要就是用来解决这个问题的,你可以在npm的script当中去定义一些与这个项目开发过程有关的一些脚本命令,那这样一来呢你就可以让这些命令跟着项目一起去维护,便于我们在后期开发过程的使用。

所以我们这里最好的方式就是通过npm scripts方式去帮助包装你的构建命令。具体的实现方式就是在我们的package.json当中去添加一个scripts字段,这个字段是一个对象,键就是script的名称,值呢是我们需要去执行的命令。

这里需要注意的是script可以自动取发现node_modules里面的命令,所以我们不需要写完整的路径,直接使用命令的名称就可以了。

"script": {
    "build": "sass main.scss style.css"
}

完成过后我们就可以通过npm或者yarn去启动这个script,npm当中需要运行npm run build, yarn当中可以省略这个run,-> yarn build。

另外,npm scripts也是实现自动化构建最简单的方式,接着我们来看一下如何通过他来实现自动化构建。

我们这里安装一个browser-sync的模块,用于去启动一个测试服务器, 去运行我们的项目。

yarn add browser-sync --dev

然后我们在package.json的scripts当中添加一个serve的命令。在这个命令当中通过browser-sync把当前这个目录运行起来。

"script": {
    "build": "sass main.scss style.css",
    "serve": "browser-sync"
}

回到命令行运行一下npm run serve,此时会启动一个服务,并打开浏览器运行我们目录下的index.html文件。

但是如果说在browser-sync之前我们并没有去生成我们的样式,那此时browser-sync工作时我们的页面就没有样式文件,我们需要在启动serve命令之前去让build任务去工作,所以我们这里可以借助npm scripts的钩子机制去定义一个preserve,他会自动在serve命令执行之前去执行。

"script": {
    "build": "sass main.scss style.css",
    "preserve": "npm run build",
    "serve": "browser-sync"
}

这时我们再去执行npm run serve就会自动化的先去执行build命令, build完成过后再去执行对应的serve,那此时我们就可以完全在启动web服务之前自动去构建我们的sass文件。

光有这些还不够我们还可以为sass文件去添加一个--watch的参数,有了这个参数过后,sass在工作时就会监听文件的变化,一旦我们代码当中的sass文件发生改变,他就会自动被编译。

"script": {
    "build": "sass main.scss style.css --watch",
    "preserve": "npm run build",
    "serve": "browser-sync"
}

我们运行serve命令,你会发现sass文件在工作时命令行会阻塞,这样就导致了我们后面的browser-sync他并没有办法直接去工作,这种情况下我们就需要同时去执行多个任务,我们这里可以借助于npm-run-all的这个模块去实现, 我们需要先安装这个模块。

yarn add npm-run-all --dev

有了这个模块过后我们就可以在scripts当中再去添加一个新的命令,这个命令我们叫做start,在这个命令当中我们通过npm-run-all里面的run-p的命令同时去执行build和serve命令。

"script": {
    "build": "sass main.scss style.css --watch",
    "serve": "browser-sync",
    "start": "run-p build serve"
}

我们再运行npm run start的命令,那这个时候就会发现build命令和browser-sync命令同时被执行了。我们可以尝试修改main.scss文件当中的内容,这个时候你会发现css文件也会跟着一起变化,也就证明我们的watch已经生效了。

我们还可以给browser-sync这个命令去添加--files的参数,这个参数可以让browser-sync在启动过后监听项目下的一些文件的变化。一旦当文件发生变化过后,browser-sync会将这些文件的内容自动同步到浏览器,从而更新浏览器当中的界面,让我们可以及时查看到最新监听的效果。

那这样就避免了我们修改完代码过后再去手动刷新浏览器这样的一个重复的工作。

那这样我们就借助于npm scripts完成一个简单的自动化构建的一个工作流,那他具体的工作流程呢就是在启动任务过后,同时去运行了build和serve这两个命令,其中build去自动监听sass文件的变化去编译sass,browser-sync他启动一个web服务,当文件发生变化过后去刷新浏览器。

"script": {
    "build": "sass main.scss style.css --watch",
    "serve": "browser-sync --files \"*.css\"",
    "start": "run-p build serve"
}

常用的自动化构建工具

npm scripts确实能解决一部分的自动化构建任务,但是对于相对复杂的构建过程,npm scripts就显得有些吃力,这时我们就需要更为专业的构建工具。

这里我们先对市面上几个比较常见的构建工具去做一个大致的介绍。让大家先有一个整体的认识,后面我们再去做具体的深入探究。

那目前市面上开发者使用最多的一些开发工具主要就是gulp,grunt和fis,可能有人会问,webpack去哪了,严格来说webpack他实际上是一个模块打包工具所以不在我们这次的谈论范围之内。

那这些工具呢他都可以帮你解决那些重复而且无聊的工作从而实现自动化,用法上他们也都大体相同,都是先通过一些简单的代码去组织一些插件的使用,然后你就可以使用这些工具去帮你执行各种重复的工作了。

grunt他算是最早的前端构建系统了,他的插件生态非常的完善,用官方的一句话来说就是grunt他的插件几乎可以帮你自动化的完成任何你想要做的事情。

但是呢,由于他的工作过程是基于临时文件去实现的,所以说他的构建速度相对较慢,例如我们使用它去完成我们项目当中sass文件的构建,那我们一般会先对sass文件去做编译操作,再去自动添加一些私有属性的前缀,最后再去压缩代码。

那这样一个过程当中,grunt每一步都会有磁盘读写操作,比如像sass文件在编译完成过后他就会将结果写入到一个临时的文件,然后下一个插件他再去读取这个临时文件进行下一步。

那这样一来,处理的环节越多,文件读写的次数也就越多,那对于超大型项目当中,我们项目文件会非常多,你的构建速度就会特别的慢。

gulp是个人使用非常多的一个构建系统,他很好的解决了grunt当中构建速度非常慢的这样一个问题,因为他是基于内存去实现的,也就是说他对文件的处理环节都是在内存当中完成的。相对于磁盘读写速度自然就快了很多。

另外他默认支持同时去执行多个任务,效率自然大大提高,而且他的使用方式相对于grunt更加直观易懂,插件生态也同样非常完善,所以说他后来居上,更受欢迎,应该是目前市面上最流行的前端构建系统了。

fis是百度的前端团队推出的一款构建系统,最早只是在他们团队内部去使用,后来开源过后在国内快速流行,那相对于前面两个构建系统这种微内核的特点,fis更像是一种捆绑套餐。

他把我们项目当中一些典型的需求尽可能都集成在内部了,例如我们在fis内部就可以很轻松的去处理资源加载,模块化开发,代码部署,甚至是性能优化。

正是因为这种大而全,所以在国内很多项目中就流行开了,那总体来说如果你是初学者的话,可能fis更适合你,但是如果你的要求灵活多变的话,gulp和grunt应该是你更好的选择。

还是那句话,新手是需要规则的,而老手呢一般都会渴望自由,也正是因为这个原因,现在这些小而美的框架或者工具。