[ 更换 ]
热门城市
北京上海广州深圳成都杭州南京武汉天津西安重庆青岛沈阳长沙大连厦门无锡福州济南宁波昆明苏州郑州长春合肥南昌哈尔滨常州烟台南宁温州石家庄太原珠海南通扬州贵阳东莞徐州大庆佛山威海洛阳淮安呼和浩特镇江潍坊桂林中山临沂咸阳包头嘉兴惠州泉州三亚赣州九江金华泰安榆林许昌新乡舟山慈溪南阳聊城海口东营淄博漳州保定沧州丹东宜兴绍兴唐山湖州揭阳江阴营口衡阳郴州鄂尔多斯泰州义乌汕头宜昌大同鞍山湘潭盐城马鞍山襄樊长治日照常熟安庆吉林乌鲁木齐兰州秦皇岛肇庆西宁介休滨州台州廊坊邢台株洲德阳绵阳双流平顶山龙岩银川芜湖晋江连云港张家港锦州岳阳长沙县济宁邯郸江门齐齐哈尔昆山柳州绍兴县运城齐河衢州太仓张家口湛江眉山常德盘锦枣庄资阳宜宾赤峰余姚清远蚌埠宁德德州宝鸡牡丹江阜阳莆田诸暨黄石吉安延安拉萨海宁通辽黄山长乐安阳增城桐乡上虞辽阳遵义韶关泸州南平滁州温岭南充景德镇抚顺乌海荆门阳江曲靖邵阳宿迁荆州焦作丹阳丽水延吉茂名梅州渭南葫芦岛娄底滕州上饶富阳内江三明淮南孝感溧阳乐山临汾攀枝花阳泉长葛汉中四平六盘水安顺新余晋城自贡三门峡本溪防城港铁岭随州广安广元天水遂宁萍乡西双版纳绥化鹤壁湘西松原阜新酒泉张家界黔西南保山昭通河池来宾玉溪梧州鹰潭钦州云浮佳木斯克拉玛依呼伦贝尔贺州通化朝阳百色毕节贵港丽江安康德宏朔州伊犁文山楚雄嘉峪关凉山雅安西藏四川广东河北山西辽宁黑龙江江苏浙江安徽福建江西山东河南湖北湖南海南贵州云南陕西甘肃青海台湾内蒙古广西宁夏香港澳门
培训资讯网 - 为兴趣爱好者提供专业的职业培训资讯知识

「前端」腾讯前端工程师总结的 webpack基础、分包大揭秘

基础 工程

若你对webpack仅仅是处于使用阶段,觉得webpack原理太杂太乱太多,但是觉得大概了解下webpack的大致原理也不错。亦或是想要了解分包优化如何进行配置呢?以及为什么webpack官方分包配置会从 CommmonsChunkPlugin演变成SplitChunksPlugin呢?我按照自己的方式,通过查阅、整理相关文档,梳理一些比较容易让大家纠结的点,让大家通过本篇文章,大概了解webpack是干了什么?

一、webpack前生今世

1.1、前端石器时代----->工业化时代

「前端」腾讯前端工程师总结的 webpack基础、分包大揭秘

前端变迁转折点

  • 2008年9月2号,当Chrome第一次出现的时候(V8与Chrome同一天宣布开源),它对网页的加载速度让所有人惊叹,是V8引擎把JavaScript的运行速度提上来了,让前端从蒸汽机机时代正式步入内燃机时代。
  • 2009年诞生的Node.js和2010年诞生的npm,迅速将JavaScript变成全球最受欢迎的生态系统之一。前端正式从石器时代进入到了工业化时代。

1.2、前端为什么需要模块化

痛点

  • 变量和方法不容易维护,容易污染全局作用域。
  • 加载资源的方式通过script标签从上到下。
  • 依赖的环境主观逻辑偏重,代码较多就会比较复杂。
  • 大型项目资源难以维护,特别是多人合作的情况下,资源的引入会让人崩溃。

作用

