Webpack 代码拆分/延迟加载:为一个 npm 包的一个动态 import() 生成两个文件

Webpack Code Splitting / Lazy Loading: Two files generated for one dynamic import() of an npm package

我有一个与 Webpack 5 捆绑在一起的 Angular 12 应用程序,我在实施 Webpack 代码拆分/延迟加载时遇到了一些问题。

在我的 package.json 中,我有以下依赖项:

"crypto-js": "4.1.1"

到目前为止,在我的 Angular 代码中我使用了:

const CryptoJS = require('crypto-js');

当与 Webpack 捆绑时,我的 vendor.js 中包含了约 200kb 的 crypto-js 源代码。但是这个 vendor.js 现在已经变得如此庞大,以至于我想拆分我的代码并延迟加载 crypto-js(以及其他,但现在我只以 crypto-js 为例)。我只在我的应用程序的某个点需要那个第三方库,所以我开始使用:

import(/* webpackChunkName: 'crypto' */ 'crypto-js').then(CryptoJS => { ... });

我需要的地方。实际上这是有效的(crypto-js 不再在 vendor.js 中,它在我需要它的地方被延迟加载),但是有一个非常丑陋的行为:Webpack 生成两个文件: 文件 crypto.js(用魔术注释“webpackChunkName”定义)和文件 480.js。带有编号的文件包含 crypto-js 源代码,crypto.js 包含以下内容:

(self["webpackChunkclassroom"] = self["webpackChunkclassroom"] || []).push([[634],{

/***/ 42480:
/***/ (() => {

/* (ignored) */

/***/ })

}]);

当测试延迟加载时,两个文件都是从服务器加载的,这就是一切正常的原因。但是我有两个请求而不是一个请求,这是完全没有必要的,而且非常丑陋。此外,我什么都记不清了。

作为边标:

当我将 crypto-js.js 从节点模块文件夹复制到我的网络应用程序中的资产文件夹并导入此文件时:

import(/* webpackChunkName: 'crypto' */ '../../assets/crypto-js.js').then(CryptoJS => { ... });

然后一切都如我所愿。仅创建并延迟加载了一个文件“crypto.js”。

但我不想在我的资产文件夹中有 JavaScript 文件(因此我必须自己保持它们是最新的)。我想使用 package.json 和 NPM 的好处来使我的第三方库保持最新。

有人可以帮我解决我的问题吗?我做错了什么?

我成功了。

在 Webpack 配置中,我添加了以下 splitChunks 配置:

   optimization: {
       splitChunks: {
            cacheGroups: {
                defaultVendors: {
                    test: /[\/]node_modules[\/](?!crypto-js)/,
                    name: 'vendor',
                    chunks: 'all'
                }
            }
        }
    }

重要提示:

  • 我在测试正则表达式中排除了 NPM 包 crypto-js
  • cachedGroup 必须命名为 defaultVendors(否则一切都会失败)