Webpack vs Gulp
Webpack vs Gulp 谁会被拍死在沙滩上
文章有点长,总共 1800 字,阅读需要 18 分钟。哈哈,没耐心的直接戳我到高潮部分。
理想的前端开发流程
在说构建工具之前得先说说咱期望的前端开发流程是怎样的?
- 写业务逻辑代码(例如 es6,scss,pug 等)
- 处理成浏览器认识的(js,css,html)
- 浏览器自动刷新看到效果
前端开发就是在不断的 123..123..123.... 循环中进行的,上面的后两步(也就是 2 和 3)应该是自动化的,前端开发者理应只需关注第 1 步——写业务逻辑代码。
自动化的事情应该交由构建工具来做,时下流行的前端构建工具有 gulp 和 webpack(有人说 webpack 不算是构建工具,我觉得这没什么好争的。横看成岭侧成峰,我觉得从当前 webpack 所能做的事情来看,说它是构建工具丝毫不为过)。本文不会对 gulp 和 webpack 的概念和内容做深入解析,而是希望从宏观的角度研究他们的优势短缺和适用场景,从而说清长期弥漫在前端圈二者之间扑朔迷离的关系。
Gulp 为何物
先来听听 Ta 的官网是怎么说:
想一想咱们日常的开发工作中痛苦又耗时任务有哪些呢?
- 用 es6,typescript 编写的脚本文件需要编译成浏览器认识的 javascript
- 用 scss,less 编写的样式文件需要编译成浏览器认识的 css
- 检查代码是否符合书写规范,跑单元测试和集成测试
- 开发环境如果有 sourcemaps 的话调试起来就方便多了,修改完代码浏览器能自动刷新立即看到效果就更好了
- 生产环境部署代码需要压缩合并静态文件,添加文件指纹控制缓存
- blabla...更多的你自己想吧
Gulp 声称要帮咱们实现自动化,那他是怎样帮助咱们实现自动化的呢?这就不得不先提一嘴牛逼哄哄的 NodeJS。
扯谈完毕,接下来就来看看 gulp 是不是在装逼,他到底能不能帮我们实现自动化。
作为一个 node 包,标准打开方式当然是:
npm i -g gulp
然后呢,这里以编译 less 为例,首先安装编译 less 需要用到的 node 包:
npm i --save-dev gulp gulp-less
接着在项目的根目录下新建一个 gulpfile.js 文件,这是 gulp 的默认配置文件。
现在工程目录结构已经成了下面的样子:
接下来就是在 gulpfile.js 里编写 gulp task(gulp 把为每个痛苦又耗时任务编写的处理方法称为一个 task):
const gulp = require('gulp');
const less = require('gulp-less');
gulp.task('build:less', function(){
return gulp.src('./src/*.less')
.pipe(less())
.pipe(gulp.dest('./dist'));
});
最后就是打开一个终端,在终端里运行 gulp build:less。好了,编译后的文件已经被输出到了 dist 目录:
至此你已经算是一个 gulp 砖家了,这基本上就是 gulp 的全部内容。怎么样,是不是够简单,够丝滑。这也是 gulp 的突出特点——易于学习,易于使用,五分钟成砖家。如果想要执行解决其他痛苦又耗时的任务,只需下载安装对应的 gulp 插件包,然后依次类推写一个 gulp.task 出来就行了。
webpack 又是从哪冒出来的
gulp 似乎是完美的,对前端开发工作中每一项痛苦又耗时任务都能见招拆招,各个击破。然而前端发展速度之快超乎想象,对页面性能和用户体验更是追求极致,以至于 gulp 某些领域尤其大型 SPA(单页应用)显得有些不够用了:
- 单页应用的核心是模块化,ES6 之前 JavaScript 语言本身一直是没有模块系统的,导致 AMD,CMD,UMD 各种轮子模块化方案都蹦出来。对这种模块化乱象,gulp 显得无能为力,gulp 插件对这一块也没有什么想法。不过也可以理解,模块化解决方案可不是谁都能 hold 住的,需要考虑的问题太多了;
- 对前沿的 SPA 技术 gulp 处理起来显得有些力不从心,例如 Vue 的单文件组件,gulp 配合一些插件可以勉强处理,但是很蹩脚。其实归根结底,还是模块化处理方面的不足;
- 优化页面加载速度的一条重要法则就是减少 http 请求。gulp 只是对静态资源做流式处理,处理之后并未做有效的优化整合,也就是说 gulp 忽略了系统层面的处理,这一块还有很大的优化空间,尤其是移动端,那才真的是一寸光阴一寸金啊,哪怕是几百毫秒的优化所带来的收益(用户?流量?付费?)绝对超乎你的想象。别跟我说 gulp-concat,CSS Sprites,这俩玩意儿小打小闹还行,遇上大型应用根本拿不上台面。现在的页面动辄上百个零碎资源(图片,样式表,脚本),也就是上百个 http 请求,因此这个优化需求还是相当迫切的。关于为何减少 http 请求可以有效降低页面加载时间戳这里。
- blabla... 你自己想吧,主要就是大型单页应用方面有短板;
时势造英雄。webpack 一声吼,大张旗鼓地挖起了gulp 的墙角。
老规矩,先看看webpack官网怎么吹牛逼介绍自己的:
是不是看完一脸懵逼,不明觉厉。其实翻译过来就是 “在我眼里,什么都是模块”。webpack “万物皆模块” 的理念和 SPA 配合起来简直是金童玉女,天作之合。这也是 webpack 短时间内名声大噪,直接撼动 gulp 地位的主要原因。
webpack 的理念比较前卫,它本身也带来了很多新的概念和内容,诸如加载器(loader)、依赖图(Dependency Graph)等等。和 gulp 两小时成砖家的学习难度相比,webpack 或许你研究两天仍然会晕头转向。
接下来简单看一下 webpack 的主要工作方式。
webpack 和 gulp 一样也是一个小 node 包,打开方式自然是:
npm i -g webpack
npm i --save-dev webpack
和 gulp 一样,全局安装是为了执行 webpack 任务,本地安装是为了使用 webpack 提供的 api。
安装完 webpack 之后在项目根目录下新建一个 webpack.config.js,这是 webpack 的默认配置文件,同 gulp 的 gulpfile.js 的功能类似。webpack.config.js 同样是不区分大小写的,取成 webPACk.CONfig.js 的话 webpack 也能认识,但是取成其他名字或放在别的目录就需要使用 --config 选项去指定配置文件了。
现在工程目录结构如下:
接下来就是在 webpack.config.js 里配置需要的选项,注意了,webpack 与 gulp 的重要不同就是使用方式由编程式变成了配置式:
const path = require('path');
module.exports = {
entry: './src/index.js', // 告诉 webpack 你要编译哪个文件
output: { // 告诉 webpack 你要把编译后生成的文件放在哪
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
}
};
最后仍然和 gulp 类似,就是在终端里运行 webpack(终端里一般会出现一大坨编译信息)。好了,现在 webpack 已经把编译好的文件输出到了 dist 目录:
看到这是不是已经一头雾水了,在你还没明白发生了什么的时候 webpack 已经把事情干完了。这也是 webpack 和 gulp 作业方式的重要不同:Gulp 是搭了个台子,让 gulp 插件在上面唱戏,尽情表演,所有构建相关的具体事情都交由 gulp 插件去做。而 Webpack 就牛逼了,webpack 先搭了个台子,然后自己在上面唱嗨了,仔细一听,他在上面唱的是《我们不一样》,当然了他也是让 webpack 插件在上面唱戏的。
也就是说 webpack 把很多功能都封装进了自己身体里面,使得自己强大同时臃肿。现在你可以在 ./src/index.js
文件里直接写 ES6 代码,因为 webpack 把编译 ES6 的工作已经封装到自己的实现里了,使得 webpack 看起来原生支持 ES6 而不需要借助第三方插件,其实他内部也是用了第三方插件的,所以你不用再专门去下一个 babel 之类的插件去转译 ES6。这样封装的好处是使用起来很方便,不好的地方就是使用者完全不知道发生了什么,构建完了还一脸懵逼。
上面仅是 webpack 使用的最最最简单示例,简直连 “hello world” 都算不上。具体怎样打包各种资源(typescript,样式表,图片,字体等等)可前往 webpack官网 深入学习,想看中文的同学使劲 戳这里。
webpack “一切皆模块” 的特点完美解决了上面 gulp 暴露的几个短板,连 webpack 官网也说自己是因为看到现存的模块打包器都不太适合大型 SPA 应用,于是决定打造一个适合大型 SPA 应用的模块打包器,也就是说 webpack 其实就是为大型 SPA 而生的。
结论
我看好多人说 gulp 和 webpack 不是一类东西,我不这么觉得,虽然说两者的出发点确实是不一样的,gulp 走的是流式处理路线,webpack 走的是模块处理路线,但是两者所要达成的目标却是一样的,那就是促进前端领域的自动化和工程化管理。webpack 发展到现在,已经非常强大了,强大到在构建方面 gulp 能做的事 webpack 基本上都可以胜任,gulp 做不了的 webpack 也能搞。同样的那些开发工作中痛苦又耗时的任务,gulp 和 webpack 都能解决,只是解决思路有天壤之别。
下表是从各个角度对 gulp 和 webpack 做的对比:
Gulp | Webpack | |
定位 | 基于流的自动化构建工具 | 一个万能模块打包器 |
目标 | 自动化和优化开发工作流,为通用 website 开发而生 | 通用模块打包加载器,为移动端大型 SPA 应用而生 |
学习难度 | 易于学习,易于使用,api总共只有5个方法 | 有大量新的概念和api,不过好在有详尽的官方文档 |
适用场景 | 基于流的作业方式适合多页面应用开发 | 一切皆模块的特点适合单页面应用开发 |
作业方式 | 对输入(gulp.src)的 js,ts,scss,less 等源文件依次执行打包(bundle)、编译(compile)、压缩、重命名等处理后输出(gulp.dest)到指定目录中去,为了构建而打包 | 对入口文件(entry)递归解析生成依赖关系图,然后将所有依赖打包在一起,在打包之前会将所有依赖转译成可打包的 js 模块,为了打包而构建 |
使用方式 | 常规 js 开发,编写一系列构建任务(task)。 | 编辑各种 JSON 配置项 |
优点 | 适合多页面开发,易于学习,易于使用,接口优雅。 | 可以打包一切资源,适配各种模块系统 |
缺点 | 在单页面应用方面输出乏力,而且对流行的单页技术有些难以处理(比如 Vue 单文件组件,使用 gulp 处理就会很困难,而 webpack 一个 loader 就能轻松搞定) | 不适合多页应用开发,灵活度高但同时配置很繁琐复杂。“打包一切” 这个优点对于 HTTP/1.1 尤其重要,因为所有资源打包在一起能明显减少浏览器访问页面时的资源请求数量,从而减少应用程序必须等待的时间。但这个优点可能会随着 HTTP/2 的流行而变得不那么突出,因为 HTTP/2 的多路复用可以有效解决客户端并行请求时的瓶颈问题。 |
结论 | 浏览器多页应用(MPA)首选方案 | 浏览器单页应用(SPA)首选方案 |
Webpack vs Gulp的更多相关文章
- 【原】webpack结合gulp打包
在我前面的文章中,总结了一下自己学习webpack和gulp的一些东西.然而,在我的实际项目中,单独使用它们两者不能满足项目的需求.我遇到了下面的一些问题. 问题1: 因为我的图片需要放单cdn上面去 ...
- webpack与gulp的区别及实例搭建
webpack是什么,提到这个概念,很多人可能立马说出来,模块化加载器兼打包工具,可以把各种资源都作为模块来使用和处理等等. 说到前端构建工具,不可避免的会提到gulp,到底webpack和gulp有 ...
- 前端构建工具之争——Webpack vs Gulp 谁会被拍死在沙滩上
.table tr>td:nth-child(1){width: 2em !important;padding-left: .6rem !important;padding-right: .6r ...
- Webpack vs Gulp(转载)
理想的前端开发流程 在说构建工具之前得先说说咱期望的前端开发流程是怎样的? 写业务逻辑代码(例如 es6,scss,pug 等) 处理成浏览器认识的(js,css,html) 浏览器自动刷新看到效果 ...
- Webpack与Gulp、Grunt区别
Webpack与Gulp.Grunt没有什么可比性,它可以看作模块打包机,通过分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等 ...
- Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G
code&monkey Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...
- Webpack和Gulp对比
Webpack和Gulp对比 作者 彬_仔 关注 2016.10.19 22:42* 字数 8012 阅读 2471评论 18喜欢 68 在现在的前端开发中,前后端分离.模块化开发.版本控制.文件合并 ...
- 解决webpack和gulp打包js时ES6转译ES5时Object.assign()方法没转译成功的问题
在webpack或gulp打包的配置文件中package.json 引入"@babel/plugin-transform-object-assign": "^7.2.0& ...
- webpack和gulp的区别
Gulp应该和Grunt比较,他们的区别我就不说了,说说用处吧.Gulp / Grunt 是一种工具,能够优化前端工作流程.比如自动刷新页面.combo.压缩css.js.编译less等等.简单来说, ...
随机推荐
- How do you add? UVA - 10943(组合数的隔板法!!)
题意: 把K个不超过N的非负整数加起来,使它们的和为N,有多少种方法? 隔板法...不会的可以买一本高中数学知识清单...给高中班主任打个广告.... 隔板法分两种...一种是不存在空集 = C(n- ...
- 【题解】 [HNOI2004]宠物收养场(Splay)
懒得复制,戳我戳我 Solution: \(Splay\)板子,注意交换的地方,然后就是注意不要越界node[x],应该是\(node[now]\),其次就是数组可以开大点 Code: //It is ...
- Crash dump进程信息
linux下 比较简单,这里不在说明, windows下 相对复杂一点,用SetUnhandledExceptionFilter 来捕获 MiniDumpWriteDump 来写dmp文件,这种方法还 ...
- CRM 常用SQL 脚本
1. 查询角色.用户 SELECT DISTINCT DomainName, u.FullName , u.FirstName, u.InternalEM ...
- 解题:HEOI 2012 朋友圈
题面 因为$A$中只有奇偶性不同的人才能做朋友,所以A中只可能出0/1/2个人,分类讨论 然后$B$中求最大团,转成补图后正好是个二分图(不然就不用做了),求最大点独立集=总点数-最大匹配 我洛谷上交 ...
- js判断是否为空
http://dushanggaolou.iteye.com/blog/1293803 1.<input type="hidden" id="key" n ...
- Java基础-反射(reflect)技术详解
Java基础-反射(reflect)技术详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.类加载器 1>.JVM 类加载机制 如下图所示,JVM类加载机制分为五个部分 ...
- Hive SQL 编译过程
转自:http://www.open-open.com/lib/view/open1400644430159.html Hive跟Impala貌似都是公司或者研究所常用的系统,前者更稳定点,实现方式是 ...
- 基于JWT(Json Web Token)的ASP.NET Web API授权方式
token应用流程 初次登录:用户初次登录,输入用户名密码 密码验证:服务器从数据库取出用户名和密码进行验证 生成JWT:服务器端验证通过,根据从数据库返回的信息,以及预设规则,生成JWT 返还JWT ...
- [整理]win7下VS2010遇到内存不足解决方发
电脑重装Win7 64bit不久后,一天内VS2010使用久了,就会出现内存不足,实际内存使用情况却不是,显示内存已使用70%.以前没有遇到过,经网上查找,貌似是VS2010对内存计算会在某些情况下计 ...