模块化的开发方式可以提高代码复用率,方便进行代码的管理。通常来说,一个文件就是一个模块,有自己的作用域,只向外暴露特定的变量和函数。有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块。

模块规范

但是,这样做有一个前提,那就是大家必须以同样的方式编写模块,否则你有你的写法,我有我的写法,岂不是乱了套!考虑到Javascript模块现在还没有官方规范,这一点就更重要了。目前流行的js模块化规范有CommonJS、AMD、CMD以及ES6的模块系统。

(1)CommonJS

NodeJS诞生之后,它使用CommonJS的模块化规范。从此,js模块化开始快速发展。它有四个重要的环境变量为模块化的实现提供支持:module、exports、require、global。

(2)AMD

CommonJS对服务器端不是一个问题,因为所有的模块都存放在本地硬盘,可以同步加载完成,等待时间就是硬盘的读取时间。但是,对于浏览器,这却是一个大问题,因为模块都放在服务器端,等待时间取决于网速的快慢,可能要等很长时间,浏览器处于“假死”状态。因此,浏览器端的模块,不能采用“同步加载”(synchronous),只能采用“异步加载”(asynchronous)。这就是AMD规范诞生的背景。

AMD是“Asynchronous Module Definition”的缩写,意思就是“异步模块定义”。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。主要有两个Javascript库实现了AMD规范:require.js和curl.js。

(3)CMD

CMD是另一种js模块化方案,它与AMD很类似,不同点在于:AMD推崇依赖前置、提前执行,CMD推崇依赖就近、延迟执行。此规范其实是在sea.js推广过程中产生的。

(4)ES6

在语言标准的层面上,实现了模块功能,而且实现得相当简单,旨在成为浏览器和服务器通用的模块解决方案。其模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。

模块化总结

「前端」腾讯前端工程师总结的 webpack基础、分包大揭秘

1.3、为什么需要webpack呢?

前端页面效果越来越酷炫、功能越来越复杂。而前端工程师们为了更方便的开发提高开发效率进行了一系列der探索,模块化思想的提出啊,将复杂的程序分割成更小的文件。这些年优秀的框架层出不穷react、vue、angular、es6这种在javascript基础上拓展的新的语法规范和less、sass、css处理器等等等。所有的事物都是具有双面性的、有利有弊。大大提高开发效率的同时,又为后期维护造成了困扰。因为利用这些工具的文件往往不能直接被浏览器识别,需要手动处理,很影响开发进度。

是否可以有一种方式,不仅可以让我们编写模块,而且还支持任何模块格式(至少在我们到达ESM之前),并且可以同时处理资源和资产?所以webpack应运而生~这就是webpack存在的原因。它是一个工具,可以打包你的JavaScript应用程序(支持ESM和CommonJS),可以扩展为支持许多不同的静态资源,例如:images, fonts和stylesheets。

webpack关心性能和加载时间;它始终在改进或添加新功能,例如:异步地加载chunk和预取,以便为你的项目和用户提供最佳体验。

二、webpack概念

「前端」腾讯前端工程师总结的 webpack基础、分包大揭秘

webpack是一个用于现代JavaScript应用程序的静态模块打包工具。当 webpack处理应用程序时,它会在内部从一个或多个入口点构建一个依赖图(dependency graph),然后将你项目中所需的每一个模块组合成一个或多个bundles,它们均为静态资源,用于展示你的内容。

三、webpack核心流程解析

「前端」腾讯前端工程师总结的 webpack基础、分包大揭秘

总体流程架构图

