Gatsby构建时出现SplitChunksPlugin异常错误求助
问题背景
使用Gatsby 4.24.0 + @loadable/component 5.15.3实现ArcGIS组件客户端渲染(避免SSR构建失败),通过gatsby-node.js批量生成地图页面。当/src/pages目录页面数超过6个时,执行gatsby build触发错误:
缓存组"shared"与现有chunk同名
380d42e81165839365c4703ae67985f785a96bdc且无父子关系
注释动态导入代码或页面数≤6时,构建可正常完成。
调试步骤(先定位chunk对应模块)
1. 开启Webpack详细构建日志
执行命令:
gatsby build --verbose
在输出日志中直接搜索chunk ID 380d42e81165839365c4703ae67985f785a96bdc,就能找到该chunk包含的具体模块文件路径。
如果日志不够详细,可在gatsby-node.js中添加Webpack配置,强制输出chunk关联信息:
exports.onCreateWebpackConfig = ({ actions, getConfig }) => { const config = getConfig(); config.stats = { chunks: true, chunkModules: true, chunkOrigins: true, }; actions.replaceWebpackConfig(config); };
重新执行构建,日志会清晰展示每个chunk对应的模块列表。
2. 分析冲突根源
- Gatsby默认Webpack配置中,
shared缓存组会自动提取多个页面的公共模块,但当批量生成的地图页面都引用同一个动态导入的ArcGIS组件时,可能和自动生成的公共chunk命名冲突。 - 检查
@arcgis/core是否被多个chunk重复引用,导致SplitChunks插件合并时出现命名冲突。
3. 修正动态导入的位置
目前代码中loadable定义在组件内部,每次组件渲染都会重新创建Loadable实例,可能导致Webpack重复打包。将动态导入移到组件外部:
import React from "react"; import Layout from "../components/layout"; import loadable from "@loadable/component"; interface MapProps { data: any; } // 移到组件外部,避免重复初始化 const LoadableArcGisMap = loadable(() => import("../components/arc/arc-gis-map")); const Map = ({ data }: MapProps) => { const map = data.strapiMap; return ( <Layout> <LoadableArcGisMap id={map.arcgisId} /> </Layout> ); };
这个修改能减少不必要的chunk生成,大概率能缓解冲突。
可能的修复方案
1. 自定义Webpack SplitChunks配置
在gatsby-node.js中修改缓存组规则,避免命名冲突:
exports.onCreateWebpackConfig = ({ actions, getConfig }) => { const config = getConfig(); config.optimization.splitChunks = { ...config.optimization.splitChunks, cacheGroups: { ...config.optimization.splitChunks.cacheGroups, // 重命名默认的shared缓存组,避免冲突 shared: { name: "custom-shared", chunks: "all", minChunks: 2, reuseExistingChunk: true, }, // 单独拆分@arcgis/core模块,避免和其他公共模块混编 arcgis: { test: /@arcgis\/core/, name: "arcgis-vendor", chunks: "all", priority: 10, enforce: true, }, }, }; actions.replaceWebpackConfig(config); };
2. 配置loadable组件的Babel插件
安装@loadable/babel-plugin:
npm install @loadable/babel-plugin --save-dev
然后在gatsby-config.js中添加Babel配置:
module.exports = { plugins: [ { resolve: `gatsby-plugin-babel`, options: { plugins: [`@loadable/babel-plugin`], }, }, ], };
该插件能帮助Webpack更高效地处理动态导入,减少chunk冲突概率。
3. 排查pages目录的公共依赖
检查pages目录新增的页面是否引入了其他公共模块,导致SplitChunks插件生成额外的公共chunk,和动态导入的chunk命名冲突。
内容的提问来源于stack exchange,提问作者Chris Lau

