Webpack 5升级内容
版本发布时间
- webpack 4于2018年2月发布
- Webpack 5.0.0于2020年10月10日发布
此版本关注
此版本重点关注以下内容:
-
通过持久化缓存提高构建性能。
-
使用更好的算法和默认值来改善长期缓存。
-
通过更好的Tree Shaking和代码生成来改善bundle大小。
-
清理处于怪异状态的内部结构,同时在v4中实现功能而不引入任何重大更改。
Clean up internal structures that were left in a
weird state
while implementing features in v4 without introducing any breaking changes. -
引入一些重大变更,为将来的功能做准备,使我们能够尽可能长时间地使用v5。
本次分享关注:
- 缓存相关(构建缓存和上线缓存)
- 模块联邦
- 一些性能改善
重大变化:移除
删除过时的项目
-
v4中所有deprecated的项目均已删除。
-
也有一些v4中没有被警告deprecation的变更,比如
IgnorePlugin
和BannerPlugin
,现在必须传递一个参数(可以是对象,字符串或函数)。 下面是一个IgnorePlugin
的示例:new webpack.IgnorePlugin({ resourceRegExp: regex })
迁移注意:v4中已弃用的所有项目已在 v5中删除。 当迁移到 v5时,请确保 Webpack 4版本不会打印弃用警告。
弃用(代)码
新的弃用包含一个弃用代码,因此更易于引用。
New deprecations include a deprecation code
so they are easier to reference.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WroKDPtn-1605456922061)(https://i.loli.net/2020/10/29/FxorPksYm1OANv9.jpg)]
弃用的语法
require.include
已被弃用,使用时默认会发出警告。
注意:当然这个行为可以通过 Rule.parser.requireInclude
来把这个语法改成 allowed, deprecated 或者 disabled。
自动删除Node.js Polyfills
早期,webpack的目标是允许在浏览器中运行大多数Node.js模块,但是模块格局发生了变化,现在许多模块用途的编写主要是用于浏览器。webpack <= 4带有许多Node.js核心模块的polyfill,一旦模块使用了任何核心模块(例如crypto
模块),这些模块就会自动应用。
这个时候再自动 Polyfills 一些 Node 模块(例如 crypto)无疑会增加打包体积,在 Webpack5 之后去掉了这个自动行为。
迁移注意:
- 尽可能尝试使用与前端兼容的模块。
- 可以为Node.js核心模块手动添加polyfill。错误消息将提示如何实现。
重大变化:chunk和(线上)长期缓存 🚩🚩
确定性的chunk、module IDs
-
添加了用于长期缓存的新算法。
-
首先是模块、ID和导出名称都唯一确定下来,背后对应的配置如下:
optimization: {
chunkIds: "deterministic",
moduleIds: "deterministic",
mangleExports: "deterministic"
}
- 该算法以确定性方式为chuck和module分配短(
3或5位数字
)数字ID,这是包大小和长期缓存之间的一种权衡。 - 虽然可以用Magic Comments、或用一些插件就可以固定住他的 moduleIds & chunkIds,但是V5将不需要引入任何的外力;除此之外如果项目不复杂,依旧可以设置
optimization: { chunkIds: 'named' }
它是兼容的。 - 在
生产模式
下默认启用了上面功能
。但是可以修改moduleIds/chunkIds/mangleExports: false
禁用默认行为,并且可以通过插件提供自定义算法。请注意,在moduleIds/chunkIds: false
没有自定义插件的webpack 4中,生成的版本有效,而在webpack 5中,您必须提供自定义插件。
迁移:最好使用默认值chunkIds
,moduleIds
和mangleExports
。您还可以选择使用旧的默认设置chunkIds: "size", moduleIds: "size", mangleExports: "size"
,这将生成较小的包,但使它们更频繁地失效以进行缓存。
注意:
- chunkId设置为deterministic,则output中chunkFilename里的
[name]
会被替换成确定性短数字ID - 虽然chuckId不变(不管值是deterministic | natural | named),但更改chunk内容,chunkhash还是会改变的
Chunk IDs 语义化
-
在
开发模式
下,默认启用的新的named chunk ID 算法为模块(和文件名)提供了人类可读的名称。 -
所以不再需要使用
import(/* webpackChunkName: "name" */ "module")
来debugging。 但如果你想控制生产环境的文件名,还是有意义的。 -
虽然可以在生产环境中使用
chunkIds: "named"
,但要确保不要不小心暴露模块名的敏感信息。
迁移:如果您不喜欢在开发
中更改文件名,则可以通过chunkIds: "natural"
使用旧的数字模式。
真实内容哈希
- 在 Webpack5 里会使用文件内容的真实哈希
[contenthash]
,而不是之前的“仅”使用文件内部结构的哈希 - 这对于长期缓存有着积极的影响,尤其是代码里面
只有注释和变量名修改
的时候,Webpack会继续用之前的缓存而不是新的文件内容
注意: mode为production
时,这个contenthash的新功能会生效
重大变化:性能
持久缓存 🚩🚩
现在有一个缓存cache配置
,cache生成的 webpack 模块和 chunk,来改善构建速度。它是可选的,可以通过以下配置启用:
module.exports = {
cache: {
// 1. 将缓存类型设置为文件系统
type: 'filesystem',
buildDependencies: {
// 2. 将你的 config 添加为 buildDependency,以便在改变 config 时获得缓存无效
// __filename变量获取当前文件的带有完整绝对路径的文件名
config: [__filename],
// 3. 如果你有其他的东西被构建依赖,你可以在这里添加它们
// 注意,webpack、加载器和所有从你的配置中引用的模块都会被自动添加
},
},
};
重要笔记:
-
cache
会在开发模式被设置成type: 'memory'
而且在 生产模式中禁用memory
。cache: true
与cache: { type: 'memory' }
配置作用一致。 传入false
会禁用缓存。 -
type: 'memory' | 'filesystem'
将
cache
类型设置成内存或者文件系统。memory
选项是非常直白的,它告诉 webpack 将内存存放在内存中并且不允许额外的配置:webpack.config.js
module.exports = { //... cache: { type: 'memory' } };
当将
cache.type
设置成filesystem
会开放更多的选荐可配置。 -
缓存将默认存储在
node_modules/.cache/webpack
(当使用 node_modules 时)或.yarn/.cache/webpack
(当使用 Yarn Plug’nPlay 时)中。 当所有的插件都正确处理缓存时,你可能永远都不需要手动删除它。 -
许多内部插件也会使用持久性缓存。例如
SourceMapDevToolPlugin
(缓存 SourceMap 的生成)或ProgressPlugin
(缓存模块数量) -
持久性缓存将根据使用情况自动创建多个缓存文件,以优化对缓存的读写访问。
-
默认情况下,时间戳将用于开发模式的快照,而文件哈希将用于生产模式。 文件哈希也允许在 CI 中使用持久性缓存。