上述提及的各类技术名词不太熟悉的同学,可以先看看简介:

  • Entry:编译入口,webpack编译的起点。
  • Compiler:编译管理器,webpack启动后会创建compiler对象,该对象一直存活直到结束退出。
  • Compilation:单次编辑过程的管理器,比如watch=true时,运行过程中只有一个compiler但每次文件变更触发重新编译时,都会创建一个新的 compilation对象。
  • Dependence:依赖对象,webpack基于该类型记录模块间依赖关系。
  • Module:webpack内部所有资源都会以“module”对象形式存在,所有关于资源的操作、转译、合并都是以“module”为基本单位进行的。
  • Chunk:编译完成准备输出时,webpack会将module按特定的规则组织成一个一个的chunk,这些chunk某种程度上跟最终输出一一对应。
  • Loader:资源内容转换器,其实就是实现从内容A转换B的转换器。
  • Plugin:webpack构建过程中,会在特定的时机广播对应的事件,插件监听这些事件,在特定时间点介入编译过程。

扩展

Compiler是plugin的apply接口传进来的参数,它代表了完整的 webpack环境配置。这个对象在启动webpack时被一次性建立,并配置好所有可操作的设置,包括options,loader和plugin。当在webpack环境中应用一个插件时,插件将收到此compiler对象的引用,可以使用它来访问webpack的主环境。对于plugin而言,通过它来注册事件钩子。

Compilation对象代表了一次资源版本构建。当运行webpack开发环境中间件时,每当检测到一个文件变化,就会创建一个新的compilation,从而生成一组新的编译资源。一个compilation对象表现了当前的模块资源、编译生成资源、变化的文件、以及被跟踪依赖的状态信息。对于plugin而言,通过它来完成数据的处理。

3.1、初始化阶段

「前端」腾讯前端工程师总结的 webpack基础、分包大揭秘

  • 初始化参数:从配置文件、 配置对象、Shell参数中读取,与默认配置结合得出最终的参数。
  • 创建编译器对象:用上一步得到的参数。
  • 创建Compiler对象初始化编译环境:包括注入内置插件、注册各种模块工厂、初始化RuleSet集合、加载配置的插件等。
  • 开始编译:执行compiler对象的run方法。
  • 确定入口:根据配置中的entry找出所有的入口文件,调用compilition.addEntry将入口文件转换为dependence对象。

这个过程需要在webpack初始化的时候预埋下各种插件,经历4个文件,7次跳转才开始进入主题。

3.2、构建阶段

「前端」腾讯前端工程师总结的 webpack基础、分包大揭秘

  • 编译模块(make):根据entry对应的dependence创建module对象,调用loader将模块转译为标准JS内容,调用JS解释器将内容转换为AST对象,从中找出该模块依赖的模块,再递归。本步骤直到所有入口依赖的文件都经过了本步骤的处理。
  • 完成模块编译:上一步递归处理所有能触达到的模块后,得到了每个模块被翻译后的内容以及它们之间依赖关系图。

构建阶段从entry开始递归解析资源与资源的依赖,在compilation对象内逐步构建出module集合以及module之间的依赖关系。

这个过程中数据流module=>ast=>dependences=>module,先转AST再从AST找依赖。compilation按这个流程递归处理,逐步解析出每个模块的内容以及module依赖关系,后续就可以根据这些内容打包输出。

3.3、生成阶段

「前端」腾讯前端工程师总结的 webpack基础、分包大揭秘

输出资源(seal):根据入口和模块之间的依赖关系,组装成一个个包含多个模块的Chunk,再把每个Chunk转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会。

写入文件系统(emitAssets):在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。

seal的关键逻辑是将module按规则组织成chunks,webpack内置的chunk封装规则比较简单:entry及entry触达到的模块,组合成一个 chunk 使用动态引入语句引入的模块,各自组合成一个chunk。

chunk是输出的基本单位,默认情况下这些chunks与最终输出的资源一一对应,那按上面的规则大致上可以推导出一个entry会对应打包出一个资源,而通过动态引入语句引入的模块,也对应会打包出相应的资源。

四、chunk概念及分包基本规则

4.1、webpack资源形态流转

「前端」腾讯前端工程师总结的 webpack基础、分包大揭秘

webpack资源形态流转

从资源流转的层面,我们来看下webpack的打包流程:

  • compiler.make阶段:

entry文件以dependence对象形式加入compilation的依赖列表,dependence对象记录有entry的类型、路径等信息。

