Webpack配置优化
Webpack 配置优化
⼀.构建流程
你好!在配置webpack之前先了解⼀下webpack的构建流程,这有助于你对webpack更好的理解,同时这也是⾯试中经常问的问题。下⾯对构建流程先做个简单的介绍。
1.启动(shell 与 config 解析)
每次在命令⾏输⼊ webpack 后,操作系统都会去调⽤ ./node_modules/.bin/webpack 这个 shell 脚本。这个脚本会去调
⽤./node_modules/webpack/bin/webpack.js (webpack.js 是 webpack 的启动⽂件)。
在 webpack.js 这个⽂件中 webpack 通过 optimist (命令⾏解析库-实现了node命令⾏的解析))将⽤户配置的 fig.js (fig.js)和 shell 脚本传过来的参数整合成 options 对象传到了下⼀个流程的控制对象中。options对象如下图所⽰:
Plugins和loader的区别(⼜⼀道经典的⾯试题):
webpack默认只能解析.js的⽂件,⽽.vue、.css、.png、.ts等是不能解析的,所以他要借助各种loader帮助⾃⼰解析这些⽂件,所以loader是起到⼀个辅助性的作⽤,⽽plugins是功能性作⽤,webpack借助各种插件实现代码的打包、封装与抽离,这是⼆者的主要区别;
2. 编译与构建主流程
在加载配置⽂件和 shell 后缀参数申明的插件,并传⼊构建信息 options 对象后,开始整个 webpack 打包最漫长的⼀步。⽽这个时候,真正的 webpack 对象才刚被初始化,具体的初始化逻辑在 lib/webpack.js 中
webpack 的实际⼊⼝是 Compiler 中的 run ⽅法,run ⼀旦执⾏后,就开始了编译和构建流程 ,其中有⼏个⽐较关键的 webpack 事件节点
1)compile 开始编译;
2)make 从⼊⼝点分析模块及其依赖的模块,创建这些模块对象;
3)build-module 构建模块;
4)after-compile 完成构建;
5)seal 封装构建结果;
6)emit 把各个chunk输出到结果⽂件;
7)after-emit 完成输出;
1)编译-核⼼对象 Compilation
compiler.run 后⾸先会触发 compile ,这⼀步会构建出 Compilation 对象:
compiler.run 后⾸先会触发 compile ,这⼀步会构建出 Compilation 对象:
这个对象有两个作⽤,⼀是负责组织整个打包过程,包含了每个构建环节及输出环节所对应的⽅法,可以从图中看到⽐较关键的步骤,如addEntry() , _addModuleChain() , buildModule() , seal() , createChunkAssets() (在每⼀个节点都会触发 webpack 事件去调⽤各插件)。⼆是该对象内部存放着所有 module ,chunk,⽣成的 asset 以及⽤来⽣成最后打包⽂件的 template 的信息
2)编译与构建主流程
在创建 module 之前,Compiler 会触发 make,并调⽤ Compilation.addEntry ⽅法,通过 options 对象的 entry 字段到我们的⼊⼝js⽂件。之后,在 addEntry 中调⽤私有⽅法 _addModuleChain ,这个⽅法主要做了两件事情。⼀是根据模块的类型获取对应的模块⼯⼚并创建模块,⼆是构建模块。
⽽构建模块作为最耗时的⼀步,⼜可细化为三步:
调⽤各 loader 处理模块之间的依赖
webpack 提供的⼀个很⼤的便利就是能将所有资源都整合成模块,不仅仅是 js ⽂件。所以需要⼀些 loader ,⽐如 url-loader ,jsx-loader , css-loader 等等来让我们可以直接在源⽂件中引⽤各类资源。webpack 调⽤ doBuild() ,对每⼀个 require() ⽤对应的 loader 进⾏加⼯,最后⽣成⼀个 js module。
loader 处理后的源⽂件⽣成抽象语法树 AST;
遍历 AST,构建该模块所依赖的模块
对于当前模块,或许存在着多个依赖模块。当前模块会开辟⼀个依赖模块的数组,在遍历 AST 时,将 require() 中的模块通过addDependency() 添加到数组中。当前模块构建完成后,webpack 调⽤ processModuleDependencies 开始递归处理依赖的module,接着就会重复之前的构建步骤。
3)打包输出(重点环节,所有的优化配置都在这⼀环节实现)
在所有模块及其依赖模块 build 完成后,webpack 会监听 seal 事件调⽤各插件对构建后的结果进⾏封装,要逐次对每个 module 和chunk 进⾏整理,⽣成编译后的源码,合并,拆分,⽣成 hash 。 同时这是我们在开发时进⾏代码优化和功能添加的关键环节。
最后⼀步,按照 output 中的配置项将⽂件输出到了对应的 path 中,从⽽ webpack 整个打包过程结束。
⼆.可优化配置(常⽤)
1.TreeShaking(摇晃树)
作⽤:当我们在组件中通过import 导⼊⼀个⽅法时,⽽在组件内部并没有使⽤这个⽅法,在打包时也会把该⽅法打包到⽂件中,这就增加了代码的体积,⽽TreeShaking就是解决这个问题的。配置如下:
主要有两点:
1.只针对于import导⼊的模块
2.在package.json中配置sideEffects属性
{
"name":"testconfig",
"version":"0.1.0",
"private":true,
//sideEffects可以为boolean类型,也可以为数组
"sideEffects":true,// 默认为true,不摇晃,false:全部摇晃掉`在这⾥插⼊代码⽚`
"sideEffects":['@/utils/common.js','*.css']//指定哪些⽂件不被摇晃
//当我们在组件内部import './common.css' 时,如果直接设置成false,打包时它会把css⽂件也摇晃掉,这时就需要把sideEffects配置成数组的格式
.}
2.optimization(最优化配置)
先说⼀下configureWebpack和chainWebpack的区别:
chainWebpack:配置的内容可以修改webpack的默认配置;
configureWebpack:配置的内容最终会和webpack的默认配置进⾏合并
...
configureWebpack:(config)=>{
...
config.optimization ={
splitChunks:{
chunks:'all',
maxInitialRequests:3,// 默认webpack打包流程 面试
cacheGroups:{
utils:{
name:'chunk-utils',
test:/[\\/]utils[\\/]/,
// chunks: "all",//默认
// minChunks: 1,//最少被引⽤1次,才进⾏抽离
// minSize: 0,//包超过这个体积才进⾏抽离
priority:1,
reuseExistingChunk:true,
enforce:true
},
vendors:{
name:'chunk-vendors',
test:/[\\/]node_modules[\\/]/,
chunks:'initial',
priority:2,
// reuseExistingChunk: true,
enforce:true
}
}
}
};
cacheGroups中默认有两个属性,⼀个是vendors,⼀个是default,test: 表⽰要过滤 node_modules,所有node_modules下的包都打到vendors⾥,⽽剩下的打包到默认的app.js中,显然这不符合我们优化的需求,⽽cacheGroups可以帮助我们对代码做进⼀步抽离。
1.utils(⾃定义命名):项⽬开发中的⼯具类库,可以抽离出来单独打⼀个包
2.maxInitialRequests: 3, // 默认,,表⽰⾸页⾯最多请求3次,所以就把app.js分了3个出来, 当我们配置cacheGroups抽离超过
3个包时,maxInitialRequests这个属性也得相应的去增⼤
4.priority:权重,数字越⼤表⽰优先级越⾼。
重新⽣成新的,即⼏个chunk复⽤被拆分出去的⼀个module;
作⽤:从打包的bundle⽂件中排除依赖。换句话说就是让在项⽬中通过import引⼊的依赖在打包的时候
不会打包到bundle包中去,⽽是通过cdn的⽅式去访问这些依赖。
具体配置如下图
fig.js中
2.main.js中(注释vue和element-ui主要是为了看是否⽣效(可以不注释))
3.public/index.html (CDN引⼊)
4.dll(动态链接库)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论