我有一个盖茨比网站,消耗了很多包。其中一个包是由我们的monorepo发布的。@example/forms
. 该包包含了许多命名的出口,我们在网站上使用的每个表单组件都有一个。有相当多的表单,而且有些是相对复杂的多步骤表单,规模不小。
目前,GatsbyWebpack在树状结构方面做得很好,确实产生了大量的捆绑包,一些普通的捆绑包和网站每个页面的一个捆绑包,其中包含任何本地资产或只在该页面上使用的组件。然而,所有来自 @example/forms
正在增加的项目 commons
捆绑,尽管事实上大多数只在一个页面上使用。这造成了不必要的臃肿的 commons
捆绑,在每个页面上加载。
如果觉得应该可以让各个组件在 @example/forms
分成特定页面的捆绑包,但我不知道我的要求是否太高。例如,如果表格A只在第4页使用,我希望表格A只被添加到第4页的捆绑包中。
这是否是支持的,如果是,是什么原因阻止了这种情况的发生。
@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网站内使用,只是在不同的页面上使用。看来,也许树形抖动不能跨捆绑使用,即先进行树形抖动,然后将剩下的内容拆成捆绑。按照这个逻辑。@example/forms
会被用在多个页面上,并会被移到公共空间。然而这绝对不是最优的,希望不是现在的情况。
树形摇动过程是最小化步骤的一部分,实际上已经到了后期,因为它不可能颠倒顺序,先是树形摇动,然后是分块。
但是你可以在之前使用一些启发式方法来拆分你的表单库。
splitChunks
为了分割这个 @example/forms
模块作为一个单独的chunk,这将减少公共资源的膨胀& 在第一次使用表单时,所有的表单将被加载。// 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
模块,在我的例子中,我根据表单路径对所有项目进行了 "分组"。// 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.comfelixmoshwebpack-module-split-example。
希望能帮到你