根据dependence调用对应的工厂函数创建module对象,之后读入module对应的文件内容,调用loader-runner对内容做转化,转化结果若有其它依赖则继续读入依赖资源,重复此过程直到所有依赖均被转化为module。

  • compilation.seal阶段:

遍历module集合,根据entry配置及引入资源的方式,将module分配到不同的chunk。

遍历chunk集合,调用compilation.emitAsset方法标记chunk的输出规则,即转化为assets集合。

  • compiler.emitAssets阶段:

将assets写入文件系统

综上,Module主要作用在webpack编译过程的前半段,解决原始资源“如何读”的问题;而Chunk对象则主要作用在编译的后半段,解决编译产物“如何写”的问题,两者合作搭建起webpack搭建主流程。

4.2、chunk概念

从上面的webpack资源形态流转图以及解析中,我们不难发现chunk的大概概念。

chunk:webpack实现中,原始的资源模块以Module对象形式存在、流转、解析处理。

而Chunk则是输出产物的基本组织单位,在生成阶段webpack按规则将entry及其它Module插入Chunk中,之后再由SplitChunksPlugin插件根据优化规则与ChunkGraph对Chunk做一系列的变化、拆解、合并操作,重新组织成一批性能(可能)更高的Chunks 。运行完毕之后webpack继续将 chunk一一写入物理文件中,完成编译工作。代码块,是webpack根据功能拆分出来的(chunk是无法在打包结果中看到的,打包结果中看到的是bundle)。

4.3、chunk的基本分包规则

chunk可以分为三类:

  • 每个entry项都会对应生成一个chunk对象,称之为initial chunk。
  • 每个异步模块都会对应生成一个chunk对象,称之为async chunk。
  • Webpack 5之后,如果entry配置中包含runtime值,则在entry之外再增加一个专门容纳runtime的chunk对象,此时可以称之为runtime chunk。

默认情况下initial chunk通常包含运行该entry所需要的所有runtime代码,但webpack 5之后出现的第三条规则打破了这一限制,允许开发者将runtime从initial chunk中剥离出来独立为一个多entry间可共享的 runtime chunk。

注意

  • 「业务模块」是指开发者所编写的项目代码。
  • 「runtime 模块」是指Webpack分析业务模块后,动态注入的用于支撑各项特性的运行时代码。

4.4、bundle vs chunk

bundle: bundle是webpack打包之后的各个文件,一般就是和chunk是一对一的关系,但有时候也不完全是一对一的关系。bundle就是对chunk进行编译压缩打包等处理之后的产出。

「前端」腾讯前端工程师总结的 webpack基础、分包大揭秘

Chunk是过程中的代码块,Bundle是结果的代码块。

五、SplitChunksPlugin的前世今生

默认情况下,Webpack会将所有代码构建成一个单独的包,这在小型项目通常不会有明显的性能问题,但伴随着项目的推进,包体积逐步增长可能会导致应用的响应耗时越来越长。归根结底这种将所有资源打包成一个文件的方式存在两个弊端:

  • 「资源冗余」:客户端必须等待整个应用的代码包都加载完毕才能启动运行,但可能用户当下访问的内容只需要使用其中一部分代码。
  • 「缓存失效」:将所有资源达成一个包后,所有改动——即使只是修改了一个字符,客户端都需要重新下载整个代码包,缓存命中率极低。

一个多页面应用,所有页面都依赖于相同的基础库,那么这些所有页面对应的entry都会包含有基础库代码,这岂不浪费?这些问题都可以通过对产物做适当的分解拆包解决 ,诞生了CommonsChunkPlugin。

5.1、CommmonsChunkPlugin的弊端

CommmonsChunkPlugin的思路是Create this chunk and move all modules matching minChunks into the new chunk,即将满足minChunks配置想所设置的条件的模块移到一个新的chunk文件中去,这个思路是基于父子关系的,也就是这个新产出的new chunk是所有chunk的父亲,在加载孩子chunk的时候,父亲chunk是必须要提前加载的。举例:

  • 同步模块加载
