title: 前端构建工具对比
toc: true
date: 2018-10-17 19:41:31
categories:css
tags:前端
前端技术发展之快,各类能够提升开发效率的新思想和框架层出不穷。可是它们都有一个共同点:node
源代码没法直接运行,必须经过转换后才能够正常运行。webpack
构建就是作这件事情,将源代码转换成可执行的JavaScript、CSS、HTML代码,包括以下内容:web
代码转换:将TypeScript编译成JavaScript、将SCSS编译成CSS等。typescript
文件优化:压缩JavaScript、CSS、HTML代码,压缩合并图片等。npm
代码分割:提取多个页面的公共代码,提取首屏不须要执行部分的代码让其异步加载。json
模块合并:在采用模块化的项目里会有不少个模块和文件,须要经过构建功能将模块分类合并成一个文件。gulp
自动刷新:监听本地源代码的变化,自动从新构建、刷新浏览器。浏览器
代码校验:在代码被提交到仓库前须要校验代码是否符合规范,以及单元测试是否经过。
自动发布:更新代码后,自动构建出线上发布代码并传输给发布系统。
构建实际上是工程化、自动化思想在前端开发中的体现,将一系列流程用代码去实现,让代码自动化地执行这一系列复杂的流程。构建为前端开发注入了更大的活力,解放了咱们的生产力。
Npm是在安装Node. js时附带的包管理器,
Npm Script则是Npm内置的一个功能,容许在package.json文件里面使用scripts字段定义脚本命令:
{ // ... "scripts": { "build": "node build.js", "dev": "node dev.js", "pub": "node build.js" } }
优势:内置,无须安装其余依赖。
缺点:功能太简单,虽然提供了pre和post两个钩子,但不能方便地管理多个任务之间的依赖。
Grunt至关于进化版的Npm Script,它的诞生实际上是为了弥补Npm Script的不足。
Grunt有大量现成的插件封装了常见的任务,
也能管理任务之间的依赖关系,自动化地执行依赖的任务,
每一个任务的具体执行代码和依赖关系写在配置文件Gruntfile.js
里,
例如:
module.exports = function(grunt) { // 全部插件的配置信息 grunt.initConfig({ // uglify插件的配置信息 uglify: { app_task: { files: { 'build/app.min.js': ['lib/index.js', 'lib/test.js'] } } }, // watch插件的配置信息 watch: { another: { files: ['lib/*.js'], } } }); // 告诉Grunt咱们将使用这些插件 grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-watch'); // 告诉Grunt咱们在终端中启动Grunt时须要执行哪些任务 grunt.registerTask('dev', ['uglify','watch']); };
在项目根目录下执行命令grunt dev
,就会启动JavaScript文件压缩和自动刷新功能。
优势:
灵活,它只负责执行咱们定义的任务;
大量的可复用插件封装好了常见的构建任务。
缺点:
集成度不高,要写不少配置后才能够用,没法作到开箱即用。
Gulp 是一个基于流的自动化构建工具。
除了能够管理和执行任务,还支持监听文件、读写文件。
Gulp被设计得很是简单,
只经过下面5种方法就能够支持几乎全部构建场景:
Gulp的最大特色是引入了流的概念,
同时提供了一系列经常使用的插件去处理流,
流能够在插件之间传递,大体使用以下:
// 引入 Gulp var gulp = require('gulp'); // 引入插件 var jshint = require('gulp-jshint'); var sass = require('gulp-sass'); var concat = require('gulp-concat'); var uglify = require('gulp-uglify'); // 编译SCSS任务 gulp.task('sass', function() { // 读取文件,经过管道喂给插件 gulp.src('./scss/*.scss') // SCSS 插件将 scss 文件编译成 CSS 文件 .pipe(sass()) // 输出文件 .pipe(gulp.dest('./css')); }); // 合并压缩JavaScript文件 gulp.task('scripts', function() { gulp.src('./js/*.js') .pipe(concat('all.js')) .pipe(uglify()) .pipe(gulp.dest('./dist')); }); // 监听文件的变化 gulp.task('watch', function(){ // 当 scss 文件被编辑时执行 SCSS 任务 gulp.watch('./scss/*.scss', ['sass']); gulp.watch('./js/*.js', ['scripts']); });
优势:好用又不失灵活,既能够单独完成构建,也能够和其余工具搭配使用。
缺点:集成度不高,要写不少配置后才能够用,没法作到开箱即用。
能够将Gulp看做Grunt的增强版。
相对于Grunt,Gulp增长了监听文件、读写文件、流式处理的功能。
Fis3 是一个来自百度的优秀国产构建工具。
相对于Grunt、Gulp这些只提供了基本功能的工具,
Fis3集成了Web开发中的经常使用构建功能。
读写文件:经过fis.match读文件,release配置文件的输出路径。
资源定位:解析文件之间的依赖关系和文件位置。
文件指纹:在经过useHash配置输出文件时为文件URL加上md5戳,来优化浏览器的缓存。
文件编译:经过parser配置文件解析器作文件转换,例如将ES6编译成ES5。
压缩资源:经过optimizer配置代码压缩方法。
图片合并:经过spriter配置合并CSS里导入的图片到一个文件中,来减小HTTP请求数。
大体使用以下:
// 加md5 fis.match('*.{js,css,png}', { useHash: true }); // 经过fis3-parser-typescript插件可将TypeScript文件转换成JavaScript文件 fis.match('*.ts', { parser: fis.plugin('typescript') }); // 对CSS进行雪碧图合并 fis.match('*.css', { // 为匹配到的文件分配属性useSprite useSprite: true }); // 压缩JavaScript fis.match('*.js', { optimizer: fis.plugin('uglify-js') }); // 压缩CSS fis.match('*.css', { optimizer: fis.plugin('clean-css') }); // 压缩图片 fis.match('*.png', { optimizer: fis.plugin('png-compressor') });
优势:集成了各类Web开发所需的构建功能,配置简单、开箱即用。
缺点:目前官方已经再也不更新和维护,不支持最新版本的Node.js。
Fis3是一种专一于Web开发的完整解决方案,若是将Grunt、Gulp比做汽车的发动机,则能够将Fis3比做一辆完整的汽车。
Webpack 是一个打包模块化JavaScript的工具,
在Webpack里一切文件皆模块,
经过Loader
转换文件,
经过Plugin
注入钩子,
最后输出由多个模块组合成的文件。
Webpack专一于构建模块化项目。
一切文件,如JavaScript、CSS、SCSS、图片、模板,
对于Webpack来讲都是一个个模块,
这样的好处是能清晰地描述各个模块之间的依赖关系,以方便Webpack对模块进行组合和打包。
通过Webpack的处理,最终会输出浏览器能使用的静态资源。
Webpack具备很大的灵活性,能配置处理文件的方式,使用方法大体以下:
module.exports = { // 全部模块的入口,Webpack从入口开始递归解析出全部依赖的模块 entry: './app.js', output: { // 将入口所依赖的全部模块打包成一个文件bundle.js输出 filename: 'bundle.js' } }
优势:
缺点:
Rollup是一个和Webpack很相似但专一于ES6的模块打包工具。
它的亮点在于,能针对ES6源码进行Tree Shaking(摇树优化),以去除那些已被定义但没被使用的代码并进行Scope Hoisting(做用域提高),以减少输出文件的大小和提高运行性能。
然而Rollup的这些亮点随后就被Webpack模仿和实现。
因为Rollup的使用方法和Webpack差很少,因此这里就不详细介绍如何使用Rollup了。
它们的差异:
上面介绍的构建工具是按照它们诞生的时间排序的,
它们是时代的产物,侧面反映出Web开发的发展趋势,以下所述:
通过多年的发展,Webpack已经成为构建工具中的首选,这是有缘由的: