【webpack】wepack番外篇 -- Webpack会主宰我们吗?

Webpack会主宰我们吗?

前言

webpack刚出现时gulp如日中天,现在webpack更新到4.x版本,gulp逐渐淡出我们的视线,聊webpack的人越来越多,直到最近发现Vue官方文档里到处都是基于webpack的讲解,仿佛webpack已经成为了打包器的事实标准,前端这几年变化太大了,如果村子刚通网的话,你会发现你是不是脱轨了…

框架技术层出不穷,技术要求越来越硬,现在的前端攻城狮如果成为不了一个"使用工具型"的程序猿,或许下一份劝退书就到手了,但我也不是呼吁大家努力成为一个会使用工具框架的程序猿,毕竟这样可能真的提高不到架构师那个层面,更多大佬都是不仅仅要求基础扎实也会使用工具完成业务啥的,更重要的是如何让代码实现复用起来最优,维护起来更方便等等等等(个人见解,大家平时也可以多逛逛一些好的论坛,知乎掘金博客github等,你会发现上面找到的可能不仅仅只有技术,还有的是如何成为一个合格的程序猿…),扯远了回到正题吧~

webpack是啥?为什么要用?

简要定义webpack

WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用,里面还有很多有关如何提升代码使用率、代码分割、模块化工程化的思想值得我们去探讨,所以要去完全定义它,我们还需要不断去摸索出一个明确的答案~

模块化开发

一切还要从模块化说起,在距今仅仅几年之前的前端页面里,还会在底部发现一个jQuery+一个js文件的链接,随着这几年规范的进步、硬件、网络的发展、人们对体验的重视,各种因素导致前端脚本越写越多,代码越来越复杂,仿佛一夜之间那个玩具般的代码组织方式无法满足前端开发需求了,于是js模块化横空出世,以横扫之势迅速被前端社区接受,依托加载器实现的js模块化开发和加载,大大提升了前端开发体验,seajs便是在那个背景下杀出来的优秀加载器之一

模块打包

模块化开发固然好,但在加载上有点问题,因为前端性能优化向来很看重减少请求数量,模块化加载无疑是背道而驰,要解决这个问题,大家想到了将模块打包,开发时是分开的,发布前用打包器合到一起,这样页面的js请求数可以降到1,很好,从此打包器开始流行,webpack就是一个打包器,在webpack之前大家用的最多的是gulp,gulp是一个比打包器更底层的任务管理器,可以压缩代码,预编译代码,处理图片,当然也可以完成打包

webpack的反杀

既然gulp被webpack反杀了,一定是有不如人的地方,以gulp为代表的传统打包最大的问题是解决不了按需打包,就更别说按需加载了,因为传统的打包思路是 遍历源文件 => 匹配规则 => 打包/处理 ,也就是说只要被规则命中了,即便是程序用不到的模块也会被无脑打包,根本原因是按需这个事无法被规则描述,只能被程序逻辑描述。其实在webpack之前不是没有解决方案,百度fis最得意的地方就是解决了这个问题,并且是理论上堪称完美的解决方案,我感觉其最大的缺点是需要后端配合,然而你懂的,后端通常不鸟这种需求,百度fis也就不了了之了。

那webpack是怎么解决按需问题的呢?前面说了,按需只能被程序逻辑描述,webpack的打包思路就是从程序逻辑入手:入口文件 => 分析代码 => 找出依赖 => 打包,这样代码里不出现的模块就不可能被打进包里,甚至还可以实现按需加载,这就是webpack最有价值的地方。

打包过程中还有一个仅次于按需的需求,那就是分包,之所以说webpack或者说所有的打包器都特别适合SPA应用,是因为SPA只有一个入口,基本不需要分包或者分包需求很简单,但在网站类应用上,我们讨论的不是要不要分包,而是怎样最不浪费的分包,将加载总量降到最低。这个通常来说不是大问题,只要配合好文件目录结构的划分,多数分包需求都可以用规则描述,但在这方面webpack更进了一步,可以在业务代码中依托特定的语法标记出需要分包的模块,这就使分包的实现能在一定程度上自动化了,没毛病

需求上的webpack

业务场景

不谈场景的选型都是耍流氓。

假设有这样一个网站项目,兼容IE8,基于jQuery开发,脚本模块化,模块分成业务模块、插件模块、类库模块,类库模块以jQuery为主,业务模块即每个页面的业务代码,也是脚本入口,插件模块主要实现各种前端展示效果,为了更好的代码复用,已经将很多插件封装好并沉淀为一个插件库,可以覆盖项目里几乎所有的展示需求,这个库以一个文件夹的形式存在。

那么问题来了,这么多模块,请求数居高不下,怎么办。

无脑回答,打包啊。

打包分析

那我们就来看这个项目该怎么打包,重点放在插件模块上,首先会遇到传统打包的老大难按需问题,因为插件都在一个文件夹里,规则只能全部匹配,结果就是打出来一个大而无当的包。你说手动把不用的插件移除不行么,行。但实际情况是,展示类页面经常更新,可能今天用到插件1,明天就改用插件2,或者增加了一个页面要用插件3,你让开发者自己去统计到底用了哪个没用哪个吗,那是历史的倒退,不行。

别人解决不了webpack可以,这是webpack首当其冲的优势,按需,不是问题。

再往下看,网站上的所有展示效果都通过插件实现,最终整个项目用到的插件总数比较可观,也就是说即便按需了,这个插件包也不会小,而插件虽说相对固化,但毕竟是展示类插件,更新是免不了的,任意一个插件发生了增删改,整个插件包都要重打,客户端重新加载,代价有点大,不划算,并且我们知道,这个需求对于展示型网站来说,绝对是个真需求。

整体打包不行,那每个页面对应一个自己的插件包呢,各改各的,互不干扰,嗯,有点道理。

但是,实际情况要复杂的多,这也是展示型网站最烦人的地方,页面间还是有不少共用插件的,头部至少有个导航、下拉菜单、搜索框吧,底部来个选项卡不过分吧,幻灯片插件很多页面都有可以吗,这些公共插件每个页面打一份真的好吗。要是将公用插件单独拎出来呢,好啊,那不就又是人肉维护依赖关系了么,还是不好。

说一千道一万,关键在于打包需求不稳定,这种情况是打包中最难解决的,webpack也没有办法。但百度fis有!fis从一个更高的维度看问题,直接拿到了资源依赖表,千变万化的打包需求瞬间变得可控了,可惜,用户少,生态就小,生态小,就没戏了。

现在的局面,在不考虑fis的情况下,已经不是怎么打包的问题了,而是根本不适合打包。

解决方案:模块本地存储

那么问题又变成,无法打包的情况下如何减少模块化应用请求数。

不打包就得用加载器,加载器自身不可避免的要占一个请求,但加载器也为模块请求优化提供了可能,现在至少有两种可行的方案,一是配合服务端的请求合并,二是模块本地存储。服务端请求合并方案这里略去不谈。

本地存储方案在纯前端就可以实现,通过扩展加载器将请求到的模块代码缓存到localStorage,这样用户初次访问会全量请求,但之后的访问将只加载模块加载器、缓存模块目录、和业务模块三个文件,模块目录文件用于记录将要缓存的模块及其版本号,实现缓存更新,实际开发中可以跟加载器合并成一个文件,从而将脚本请求数降到2。

下面我们就要算一笔账了,虽然打包方案极难完美实现,但如果我们财大气粗,上CDN加速呢,虽然包经常更新,但有了CDN加载速度也能保证,理论上每个页面的脚本请求数可以降到1,但实际中总要提取第三方类库吧,请求数同样是2,好,那对比双方就是:

普通请求加载器 + 业务代码 VS CDN加持下的公共包 + 页面包:

下面讨论的前提是,CDN再快也有极限,一个CDN大包在一个小文件面前,不会有很大优势。下面看看双方的代码体积,加载器用的seajs,页面的业务代码百行左右,这种情况下的2个请求,我认为上CDN的钱可以省。在非首次加载情况下,我认为本地存储方案处于无敌水平。

本地存储方案最大的问题是首次加载,大批的插件请求怎么办。无法根除,但可以缓解。比如在前端开发时多考虑模块懒加载,尽量提升首屏展示速度,这是前端的看家本领。实在不行咱也可以给插件上CDN嘛,反正只有首次加载走流量,就算上了CDN都比其他方案省好多钱。

因此最终选定的方案是,seajs + 本地存储

webpack是银弹吗?

在兼容性方面,webpack一直是面向最新的标准,自身的很多特性需要依赖polyfill才能向下兼容,甚至有的特性最新的浏览器都还没有原生兼容,用起来难免有点折腾。

技术圈都是追新的,仿佛现在的前端都不好意思再聊jQuery技术栈了,即便说起来也都是jQuery已经过时了的论调,我只想说,浏览器市占率摆在那,展示类项目的需求摆在那,这些应用场景还确确实实的存在着,现实世界的任何一个2C产品可能都有一个高到让你不屑的兼容性要求。

最后webpack的侵入性较强,这是我个人最介意的一点,某些高级特性需要依赖独特的语法才能实现,也就是说需要在一定程度上面向webpack编程,一旦离开了webpack,你的源码无法运行。

唯一不变的是变化。

模块加载在未来大概率会被浏览器原生支持,到那时会不会有新的优化方案?

打包这件事,怎么看都像一个补丁,未来的HTTP2会不会彻底使其成为伪需求?

IE8迟早淘汰,Vue/React的市场会无限增大吗,SEO怎么做,Nodejs服务端渲染是答案吗?

结语忠告

时代在变,前端不断成为不可或缺的一门职业,我想以后的大学课程会不会将前端列入计算机学习的内容也不得而知,但无论怎样,现在发展的任何框架任何技术,终究离不开的是基础,基础打好剩下的就是自己在技术以及思想上的不断升华自己,当你成为你公司或者生活中不可替代的人的时候,那才是需要感谢自己的时候,加油吧骚年~

让人迷茫的原因只有一个,那就是本该拼搏的年纪,却想的太多做的太少
·············································································································—— 鲁迅

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值