example:
entryA:  vue  vuex  someComponents 
entryB:  vue axios someComponents 
entryC: vue vux axios someComponents minchunks: 2

产出后的chunk:

vendor-chunk:vue vuex axios 
chunkA~chunkC: only the components

对entryA和entryB来说,vendor-chunk都包含了多余的module。

  • 异步的模块
example:
 entryA:  vue  vuex  someComponents 
 asyncB:vue axios someComponents 
 entryC: vue vux axios someComponents 
 minchunks: 2

产出后的chunk:

vendor-chunk:vue vuex  
chunkA: only the components
chunkB: vue axios someComponents 
 chunkC: axios someComponents<

相关内容

沁源县沁河乡村e镇抖音直播培训开班啦!欢迎同学踊跃报名!

免费培训!免费午餐!快来报名吧!抖音直播带货培训基础培训、实操入门培训及进阶培训为巩固拓展脱贫攻坚成果同乡村振兴有效衔接,培育新的经济增长点,助力农民增收,更深入开展沁源县乡村e镇项目工作,完善沁源县电商人才培训体系,满足农村居民美好生活需···

山西省林学会举办自然教育人力资源双创服务培训班

山西省林学会举办山西省自然教育人力资源双创服务培训班,通过理论讲授、互动交流和分组讨论的方式,加强自然教育人才队伍建设,促进我省自然教育和林草科普事业的发展。▲山西省自然教育人力资源双创服务培训班开班仪式现场。11月11日-13日,山西省林···

山西发放10亿元职业技能电子培训券 劳动者凭电子券享受免费职业技能培训

来源:央广网央广网太原4月19日消息(记者贺威通 通讯员康熙如)近日,山西公开发放首批面值10亿元的职业技能电子培训券,广大劳动者可以凭电子券享受免费的职业技能培训。今年,山西采取发放职业培训券的方式开展职业技能培训工作,对技能培训全过程实···

去哪儿了解职业技能培训项目和机构?

···

种植加工技术、科学管理农田、直播带货技能……山西省2022年高素质青年农民培训班即将开班

11月30日,山西晚报记者从团省委获悉,为引导广大青年农民更好地实施乡村振兴战略、加快农业农村现代化贡献青春力量,共青团山西省委、山西省农业农村厅将联合开展2022年度高素质青年农民培训工作,并结合我省实际,制定《山西省2022年高素质青年···

宁夏援外医疗队在贝宁开展中医针灸培训

中新网银川8月31日电 (记者 杨迪)当地时间8月30日,中国(宁夏)第26批援贝宁医疗队在非洲国家贝宁的纳迪丹古妇幼医院举办“中医针灸技术培训班”,为来自受援医院的20余名医务人员讲解、教授中医针灸的相关知识及实操技巧。为贝宁医务人员开展···

祁阳市总工会2023年育婴员职业技能培训班开班

湖南日报·新湖南客户端11月6日讯(通讯员 邓成)11月6日,祁阳市2023年“女职工素质提升培训——育婴员职业技能培训班”在万联职业学校正式开班,授课老师和培训学员共计50余人参加。祁阳市委常委、组织部长、市总工会主席唐旭出席开班仪式并讲···

2023年湖南省高素质农民培育常德市本级无人机飞手专题培训班开班

近日,由常德市农业农村局主办、常德职业技术学院承办、湖南精飞智能科技有限公司协办的“2023年湖南省高素质农民培育常德市本级无人机飞手专题培训班”开班,来自全市各区(县、市)的70名学员参加。开班仪式现场常德市农业农村局二级调研员罗卫华、常···

新化县:技能培训强本领,提升能力促就业

湖南日报·新湖南客户端通讯员 陈慧今年以来,新化县大力开展职业技能培训,提升城乡劳动力市场就业能力,加强与相关岗位的适配性,从根本上为群众解决就业压力,实现高质量就业,进而增进民生福祉。认真贯彻落实省、市职业技能培训文件精神,加强职业技能培···

