前言:Webpack 与 gulp 是目前圈子内比较活跃的前端构建工具。网上有很多二者比较的文章,面试中也会经常遇到 gulp,Webpack 的区别这样的问题。对于初学者来说,对这二者往往容易认识不清,今天,就从事件的源头,说清楚 Webpack 与 gulp。
Gulp
那是 2014 年,虽然 JQuery 风光多年,但是前端却暗流涌动;MVVM 刚刚提出不久,Angular 快速成长,而 React 和 Vue 也刚刚开源不到一年,尚属于冷门小语种。那个时候,前端工作者面临的主要矛盾在于日益增长的业务复杂化的需求同落后低效率的前端部署。开发工作者为了发布一个网站,往往会重复的进行一些与开发无关的工作,手动完成这些工作会带来很大的挫败感。这个时候,自动化构建工具及应运而生,gulp 就是在大浪淘沙中的胜利者。
Gulp 是基于流的前端构建工具,nodejs 的 stream 操作来读取和操作数据;可以实现文件的转换,压缩,合并,监听,自动部署等功能。gulp 拥有强大的插件库,基本上满足开发需求,而且开发人员也可以根据自己的需求开发自定义插件。难得是,gulp 只有五个 api,容易上手。
const gulp = require(‘gulp’);
const sass = require(“gulp-sass”)
gulp.task(“sassStyle”,function() {
gulp.src(“style/*.scss”)
.pipe(sass())
.pipe(gulp.dest(“style”))
})
上面就是一个基本的 gulpfile 配置文件,实现了 scss 文件到 css 文件的转换;在终端输入 gulp sassStyle 就能够进行文件处理了。对于 gulp 而言,会有一个 task,这个 task 只会做一件事,比如将 sass 格式的文档转换成 css 文件;对于一个 task 而言,会有一个入口文件,即 gulp.src,最会有一个目标文件,即 gulp.dest;一入一出,可以将 gulp 理解为 一元函数,输入一个 x,根据 funcion 产出一个 y。
Gulp 简单,快速,自动化的构建方案,收获了很多开发者的喜爱。但是怎样的机遇,让 webpack 占据了前端工程化的半壁江山呢?
Webpack
解决方案永远是紧跟需求的脚步的。随着 React 与 Vue 份额越来越大,spa 开发模式应用在越来越多的领域中,而 ES6 Module 语法的提出与大规模应用,模块化开发方式越来越受人们的青睐。致使前端文件之间的依赖性越来越高,这时候就需要一个工具能够解析这些依赖,并且将它们有条理的打包起来,优化请求,最好顺便能够解析成浏览器可以识别的语言——这正是 webpack 所承担的工作; 而很多开发者,也是从 react 或者 vue 的项目入手 webpack 的。
图片来源于互联网,侵删
Webpack 是前端资源模块化 管理和打包工具。它可以将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源。还可以将按需加载的模块进行代码分割,等到实际需要的时候再异步加载——来自 Webpack 官方网站。所以 Webpack 只完成两件事:按需加载,打包。
module.exports = {
// 入口文件,是模块构建的起点,同时每一个入口文件对应最后生成的一个 chunk。
entry: {
bundle: [
‘webpack/hot/dev-server’,
‘webpack-dev-server/client?http://localhost:8080’,
path.resolve(__dirname, ‘app/app.js’)
]
},
// 文件路径指向 (可加快打包过程)。
resolve: {
alias: {
‘react’: pathToReact
}
},
// 生成文件,是模块构建的终点,包括输出文件与输出路径。
output: {
path: path.resolve(__dirname, ‘build’),
filename: ‘[name].js’
},
// 这里配置了处理各模块的 loader,包括 css 预处理 loader,es6 编译 loader,图片处理 loader。
module: {
loaders: [
{
test: /\.js$/,
loader: ‘babel’,
query: {
presets: [‘es2015’, ‘react’]
}
}
],
noParse: [pathToReact]
},
// webpack 各插件对象,在 webpack 的事件流中执行对应的方法。
plugins: [
new webpack.HotModuleReplacementPlugin()
]
};
上面是比较简单的 webpack 配置文件 webpack.config.js, 如果说 gulp 是一个一元函数,那么,webpack 就是一个多元函数或者是加工厂;webpack 从入口文件开始,递归找出所有依赖的代码块,再将代码块按照 loader 解析成新内容,而在 webpack 会在各个特定的时期广播对应事件,插件会监听这些事件,在某个事件中进行特定的操作。通俗一点来说,webpack 本身来递归找到各个文件之间的依赖关系,在这个过程中,使用 loaders 对文件进行解析,最后,在各个不同的事件阶段,插件可以对文件进行一个统一的处理。
webpack.config 文件会包括以下几部分:
1.entry: 入口,webpack 问此文件入手迭代。2.output: 打包后形成的文件出口。3.module: 模块,在 webpack 中一个模块对应一个文件。webpack 会从 entry 开始,递归找出所有依赖的模块 4.loaders: 文件解析的各种转换器 5.plugin: 拓展插件
webpack 的配置文件和构建方式比较复杂,这里不再赘述,感兴趣的同学可以参考我列出来的参考文献第三篇文章,或者可以关注我的专栏,后期我会出一篇关于 webpack 的学习笔记。
比较
所以,我们可以看出来,虽然 Webpack 与 gulp 都是前端工程化的管理工具,但是二者的侧重点不同——gulp 更加关注的是自动化的构建工具,你把代码写好了,gulp 会帮你编译、压缩、解析。而 Webpack 关注的是在模块化背景下的打包工作;它侧重的还是如何将依赖的文件合理的组织起来,并且实现按需加载。
总结
总的来说,虽然 webpack 以打包起家,但是 gulp 能够实现的功能,Webpack 也能做;那么,是不是我们以后都要唯 webpack 马首是瞻呢?非也,非也!webpack 功能强大,但是它的缺点也来自于此;webpack 并非一个轻量级的工具,学习曲线也非 gulp 那般平缓。曾经,gulp 为了弥补 js 打包方面的不足,也有 gulp-webpack 插件的出现;但是 webpack 强大如斯,如果仅仅只是解析 es6 文件,未免有大马拉小车之感。根据我的项目实践经验,如果你要构建一个复杂的项目,项目使用 vue 或者 react,模块化引领,那么请选择 Webpack,Webpack 天生模块化,更加适合于 SPA 的应用场景,而 gulp 在 SPA 下明显后力不足。如果你只是开发一个工具,请选择 gulp,至于 js 打包这种工作,有更加专一的 rollup。毕竟,如果只是写一个年会抽奖工具活跃气氛,就不需要 webpack 火种送碳了。
总结下来:gulp 与 Webapck 是各有所长,并不存在东风压倒西风,而在前端工程化的大旗下,并非只有 Webpack 与 gulp,我们还能看到 rollup 与 browserify 的一席之地。因此,在真正的工作中,还是要结合项目本身特点,切忌人云亦云。
参考文献
1、JavaScript 开发者的工具箱 非常实用 2、Gulp 官网 3、超级详细的 Webpack 解读—五星推荐 4、端构建工具之争——Webpack vs Gulp 谁会被拍死在沙滩上—五星推荐