Webpack|Webpack 5 中的新特性
你可能已经在使用Webpack来打包前端资源,Webpack即将发布新的V5版本。在本文中,我将分享 Webpack 5的一些新特性,以及在日常工作中继续使用它时应该注意的事项。
该版本新增了大量的新功能,这里简单介绍其中被Webpack Core Team提到的核心功能。
预期
在写这篇文章的时候,v5版本仍然处于早期阶段,可能仍然有问题。作为一个major版本,其中有一些breaking changes,可能会导致一些常见不能做正常工作。Webpack 尝试在可能的情况下提供兼容层,有些更改使其非常难处理,特别是会增加额外的运行时代码。 如果有插件不工作了,可以在这里报告: webpack 5 alpha feedback · Issue #8537 · webpack/webpack 。完整的更新日志可以查看这里:webpack/changelog-v5。值得注意的是:Webpack 5 将不支持node 8以前的版本。
v 5版本主要集中在几个关键组件上:
- 使用持久化缓存提高构建性能;
- 使用更好的算法和默认值改进长期缓存(long-term caching);
- 清理内部结构而不引入任何破坏性的变化;
- 引入一些breaking changes,以便尽可能长的使用v5版本。
同样,这里是完整的更新日志,但一定要确保在配置更改之前进行阅读,以保持最新。
要测试 v5版本,你可以使用以下命令安装它:
npm install —save-dev webpack@next
这个命令引用了最新的 alpha 版本,但是你也可以使用以下命令通过 Webpack 的仓库中的tag使用v5开发中的版本:
npm install —save-dev webpack@v5.0.0-alpha.9
If you’re using Webpack v4 or later, you’ll also need to install the CLI:
如果你使用 Webpack v 4或更高版本,你还需要安装 CLI:
npm install --save-dev webpack-cli
废弃项目
V4中已弃用的所有项目已在 v5中删除。 当迁移到 v5时,请确保 Webpack 4版本不会打印弃用警告。 如果您遇到错误问题,请尝试省略 stats 选项或不使用预设。 尽管如此,事情仍然处于发布前的阶段,所以最好通过 GitHub 向 Webpack 团队咨询。
也有一些v4中没有被警告deprecation的变更,比如
IgnorrePlugin
和 BannerPlugin
,现在必须传递一个 options 对象。 下面是一个IgnorrePlugin
的示例,当前的文档似乎没有提到这一点:new webpack.IgnorePlugin({ resourceRegExp: regex })
参考资料:
- https://webpack.js.org/plugins/banner-plugin/#options
- https://webpack.js.org/plugins/ignore-plugin
Back in the day, Webpack’s aim was to allow for running most Node.js modules in the browser, but the module landscape changed and many module uses are now written specifically for front-end purposes. Versions <= 4 shipped with polyfills for a good majority of Node.js core modules that are automatically applied once a module uses any core modules.
过去,Webpack 的目标是允许在浏览器中运行大多数 Node.js 模块,但是模块版本发生了变化,许多模块的使用现在都是专门为前端目的而编写的。 4版本附带了大多数 Node.js 核心模块的 polyfills,一旦模块使用了任何核心模块,这些模块就会自动应用。
This, in turn, added these large polyfills to the final bundle but were generally unnecessary. The attempts in v5 are to automatically stop polyfilling these core modules and focuses on front-end compatible ones.
反过来,这又将这些大的多边填充添加到最后的捆绑包中,但通常是不必要的。 V5中的尝试是自动停止 polyfilling 这些核心模块,并侧重于前端兼容的模块。
When migrating to v5, it would be best to use front-end compatible modules when possible and manually add a polyfill for core modules when possible (error messages can help guide you). Feedback is appreciated/encouraged for the core team as this change may or may not make it into the final v5 release.
当迁移到 v5时,最好尽可能使用前端兼容的模块,并尽可能手动添加核心模块的多边形填充(错误消息可以帮助指导您)。 对于核心团队的反馈,我们表示感谢 / 鼓励,因为这个更改可能会也可能不会进入最终的 v5版本。
Deterministic chunk and module IDs
确定性块和模块 id
New algorithms have been added in order to assist with long term caching, and is enabled in production mode with the following configuration lines:
为了增强long-term caching,增加了新的算法,并在生产模式下使用以下配置开启:
chunkIds: "deterministic”,
moduleIds: “deterministic"
The algorithms assign very short (3 or 4 character) numeric IDs to modules and chunks in a deterministic way. This is a trade-off between bundle size and long-term caching. When migrating from v4 it is best to use the default values for
chunkIds
and moduleIds
. You can also opt-in to the old defaults from your config file:这些算法以确定性的方式为模块和数据块分配非常短(3或4个字符)的数字 id。 这是捆绑包大小和长期缓存之间的权衡。 从 v4迁移时,最好使用 chunkIds 和 moduleIds 的默认值。 你也可以从配置文件中选择旧的默认设置:
chunkIds: "size”,
moduleIds: “size"
These lines will generate smaller bundles but invalidate them more often for caching.
这些行将生成较小的 bundle,但由于缓存的原因,它们更经常地失效。
Reference
参考资料
- https://webpack.js.org/configuration/optimization/#optimization-moduleids
- https://webpack.js.org/configuration/optimization/#optimization-chunkids
命名块 id
A newly named chunk id algorithm is now enabled by default in development mode that gives chunks (and filenames) human-readable references. A Module ID is determined by its path that’s relative to the context. A Chunk ID is determined by the chunk’s content so you no longer need to use:
默认情况下,在开发模式中启用了一个新命名的块 id 算法,该算法提供块(以及文件名)可读的引用。 模块 ID 由其相对于上下文的路径确定。 块 ID 是由块的内容决定的,所以你不再需要使用:
import(/* webpackChunkName: "name" */ "module")
The line above can be used for debugging, but it also makes sense if you wanna control the filenames for production environments. It is possible to use
chunkIds: “named”
in production just make sure not to expose sensitive information regarding module names accidentally.上面的这一行可以用于调试,但是如果您想控制生产环境的文件名,这一行也是有意义的。 在产品中使用 chunkIds:"named"是可能的,只是确保不会意外地暴露有关模块名称的敏感信息。
optimization: { chunkIds: 'named' }
When migrating from v4 you might discover a dislike for filenames becoming altered in development mode. With that in mind you can pass the line below in order to use the old numeric mode from your config file.
当从 v4进行迁移时,您可能会发现不喜欢在开发模式下改变文件名。 考虑到这一点,您可以传递下面的一行,以便从配置文件中使用旧的数值模式。
chunkIds: “natural”
Reference
参考资料
- https://webpack.js.org/configuration/optimization/#optimization-chunkids
编译器
Compilers will be required to close after use as they now enter and leave idle states as well as possess hooks for these states. Plugins may use these hooks to do unimportant work (i. e. the persistent cache slowly stores the cache to disk). When the compiler closes all remaining work should be completed ASAP. A callback will then signal the closing has been completed.
编译器在使用后将被要求关闭,因为它们现在进入和离开空闲状态,并且拥有用于这些状态的钩子。 插件可以使用这些钩子来做一些不重要的工作(例如,持久缓存缓慢地将缓存存储到磁盘)。 当编译器关闭所有剩余的工作应尽快完成。 然后一个回调将标志着关闭已经完成。
Plugins and their respective authors should expect that some users may forget to close the Compiler so all work should eventually be in the process of finishing up while in idle. Processes should also be prevented from exiting while the work is in progress. The
webpack()
facade automatically calls to close
when passed a callback. When updating to v5 make sure while using the Node.js API to call Compiler.close
upon completion of your work.插件和它们各自的作者应该预料到一些用户可能会忘记关闭编译器,因此所有的工作最终应该在空闲时完成。 在工作进行期间,还应防止流程退出。 当传递回调时,webpack () facade 自动调用关闭。 在更新到 v5时,确保在使用 Node.js API 调用 Compiler.close 时完成工作。
Reference
参考资料
- https://webpack.js.org/api/compiler-hooks
和模块大小
Modules now have the ability to express size in a better way as opposed to displaying a single number and have different types of sizes. The
SplitChunksPlugin
is now aware of how to handle these different sizes and uses them for minSize
and maxSize
. By default, only javascript
size is handled, but you can now pass multiple values to manage them:模块现在能够以更好的方式表示大小,而不是显示单个数字和不同类型的大小。 Splugin 现在知道如何处理这些不同的大小,并将它们用于 minSize 和 maxSize。 默认情况下,只能处理 javascript 的大小,但是你现在可以传递多个值来管理它们:
minSize: {
javascript: 30000,
style: 50000,
}
When migrating to v5 make sure to check which types of sizes are used in your build. This can be configured with
splitChunks.minSize
and optionally in splitChunks.maxSize
.当迁移到 v5时,一定要检查在构建中使用了哪些类型的大小。 这可以配置为 splitChunks.minSize,也可以配置为 splitChunks.maxSize。
Reference
参考资料
- https://webpack.js.org/plugins/split-chunks-plugin
持久化缓存
In v5 you’ll find an experimental filesystem cache that’s an opt-in feature enabled using the following line in your Webpack config file:
在第5版中,你可以找到一个实验性的文件系统缓存,这个缓存是通过 Webpack 配置文件中的下面一行启用的 opt-In 功能:
cache: { type: "filesystem” }
Right now, only the core feature set is ready. But when using it you must be aware of the limitations in order to avoid unexpected bugs. If you don’t fully understand these limitations, you’re probably better off avoiding this feature entirely until you’re really comfortable.
现在,只有核心功能集已经准备就绪。 但是在使用它的时候,你必须意识到它的局限性,以避免意想不到的错误。 如果你不完全理解这些限制,你最好完全避免使用这个功能,直到你真正感到舒服为止。
You’ll also have an automatic cache invalidation for resolving module source code and filesystem structure, but there’s no automatic cache invalidations for configurations and loader/plugin/core changes. If you’d like to manually cache invalidation there’s an option that can be used in your config with
cache.version
. It isn’t fully ready yet at the moment but you can make everything run smoothly by updating your cache.version
when upgrading your tooling dependencies (webpack, loader, plugin) or when you change your configuration.您还可以通过自动缓存失效来解析模块源代码和文件系统结构,但是没有针对配置和 loader / plugin / core 更改的自动缓存失效。 如果您想手动缓存无效化,可以在 cache.version 配置中使用一个选项。 目前它还没有完全准备好,但是你可以在升级工具依赖项(webpack,loader,plugin)或者更改配置的时候通过更新 cache.version 来使一切运行顺利。
If you want to automate this, it might be best to hash
webpack.config.js
and node_modules/.yarn-integrity
and pass them to cache.version
and is likely how the Webpack team will do it internally.如果您希望自动化此操作,最好散列 webpack.config.js 和节点模块 / 。 然后将它们传递给 cache.version,这很可能就是 Webpack 团队在内部实现它的方式。
When using the Persistent Cache, you don’t need the
*cache-loader*
anymore. The same is also true for babel cacheDirectory
.当使用持久缓存时,不再需要缓存加载程序。 对于 babel cacheDirectory 也是如此。
Reference
参考资料
- https://webpack.js.org/configuration/other-options/#cache
配置更改
Since there are far too many config updates to list you can read all about the config changes via the v5 changelog.
因为要列出的配置更新太多了,所以你可以通过 v5 changelog 读取所有关于配置更新的信息。
Internal changes
内部变化
There are a handful of internal changes that are strictly relevant to plugin authors. You can read further about these internal changes should you need to reference them via the changelog.
有一些内部变化是严格相关的插件作者。 如果您需要通过更改日志引用这些内部更改,可以进一步阅读有关这些更改的内容。
Parting thoughts
离别的想法
Should you find an error that confuses or require further assistance make sure to file an issue with your question here or scroll through the comments posted by other developers as you may find an answer to your question before posting it.
如果你发现一个混淆或需要进一步帮助的错误,请务必将你的问题归档在这里,或者滚动浏览其他开发人员发布的评论,因为你可能会在发布之前找到问题的答案。
If you find something missing in the changelog make sure to help the team and report it here. Currently, every Webpack contributor has write access, and those who don’t are encouraged to send a pull request.
如果您发现更改日志中缺少某些内容,请务必帮助团队并在此报告。 目前,每个 Webpack 贡献者都有写访问权限,那些没有的人被鼓励发送一个拉请求。
Finally, make sure to try upgrading with the latest alpha version before reporting your issue as it may already be fixed. Happy bundling!
最后,确保在报告问题之前尝试升级最新的 alpha 版本,因为它可能已经被修复了。 捆绑快乐!
Helpful Links & Resources
有用的连结及资源
- https://github.com/webpack/webpack
- https://webpack.js.org/configuration
- https://webpack.js.org/concepts
推荐阅读
- 热闹中的孤独
- JS中的各种宽高度定义及其应用
- 我眼中的佛系经纪人
- 《魔法科高中的劣等生》第26卷(Invasion篇)发售
- Android中的AES加密-下
- 放下心中的偶像包袱吧
- C语言字符函数中的isalnum()和iscntrl()你都知道吗
- C语言浮点函数中的modf和fmod详解
- C语言中的时间函数clock()和time()你都了解吗
- 如何在Mac中的文件选择框中打开系统隐藏文件夹