2023年湖南省高素质农民培育桃源县新农商带头人(直播)培训班正式开班

科教新报·新湖南客户端讯(通讯员 郭云华)为进一步改善农产品营销策略,推进乡村经济发展,助力乡村振兴,根据县委、县政府的部署安排,11月6日,由桃源县农业农村局主办、桃源县职业中专承办的2023年桃源县新农商带头人(直播)培训班正式开班。县···

以训代练 以训提能 以训促战——内乡县综合应急救援队开展无人机和风力灭火机技能培训

为加强救援队伍标准化、规范化建设,提升救援队伍综合素质和救援能力,充分发挥无人机和风力灭火机在应急事件处理中的实战作用,10月12日下午应急救援队进行无人机实操飞行和风力灭火机的技能培训。培训活动中,综合应急救援队副队长李帅同志先后就无人机···

特别关注·“技能河南”建设系列报道③丨培训厚“技” 人才“勃”发

中国平煤神马集团首席技能大师杨庆华在测试自行研发的井下自动化设备模块。受访者供图宇通集团实训中心,“大国工匠”牛东昌给员工们模拟焊接技术。王向前 摄郑州交通技师学院实训教学中心,学生们在老师指导下维修车身。王向前 摄河南日报记者 王向前“不···

平桥区2023年“人人持证、技能河南”建设职业技能培训补贴的公示

根据《2023年河南省补贴性职业技能提升行动目录清单》、《河南省“人人持证、技能河南”建设工作领导小组办公室关于印发< 2023年高质量推进“人人持证、技能河南”建设工作方案>的通知》豫技领办〔2023〕12号、《河南省人力资源···

山东省做好高素质农民教育培训技能和学历“双提升”

来源:人民网-山东频道日前,山东省农业广播电视学校在淄博市召开高素质农民教育培训与学历提升有效衔接试点工作教学计划研讨会议,有关县(市、区)分校(中心)负责同志参加研讨。会议旨在贯彻落实《山东省农业农村厅关于印发的通知》文件精神,切实做好高···

2023年山东省全民数字素养与技能提升月今日启动 活动“剧透”来了

···

黑龙江省省文化和旅游厅扎实开展“送教上门”职业技能培训

(焦阳中国商报黑龙江综合采写)冰雪资源是黑龙江省的特色旅游资源,亚雪旅游线是全国知名的“白金”旅游线,也是冰雪旅游目的地,具有独特发展优势。近年来,黑龙江省在发展冰雪旅游、冰雪经济上取得了长足发展,但也亟需解决丰富旅游产品、提升服务意识、服···

奋“泳”向前!“新蓝”游泳技能培训班开训啦

点击关注 辽宁消防 2023-04-25 发表于辽宁视频加载中...辽宁省消防救援总队第五批新消防员入职培训工作开展至今,新训大队在总队、支队两级党委的坚强领导下,对标新时期消防救援队伍“全灾种、大应急”的职能需要,秉承“初始即专,一专到底···

辽宁将评选10家职业技能培训示范基地和20家技能大师工作站

近日,省人社厅下发通知,开展2023年辽宁省职业技能培训示范基地和技能大师工作站项目建设申报工作,全省拟评选10家省级职业技能培训示范基地和20家省级技能大师工作站,以加快推进我省高技能人才队伍建设。通知提出,省级职业技能培训示范基地的申报···

山西将在五年内每年培训一百万技能人才

技能培训,让就业更稳当“大家好,我是烹饪培训老师贾安平,今天为大家分享一道美食,就是这个金汤酸菜鱼,现在开始我们逐步讲解它的做法……”下午3:30,山西运城盐湖区彩虹职业培训学校老师贾安平准时进入直播间进行授课。这样的线上培训是山西省全民技···

想学技能,职业技能培训项目和机构怎么找?解答来了→

(以上图文若涉及侵权,请原作者及时与我们联系)来源|人力资源和社会保障部编辑|徐 飞校对|白子璐审核|邰荣军···