原文链接:webpack-changelog-v5

指南

v5重点:

  • 尝试使用持久性缓存来提高构建性能。
  • 尝试使用更好的算法和默认值来改进长期缓存
  • 尝试在不进行重大更新的情况下,清理在v4中实现特性时处于怪异状态的内部结构。
  • 尝试通过重大更新来尽可能长时间地停留在v5上,从而为将来的特性做准备。

主要更新

删除了弃用的东西

v4中已弃用的所有内容都已删除。
迁移:确保你的webpack 4版本不打印弃用警告。
以下是一些已删除但在v4中没有弃用警告的内容:

  • IgnorePlugin和BannerPlugin必须传递一个options对象。

删除自动添加的nodejs polyfills

在早期,webpack旨在允许在浏览器中运行大多数node.js模块,但模块格局发生了变化,许多模块现在都是为了前端而编写的。
webpack <= 4 附带了许多node.js核心模块的polyfill。一旦使用就会自动添加。
虽然这使得使用为node.js编写的模块变得简单,但这会将巨大的polyfill添加到bundle中。在许多情况下,我们甚至并不需要这些polyfills。
webpack 5停止自动填充这些核心模块,并试图专注于前端兼容的模块。

迁移:

  • 尽可能尝试使用前端兼容模块
  • 可以手动为node.js核心模块添加polyfill。错误消息会告诉你如何执行此操作
  • package作者:使用package.json中的browser字段让package做到前端兼容。为浏览器提供可替代的implementations/dependencies

反馈:请提供您喜欢或不喜欢这种变化的反馈。我们不确定这是否会进入最终版本。

确定的Chunk以及模块ids

我们为长期缓存添加了新算法。这些在生产模式下默认启用。

1
chunkIds: "deterministic", moduleIds: "deterministic"

算法为module和chunk分配3或4个字符数字id。这是bundle size和长期缓存之间的权衡。
迁移:
最好使用chunkIds和moduleIds的默认值。您也可以选择使用旧的默认值:

1
chunkIds: "size", moduleIds: "size"

这将创建更小的bundles

命名块ids

在开发模式下默认启用的新命名块ID算法为块(和文件名)提供了有用的名称。模块ID由路径确定。块ID由块内容确定。
所以你不再需要使用以下代码来debug

1
import(/* webpackChunkName: "name" */ "module")

但是这仍然使得控制生产的文件名有意义。
在生产环境可以使用:

1
chunkIds: "named"

但要确保不要意外地暴露有关模块名称的敏感信息。
迁移:
如果在开发模式下,你不喜欢更改文件名,你可以设置:

1
chunkIds: "natural"

编译器空闲和关闭

编译器现在需要在使用后关闭。编译器在进入和离开空闲状态时都提供了钩子函数。插件可以使用它来做不重要的工作。即持久缓存缓慢地存储缓存到硬盘。
插件认为某些用户可能忘记关闭编译器,因此所有工作最终都应该在空闲状态下完成。当工作完成时,应该防止进程退出。传递回调时,webpack()会自动调用close。
迁移:
使用node.js API时,请确保在完成后调用Compiler.close。

SplitChunks和模块大小

相比单个数字,模块现在以更好的方式来表示大小。现在有不同类型的大小。
SplitChunksPlugin学习了如何处理这些不同的大小并将它们用于minSize和maxSize。默认情况下,只处理javascript大小。但现在可以传递多个值来处理它们。

1
2
3
4
minSize: {
javascript: 30000,
style: 50000,
}

迁移:
检查你在构建过程中使用哪种大小类型并且在splitChunks.minSize或splitChunks.maxSize中配置。

持久缓存

现在有一个实验性的文件系统缓存。这是可选的,可以通过在配置中设置来生效。

1
cache: { type: "filesystem" }

目前只有核心功能集已准备就绪,在使用它时,应该了解当前的限制以避免奇怪的错误。如果不理解这些限制,就不要使用此功能。

模块源代码和文件系统结构存在自动缓存失效。配置和loader/插件/核心更改没有自动缓存失效。配置或构建代码更改时,可以选择手动缓存失效 (cache.version)。

我们计划添加这个,但是还没有准备好。

下面是一个指南:

  • 升级工具依赖项(webpack,loader,plugin)
  • 改变配置

提示:如果想要自动执行此操作,最好将webpack.config.js和node_modules / .yarn-integrity哈希化,并将其传递给cache.version。我们可能会这样来做。

最小的nodejs版本

最小的node.js版本从6增加到8。
迁移:
升级到最新的node.js版本

配置的更改

