// 在项目中我使用到了 crypto 模块,webpack5会询问是否引入对应的 polyfill。
Module not found: Error: Can't resolve 'crypto' in '/Users/xxx/Documents/private-project/webpack/ac_repair_mobile_webpack_5/node_modules/sshpk/lib/formats'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need these module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add an alias 'resolve.alias: { "crypto": "crypto-browserify" }'
- install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.alias: { "crypto": false }
如何升级到webpack5
To v5 from v4
webpack5 新变化与对应的优化措施
在使用webpack的时候,我们常常会做一些优化,比如:
到了webpack5,这些优化措施都变得更加的简单和效果显著了。先从构建速度的优化说起:
构建速度优化
在webpack4中,为了让我们的构建速度更快,我们通常需要借助一些插件或一些额外的配置来达到目的。
比如我们会借助 cache-loader 去对我们构建过程中消耗性能比较大的部分进行缓存,缓存会存放到硬盘中
node_modules/.cache/cache-loader
,缓存的读取和存储是会消耗性能的,所以只推荐用在性能开销大的地方。terserPlugin继承自uglifyjsPlugin,我们可以开启插件的cache以及parallel特性来加快压缩。(terserPlugin是webpack推荐及内置的压缩插件,cache与parallel默认为开启状态)缓存路径在
node_modules/.cache/terser-webpack-plugin
到了webpack5,可以通过cache 特性来将webpack工作缓存到硬盘中。存放的路径为
node_modules/.cache/webpack
包代码体积的优化 - SplitChunks
为了让我们的打出来的包体积更加小,颗粒度更加明确。我们经常会用到webpack的代码分割splitchunk以及tree shaking。在webpack5中,这两者也得到了优化与加强。比如
包代码体积的优化 - Tree Shaking
同时tree shaking也得到了加强,可以覆盖更到负责的场景。
包代码体积的优化 - Node.js Polyfills
在webpack5之前,webpack会自动的帮我们项目引入Node全局模块polyfill。我们可以通过node配置
但是webpack团队认为,现在大多数工具包多是为前端用途而编写的,所以不再自动引入polyfill。我们需要自行判断是否需要引入polyfill,当我们用weback5打包的时候,webpack会给我们类似如下的提示:
webpack5中,增加了resolve.alias配置项来告诉webpack是否需要引入对应polyfill。node配置项也做了调整。
也就是说到了webpack5,我们需要清楚自己的项目需要引入哪些node polyfill。更加了配置的门槛,但是减少了代码的体积。
node: {}
配置项来改成mock或不提供模块resolve.alias
配置项决定每个node模块是否引入polyfill持久化缓存的优化
在日常开发中我们会尽量减少文件hash发生变化的情况,以最大化的利用缓存,节省流量。这就是我们常说的“优化持久化缓存”。首先最简单的措施就是使用contenthash来作为文件哈希后缀,只有当文件内容发生变化的时候,哈希才会发生改变。但是这样并不够。我们还是会遇到这样的问题:
所有文件的哈希后缀都发生了改变,不符合期望,vender~xxx.js的hash不应发生变化。
同样的所有文件的哈希后缀都发生了改变,不符合期望,原有文件hash不应发生变化。
问题原因
在webpack4 中,chunkId与moduleId都是自增id。也就是只要我们新增一个模块,那么代码中module的数量就会发生变化,从而导致moduleId发生变化,于是文件内容就发生了变化。chunkId也是如此,新增一个入口的时候,chunk数量的变化造成了chunkId的变化,导致了文件内容变化。
解决方法
webpack4可以通过设置optimization.moduleIds = 'hashed'与optimization.namedChunks=true来解决这写问题,但都有性能损耗等副作用。
而webpack5 在production模式下optimization.chunkIds和optimization.moduleIds默认会设为'deterministic',webpack会采用新的算法来计算确定性的chunkI和moduleId。默认即可避免上述情况发生。
Module Federation
模块联邦制,使 JavaScript 应用得以从另一个 JavaScript 应用中动态地加载代码 —— 同时共享依赖。项目分为Host(消费者),remote(被消费者)。功能实现主要依靠
ModuleFederationPlugin
插件。比如 app1, 输出log方法
app2, 使用app1中的logSomething 方法