如何在没有供应商拆分的情况下加载动态块
How to load dynamic chunk without vendors splitting
快速总结
如何在不生成额外的 vendors~
前缀块的情况下动态导入 NPM 模块?
详情
设置
webpack.config.js
const path = require("path");
module.exports = [{
mode: "development",
entry: path.resolve(__dirname, "js/index.js"),
}];
index.js
__webpack_public_path__ = "dist/";
loadMoment();
function loadMoment() {
return require.ensure(
"moment-timezone",
require => {
console.log("moment loaded");
window.MY_GLOBAL = {
moment: require("moment-timezone"),
};
},
() => {},
"lib/moment",
);
/*
// Working on an existing project with an older version of ESLint, so the preferred import()
// trips up the linter. Using the older require.ensure to avoid linter errors, but I tested
// with async/await and import() and I get the same result.
window.MY_GLOBAL = {
moment: await import(
/* webpackChunkName: "lib/moment" * /
"moment-timezone"
),
};
*/
}
结果
这是我目前得到的不想要的结果:
dist/
lib/
moment.js
vendors~lib/
moment.js
请注意,有 2 个 moment.js
个文件!
lib/moment.js
是 16 kb,当我检查它时,只包含 ./node_modules/moment/locale
模块
vendors~lib/moment.js
是 938kb,当我检查它时,包含超过 130 个模块。所以,基本上,所有的时刻和时刻时区模块。
想要的结果:
dist/
lib/
moment.js
我想将我所有的 NPM 模块以及我可能想要加载的任何其他内容保存在一个块中,按照我指定的方式命名,没有任何自动前缀。
更多背景
我正在处理一个旧项目,该项目之前 copy/pasted 将整个缩小的时刻和时刻时区库放入名为“lib/moment.js”的 JS 资源中。我想从我们的代码库中删除它们并通过动态导入生成“lib/moment.js”文件。保留现有的文件名和文件夹结构很重要。
动态导入代码看起来很简单 (webpack documentation),但我没能找到任何关于 vendors~
前缀或如何删除它的解释。当然,我可以在示例中看到它,但据我所知,该前缀从未直接提到过。
如果我不能摆脱前缀并将所有内容捆绑到 lib/moment
块中,那么我将不得不放弃这种方法并继续使用存储在 lib 文件中的缩小库(这并不理想)。
TL;DR
简而言之,你需要禁用 defaultVendors
缓存组(或 vendors
之前的 webpack 5):
webpack.config.js
const path = require("path");
module.exports = [{
mode: "development",
entry: path.resolve(__dirname, "js/index.js"),
// ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
optimization: {
splitChunks: {
cacheGroups: {
defaultVendors: false,
// prior to webpack 5:
//vendors: false,
},
},
},
// ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
}];
现在怎么办?
Webpack 提供了一个 default configuration for the optimization.splitChunks
property which includes a simple "defaultVendors" rule (or "vendors" in v4) 将 NPM 模块拆分成一个单独的块:
cacheGroups: {
defaultVendors: {
test: /[\/]node_modules[\/]/,
priority: -10,
reuseExistingChunk: true,
},
},
根据文档,如果您不想使用这些默认缓存组,则 you have to explicitly set them to false
:
To disable any of the default cache groups, set them to false
.
要禁用供应商缓存组,只需在您的 webpack 配置中将其设置为 false
:
cacheGroups: {
defaultVendors: false,
},
结果
dist/
lib/
moment.js
快速总结
如何在不生成额外的 vendors~
前缀块的情况下动态导入 NPM 模块?
详情
设置
webpack.config.js
const path = require("path");
module.exports = [{
mode: "development",
entry: path.resolve(__dirname, "js/index.js"),
}];
index.js
__webpack_public_path__ = "dist/";
loadMoment();
function loadMoment() {
return require.ensure(
"moment-timezone",
require => {
console.log("moment loaded");
window.MY_GLOBAL = {
moment: require("moment-timezone"),
};
},
() => {},
"lib/moment",
);
/*
// Working on an existing project with an older version of ESLint, so the preferred import()
// trips up the linter. Using the older require.ensure to avoid linter errors, but I tested
// with async/await and import() and I get the same result.
window.MY_GLOBAL = {
moment: await import(
/* webpackChunkName: "lib/moment" * /
"moment-timezone"
),
};
*/
}
结果
这是我目前得到的不想要的结果:
dist/
lib/
moment.js
vendors~lib/
moment.js
请注意,有 2 个 moment.js
个文件!
lib/moment.js
是 16 kb,当我检查它时,只包含./node_modules/moment/locale
模块vendors~lib/moment.js
是 938kb,当我检查它时,包含超过 130 个模块。所以,基本上,所有的时刻和时刻时区模块。
想要的结果:
dist/
lib/
moment.js
我想将我所有的 NPM 模块以及我可能想要加载的任何其他内容保存在一个块中,按照我指定的方式命名,没有任何自动前缀。
更多背景
我正在处理一个旧项目,该项目之前 copy/pasted 将整个缩小的时刻和时刻时区库放入名为“lib/moment.js”的 JS 资源中。我想从我们的代码库中删除它们并通过动态导入生成“lib/moment.js”文件。保留现有的文件名和文件夹结构很重要。
动态导入代码看起来很简单 (webpack documentation),但我没能找到任何关于 vendors~
前缀或如何删除它的解释。当然,我可以在示例中看到它,但据我所知,该前缀从未直接提到过。
如果我不能摆脱前缀并将所有内容捆绑到 lib/moment
块中,那么我将不得不放弃这种方法并继续使用存储在 lib 文件中的缩小库(这并不理想)。
TL;DR
简而言之,你需要禁用 defaultVendors
缓存组(或 vendors
之前的 webpack 5):
webpack.config.js
const path = require("path");
module.exports = [{
mode: "development",
entry: path.resolve(__dirname, "js/index.js"),
// ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
optimization: {
splitChunks: {
cacheGroups: {
defaultVendors: false,
// prior to webpack 5:
//vendors: false,
},
},
},
// ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
}];
现在怎么办?
Webpack 提供了一个 default configuration for the optimization.splitChunks
property which includes a simple "defaultVendors" rule (or "vendors" in v4) 将 NPM 模块拆分成一个单独的块:
cacheGroups: {
defaultVendors: {
test: /[\/]node_modules[\/]/,
priority: -10,
reuseExistingChunk: true,
},
},
根据文档,如果您不想使用这些默认缓存组,则 you have to explicitly set them to false
:
To disable any of the default cache groups, set them to
false
.
要禁用供应商缓存组,只需在您的 webpack 配置中将其设置为 false
:
cacheGroups: {
defaultVendors: false,
},
结果
dist/
lib/
moment.js