Next.js + Turbopack生产构建中导入SVG作为React组件时出现Element type is invalid错误
这个问题我之前用Turbopack搭配@svgr/webpack时也碰到过,开发模式一切正常,生产构建就炸出React #130错误,本质原因是生产构建时Turbopack对SVG的导出处理和开发模式不一致,导致你导入的不是直接的React组件,而是一个模块对象。
为什么会出现这个差异?
开发模式下,Turbopack的调试环境会做一些宽松兼容,比如自动解析模块的默认导出到你用的默认导入语句里。但生产构建时,为了优化打包体积和执行效率,Turbopack会严格按照配置的规则处理模块导出,你的现有配置没有明确告诉它要把@svgr生成的React组件作为默认导出暴露,结果就是你导入的ReloadIcon其实是一个包含default属性的模块对象,而不是直接的组件函数,React自然就报错说你渲染的不是有效组件。
修复方案(一步步来)
1. 修正Turbopack的SVG规则配置
首先调整next.config.ts里的Turbopack规则,明确指定导出格式和组件类型:
import type { NextConfig } from 'next'; const nextConfig: NextConfig = { turbopack: { rules: { '*.svg': { loaders: [ { loader: '@svgr/webpack', options: { icon: true, typescript: true, // 生成TSX格式的组件代码,匹配我们的as设置 }, }, ], as: '*.tsx', // 明确用TSX格式输出,和React组件类型匹配 exports: 'default', // 强制把生成的组件设为模块的默认导出 }, }, }, }; export default nextConfig;
这里的关键是exports: 'default'——它告诉Turbopack,把@svgr生成的组件直接作为模块的默认导出,这样你用import ReloadIcon from '...'时拿到的就是直接的组件,而不是模块对象。
2. 确保类型声明被TypeScript识别
检查你的tsconfig.json,确认svg.d.ts已经被包含在编译范围内,不然TypeScript可能还是会对SVG导入报错:
{ "compilerOptions": { // 你的其他编译配置 }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "svg.d.ts"] }
3. 清理缓存并重新构建生产版本
旧的构建缓存可能残留了错误的打包结果,先清空再重新构建:
# 删除缓存和旧构建文件 rm -rf .next node_modules/.cache # 构建生产版本并启动测试 next build next start
4. (兜底方案)临时调整导入语句
如果上面的配置还是没解决(比如Turbopack的某些版本有兼容问题),可以临时修改组件里的导入语句,显式获取默认导出:
// 替换原来的默认导入 import { default as ReloadIcon } from '@icons/menu/reload-icon.svg';
不过这个是治标不治本的方法,优先还是用配置修复。
额外检查:依赖版本兼容性
确保你安装的@svgr/webpack是最新稳定版,避免和当前Next.js/Turbopack版本不兼容:
npm install @svgr/webpack@latest # 用yarn或pnpm的话对应替换命令
按照上面的步骤操作后,生产构建里的SVG组件应该就能正常渲染了,不会再触发React的#130错误。
内容来源于stack exchange

