CRA:将特别大的模块提取到单独的块中?

CRA: Extract particularly big modules into separate chunks?

使用最新的 CRA。所有 node_modules 都捆绑到一个单独的块中,这很好。但是该块的大小仍然超过几兆字节。同时,我在 CRA 中看不到任何覆盖或自定义分块逻辑的选项。基本上,我想从 node_modules 块中提取特别大的模块,并将它们作为单独的块完全加载。不弹出可以吗?

是的,使用 React.Lazy 它会将特定组件与主要块分开。

const OtherComponent = React.lazy(() => import('./OtherComponent'));

Code-Splitting

如果您不想弹出,请参阅 react-app-rewired or use other services than CRA like Gatsby

正如 Dennis 提到的,React.lazy 是一个好方法。 但是,如果您想完全控制来自 node_modules 或实际上来自项目中任何地方的模块 - 请查看 webpack splitchunks

这将使您能够决定哪个模块转到哪个块。 一个简单的例子:

optimization: {
        splitChunks: {
            cacheGroups: {
                monaco_editor: {
                    test: /monceo-editor[\/]/,
                    name: 'monaco_editor',
                    maxSize: MaxChunkSize,
                    minSize: MinChunkSize
                },
            }
        }
    }

例如,这里我说的是将 monaco-editor 目录下的所有模块(文件)放入一个桶中 - 这个桶稍后将分成多个块,每个块的最小大小为 MinChunkSize,最大大小为MaxChunkSize.

vendor chunk是webpack自动添加的缓存组。 - 它从 node_modules 中提取所有未动态加载的模块并将它们放在一个块中。

您可以通过设置禁用此行为:

cacheGroups: {
    defaultVendors: null
}

您可以定义自己的 simple/complex node_modules 分布。您可以将某些包定义为始终转到某些块。这样,除非您升级其中一个软件包版本,否则块缓存不会更改 - 这是提高性能的好习惯,因为此缓存很可能来自缓存。

这是一个更复杂的例子,它对性能有好处:

optimization: {
        splitChunks: {
            cacheGroups: {
                myVendor: {
                    test: /node_modules[\/]/,
                    name(module) {
                        const matched = module.context.match(/[\/]node_modules[\/](.*?)([\/]|$)/);
                        const packageName = matched && matched.length > 2 ? matched[1] : undefined;

                        return packageName;
                    },
                    maxSize: MaxChunkSize,
                    minSize: MinChunkSize
                },
            }
        }
    }

在这个例子中,每个包都会被推送到它自己的桶中。现在桶将按 min/max 大小合并或拆分。