结构的变化:

  • cache: Object removed: Setting to a memory-cache object is no longer possible
  • cache.type added: It’s now possible to choose between "memory" and "filesystem"
  • New configuration options for cache.type = "filesystem" added:
    • cache.cacheDirectory
    • cache.name
    • cache.version
    • cache.store
    • cache.loglevel
    • cache.hashAlgorithm
  • resolve.cache added: Allows to disable/enable the safe resolve cache
  • resolve.concord removed
  • Automatic polyfills for native node.js modules were removed
    • node.Buffer removed
    • node.console removed
    • node.process removed
    • node.* (node.js native module) removed
    • MIGRATION: resolve.alias and ProvidePlugin. Errors will give hints.
  • optimization.chunkIds: "deterministic" added
  • optimization.moduleIds: "deterministic" added
  • optimization.moduleIds: "hashed" deprecated
  • optimization.moduleIds: "total-size" removed
  • Deprecated flags for module and chunk ids were removed
    • optimization.hashedModuleIds removed
    • optimization.namedChunks removed (NamedChunksPlugin too)
    • optimization.namedModules removed (NamedModulesPlugin too)
    • optimization.occurrenceOrder removed
    • MIGRATION: Use chunkIds and moduleIds
  • optimization.splitChunks sizes can now be objects with a size per source type
    • minSize
    • maxSize
    • maxAsyncSize
    • maxInitialSize
  • optimization.splitChunks maxAsyncSize and maxInitialSize added next to maxSize: allows to specify different max sizes for initial and async chunks
  • optimization.splitChunks name: true removed: Automatic names are no longer supported
    • MIGRATION: Use the default. chunkIds: "named" will give your files useful names for debugging
  • optimization.splitChunks.cacheGroups[].idHint added: Gives a hint how the named chunk id should be chosen
  • optimization.splitChunks automaticNamePrefix removed
    • MIGRATION: Use idHint instead
  • output.devtoolLineToLine removed
    • MIGRATION: No replacement
  • output.hotUpdateChunkFilename: Function is now forbidden: It never worked anyway.
  • output.hotUpdateMainFilename: Function is now forbidden: It never worked anyway.
  • stats.chunkRootModules added: Show root modules for chunks
  • stats.orphanModules added: Show modules which are not emitted
  • stats.runtime added: Show runtime modules
  • stats.chunkRelations added: Show parent/children/sibling chunks (since alpha.1)
  • stats.preset added: select a preset (since alpha.1)
  • BannerPlugin.banner signature changed
    • data.basename removed
    • data.query removed
    • MIGRATION: extract from filename
  • SourceMapDevToolPlugin lineToLine removed
    • MIGRATION: No replacement
  • [hash] as hash for the full compilation is now deprecated
    • MIGRATION: Use [fullhash] instead or better use another hash option
  • [modulehash] is deprecated
    • MIGRATION: Use [hash] instead
  • [moduleid] is deprecated
    • MIGRATION: Use [id] instead
  • [filebase] removed
    • MIGRATION: Use [base] instead
  • New placeholders for file-based templates (i. e. SourceMapDevToolPlugin)
    • [name]
    • [base]
    • [path]
    • [ext]
  • externals when passing a function it has now a different signature ({ context, request }, callback)
    • MIGRATION: Change signature

更改默认值

  • module.unsafeCache is now only enabled for node_modules by default
  • optimization.moduleIds defaults to deterministic in production mode instead of size
  • optimization.chunkIds defaults to deterministic in production mode instead of total-size
  • optimization.nodeEnv defaults to false in none mode
  • resolve(Loader).cache defaults to true when a cache is used
  • resolve(Loader).cacheWithContext defaults to false
  • node.global defaults to false

主要的内部变化

下面的变化仅和你编写插件时相关:

运行时模块

大部分运行时代码被移动到所谓的“运行时模块”中。这些特殊的模块添加了运行时代码。它们可以添加到任何块中,但目前始终添加到运行时块中。“Runtime requirements”控制将哪些运行时模块添加到bundle中。他确保只将使用的运行时代码添加到bundle中。在将来,运行时模块还可以添加到按需加载的块中,以在需要时加载运行时代码。

核心的运行时代码现在非常小,只包含__webpack_require__函数,模块工厂和模块实例缓存。将来可以使用替代代码来避免将bundle包装在IIFE中并允许ESM类型的导出。

迁移:在插件中请考虑使用RuntimeModules来将运行时代码注入到webpack运行时。

序列化

添加了序列化机制以允许在webpack中序列化复杂对象。它具有可选语义,因此需要显式标记应该序列化的类。大多数模块,所有依赖项和一些错误已经实现该功能。

迁移:使用自定义模块或依赖项时,请确保它们可序列化,以从持久性缓存中受益。

可扩展的缓存

添加了具有插件接口的Cache类。此类可用于写入和读取缓存。根据配置,不同的插件会将功能添加到缓存中。MemoryCachePlugin添加了内存缓存。FileCachePlugin添加了持久性缓存。

FileCachePlugin使用序列化机制来持久化缓存到硬盘中。

Hook object frozen

带钩子的类使其钩子对象冻结,因此不再可能通过这种方式添加自定义钩子。

迁移: 推荐的添加自定义钩子的方法是通过WeakMap和一个静态的方法 getXXXHooks(XXX)(即getCompilationHook(compilation))。内部类使用相同的机制来自定义钩子。

