我有一个 Gatsby 站点,它消耗了许多包。其中一个包是从我们的 monorepo 发布的:@example/forms
.该包包含许多命名导出,一个用于我们在网站上使用的每个表单组件。有相当多的表格,有些是相当复杂的多步表格,大小不一。
目前,Gatsby/Webpack 在 treeshaking 方面做得很好,并且确实生成了大量的包,一些常见的包和站点的每个页面都有一个包,包含仅在该页面上使用的任何本地 Assets 或组件。但是,来自 @example/forms
的所有组件正在添加到 commons
bundle ,尽管大多数只在一个页面上使用。这会导致 commons
不必要的膨胀。在每个页面上加载的 bundle 。
如果感觉 @example/forms
中的各个组件应该是可能的分成特定于页面的 bundle ,但我不确定我是否希望太多。例如,如果表格 A 仅用于第 4 页,我希望表格 A 仅添加到第 4 页的 bundle 中。
这是支持的东西吗?如果支持,是什么阻止了这种情况的发生。 @example/forms
与 ES6 导出保持原样进行转译,并且 sideEffects
设置为 false
在其package.json
.
其main
文件是 index.js
它将所有表单组件从它们自己的文件中(重新)导出为单独的命名导出:
export {default as FormA} from './forms/formA'
export {default as FormB} from './forms/formB'
...
可能相关的另一件事是
@example/forms
的所有导出在 Gatsby 网站中使用,只是在单独的页面上。似乎可能无法跨包使用 tree-shaking,即首先执行 tree-shaking,然后将剩下的拆分成 bundle。使用该逻辑,@example/forms
将在多个页面上使用,并将被移至公共(public)区域。然而,这绝对不是最佳的,希望不是正在发生的事情。
最佳答案
摇树过程是真正处于后期阶段的缩小步骤的一部分,因为不可能颠倒顺序,首先摇树然后分 block 。
但是您可以使用一些启发式方法预先拆分您的表单库
splitChunks
为了分割这个@example/forms
模块作为一个整体分成一个单独的 block ,这将减少公共(public)膨胀&在第一个表单使用时,所有表单都将被加载。 // webpack.config.js
module.exports = {
...
optimization: {
splitChunks: {
cacheGroups: {
formComponents: {
chunks: 'all',
enforce: true,
minChunks: 1,
name: 'form-components',
priority: 10,
test: /[\\\/]node_modules[\\\/]@example[\\\/]forms[\\\/]/,
},
},
},
},
...
};
@example/forms
中的每个表单创建一个 block 基于一些启发式的模块,在我的示例中,我根据表单路径“分组”所有项目。 // webpack.config.js
module.exports = {
...
optimization: {
splitChunks: {
cacheGroups: {
formComponents: {
chunks: 'all',
minChunks: 1,
name(module) {
const libPath = path.resolve(path.join('node_modules/@example/forms'))
const folderBasedChunk = path.relative(libPath, module.context);
const hash = crypto.createHash('sha1');
hash.update(folderBasedChunk)
return hash.digest('hex').substring(0, 8)
},
priority: 10,
reuseExistingChunk: true,
enforce: true,
test: /[\\\/]node_modules[\\\/]@example[\\\/]forms[\\\/]src[\\\/]forms[\\\/]/,
},
},
},
...
};
您可以查看我创建的一个模拟场景的小示例。
https://github.com/felixmosh/webpack-module-split-example
希望这可以帮助
关于javascript - 将包中的代码拆分单独导出到不同的包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62201836/