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命令行的解析))将用户配置的 webpack.config.js (vue.congfig.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 对象:
这个对象有两个作用,一是负责组织整个打包过程,包含了每个构建环节及输出环节所对应的方法,可以从图中看到比较关键的步骤,如 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, // 默认
                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这个属性也得相应的去增大
3.test: 正则匹配路径,
4.priority:权重,数字越大表示优先级越高。
5.reuseExistingChunk:表示是否使用已有的 chunk,true 则表示如果当前的 chunk 包含的模块已经被抽取出去了,那么将不会重新生成新的,即几个chunk复用被拆分出去的一个module;
6.enforce:设置了为true,匹配的模块就会忽略前面提到的那几个属性(注释的属性)

3.externals

作用:从打包的bundle文件中排除依赖。换句话说就是让在项目中通过import引入的依赖在打包的时候不会打包到bundle包中去,而是通过cdn的方式去访问这些依赖。
具体配置如下图
1.vue.config.js中
在这里插入图片描述
2.main.js中(注释vue和element-ui主要是为了看是否生效(可以不注释))

在这里插入图片描述
3.public/index.html (CDN引入)
在这里插入图片描述

4.dll(动态链接库)

通常来说,我们的代码都可以简单区分成业务代码和第三方库。如果不做处理,每次构建时都需要把所有的代码重新构建一次,耗费大量的时间。然后大部分情况下,很多第三方库的代码并不会发生变更(除非是版本升级),这时就可以用到dll:把复用性较高的第三方模块打包到动态链接库中,在不升级这些库的情况下,动态库不需要重新打包,每次构建只重新打包业务代码,大大提升了项目的访问速度与打包速度,提升了性能。

1.在根目录下创建dll.config.js(自定义文件名)文件,内容如图所示

entry中配置要独立出来的第三方依赖库在这里插入图片描述
2.在package.json新增一条命令dll,然后在终端中执行npm run dll,它会提示让你安装webpack-cli,安装成功后,再一次执行npm run dll,它会生成两个文件vueSource-manifest.json和vueSource.js
在这里插入图片描述
在这里插入图片描述
2.然后在vue.config.js中如下图进行配置即可
在这里插入图片描述
在打包过程中,它会通过dllReferencePlugin找到vueSource-manifest.json文件(先去动态链接库中去查找),判断里面是否有依赖的包,如果有,就跳过,不进行打包,如果没有才进行打包。
3.在public/index.html文件中手动引入vueSource.js

5.externals与dll对比

共同点:都是对依赖的第三方包进行进一步抽离(分离模块),在本地启用服务时,大大缩短了启用时间,相当于只对业务逻辑代码进行打包
不同点
externals防止将某些 import 的包(package)打包到 bundle 中,而是在运行时再去从外部获取这些扩展依赖(cdn的方式引入)。简单讲,就是把我们引入的三方模块声明为外部依赖,webpack不会对其进行打包,最后我们在打包的项目中通过script外链引入。
dll:将项目依赖的基础模块(第三方模块)抽离出来,然后打包到一个个单独的动态链接库中。当下一次打包时,通过webpackReferencePlugin,如果打包过程中发现需要导入的模块存在于某个动态链接库中,就不能再次被打包,而是去动态链接库中get到。简单讲,就是将第三依赖单独打包,通过引用 manifest.json来把依赖映射到模块上,相当于把原本的一个文件拆分成多个。这样做有三个优点

1.异步加载文件,减少了页面的白屏时间

2.Dll打包以后是独立存在的,只要其包含的库没有修改,其hash也不会变化,因此线上的dll文件基本不需要随着频繁更新。
3.如果多个项目使用了相同的依赖库,可以共用一个文件。

总结:dll配置繁琐一点,但更智能,externals需要cdn引入。

6.extensions,mainFiles,alias配置

在这里插入图片描述

1.extensions:指定extension之后可以不用在require或是import的时候加文件扩展名,会依次尝试添加的扩展名顺序进行匹配
2.alias:配置别名可以加快webpack查找模块的速度,每当引入模块的时候,它会直接引入,而不需要从node_modules文件夹中按模块的查找规则查找或者按照指定路径查找;
3.mainFiles:配置之后它会优先使用文件夹的child.js这个文件,如果没有child.js文件,在查找有没有index.js文件,会根据mainFiles配置的数组顺序依次查找,直到找到为止。

7.多入口、多页面配置(这里就不介绍了,很简单)

感谢大家的支持,如果感觉这篇文章对您有所帮助,麻烦您给点个赞+评论!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
webpack优化配置包括通过配置`configureWebpack`和`chainWebpack`来修改webpack的默认配置,以实现不同的优化效果。 `configureWebpack`是用来修改webpack配置,它的配置内容会与webpack的默认配置进行合并。通过配置`configureWebpack`,我们可以对webpack的各个方面进行优化,比如优化代码分离、减小打包体积、使用CDN服务器等。例如,你可以在`configureWebpack`中配置`optimization`选项来进行代码分离,通过指定`splitChunks`来实现将代码分离到不同的bundle中,从而按需加载或并行加载这些文件。 `chainWebpack`则可以修改webpack的默认配置。通过配置`chainWebpack`,我们可以自定义webpack的打包过程,进行一些特定的优化。例如,你可以使用`exclude`和`cache-loader`等选项来优化打包速度。 总的来说,webpack优化配置可以分为两个方面:打包后的结果的性能优化和打包速度的优化。对于打包后的结果的性能优化,可以通过代码分离来实现。而对于打包速度的优化,可以利用webpack的默认优化配置,也可以根据项目的具体情况进行针对性的优化。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Webpack 配置优化](https://blog.csdn.net/weixin_42682011/article/details/116060572)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [webpack性能优化方案(详细)](https://blog.csdn.net/weixin_57677300/article/details/130684139)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Webpack优化配置缩小文件搜索范围](https://download.csdn.net/download/weixin_38698403/12766302)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我还是我…

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值