移除Tapable的基础类

删除webpack3插件的compat层,它已被webpack4抛弃。

迁移:使用tapable的新API。

阶段性的钩子

在运行过程中不同阶段有许多的钩子,即optimizeDependenciesBasic、optimizeDependencies和 optimizeDependenciesAdvanced。这些已经被删除,我们可以通过stage选项来使用单一的钩子。查看
OptimizationStages以获取可能的值。

迁移:添加stage选项。

order和ids

webpack常常在编译阶段整理modules和chunks,这是一个特殊的方法来分配ids。

目前已不再是这种情况了。Order不再用于id的产生。 而是在插件中完全控制id生成。

已删除用于优化module和chunk顺序的挂钩。

迁移:你不能再依赖于编译中的module和chunk的顺序。

数组到Set

  • Compilation.modules 是Set类型
  • Compilation.chunks 是Set类型

有一个复合层可以打印弃用警告。

迁移:使用Set方法取代Array方法

Compilation.fileSystemInfo

这些类可以以缓存的方式访问文件系统信息。目前,它允许请求文件和目录时间戳。如果可能,有关时间戳的信息从观察者传输,否则由文件系统访问确定。将来会要求添加文件内容哈希,并且模块可以使用文件内容而不是文件哈希来检查有效性。

迁移:使用compilation.fileSystemInfo来代替file/contextTimestamps

热更新

HMR runtime已重构为runtime Modules。HotUpdateChunkTemplate已被合并到ChunkTemplate。ChunkTemplates 和插件也可以处理HotUpdateChunks。
HMR运行时的javascript部分已与核心HMR运行时分离。其他模块类型现在也可以以自己的方式处理HMR。将来允许HMR用来mini-css-extract-plugin 或 WASM模块。

迁移:由于这是一项新功能,以前没有实现,所以不需要迁移。

工作队列

webpack过去常常处理模块时使用函数调用函数以及限制并行性的信号量的方式。Compilation.semaphore已经被移除。异步队列来处理工作队列。每个步骤都有一个单独的队列:

  • Compilation.factorizeQueue: 为一组依赖项调用模块工厂
  • Compilation.addModuleQueue: 将模块添加到编译中(可以从缓存中恢复模块)
  • Compilation.buildQueue: 必要时构建模块(可以存储模块到缓存)
  • Compilation.rebuildQueue: 如果手动触发,则再次构建模块
  • Compilation.processDependenciesQueue: 处理模块的依赖

这些队列有一些钩子可以监视和拦截工作进程。
将来,多个编译器可以协同工作,并且可以通过拦截这些队列来完成工作协调。

迁移:以前没有,无需迁移。

Module and Chunk Graph

webpack常常将将解析的模块存储在依赖中,将包含的模块存储在chunk中。现在已经不这样了。有关模块如何在模块图中连接的所有信息现在都存储在ModuleGraph类中。有关模块如何与块连接的所有信息都存储在ChunkGraph类中。依赖于chunk graph的信息也存储在相关类中。

这意味着已移动有关模块的以下信息:

  • Module connections -> ModuleGraph
  • Module issuer -> ModuleGraph
  • Module optimization bailout -> ModuleGraph (TODO check if it should ChunkGraph instead)
  • Module usedExports -> ModuleGraph
  • Module pre order index -> ModuleGraph
  • Module post order index -> ModuleGraph
  • Module depth -> ModuleGraph
  • Module profile -> ModuleGraph
  • Module id -> ChunkGraph
  • Module hash -> ChunkGraph
  • Module runtime requirements -> ChunkGraph
  • Module is in chunk -> ChunkGraph
  • Module is entry in chunk -> ChunkGraph
  • Module is runtime module in chunk -> ChunkGraph
  • Chunk runtime requirements -> ChunkGraph

初始化 fragments

已删除DependenciesBlockVariables以支持InitFragments。DependencyTemplates现在可以添加InitFragments以将代码注入模块源的顶部。InitFragments允许重复数据删除

模块源类型

模块现在必须通过Module.getSourceTypes()告诉它们支持哪些源类型。根据不同的插件,使用此类型调用source() 即对于源类型javascript ,JavascriptModulesPlugin将源代码嵌入到bundle中。源类型webassembly将使WebAssemblyModulesPlugin释放一个wasm文件。自定义源类型是可能的,即
mini-css-extract-plugin可能会使用源类型stylesheet将源代码嵌入到css文件中。

模块类型和源类型之间没有关系。即模块类型json也使用源类型javascript和模块类型webassembly / experimental使用源类型javascript和webassembly。

迁移:自定义模块需要实现这些新的接口方法

可扩展的统计数据

stats预设,默认,json,和tostring现在由插件系统提供。将当前的Stats转换为插件。

迁移:现在可以自定义它,而不是替换整个统计功能。现在可以将额外信息添加到统计信息json中,而不是写入单独的文件。