Next.js运行SVGR构建命令报错 TrustedHTML无法赋值给string类型
Turborepo下SVGR生成SVG组件生产构建TypeScript报错修复
问题原因
该报错是三类问题叠加导致:
- Next.js 12开发环境默认会跳过非直接引用资源的严格类型检查,对生成类产物做类型豁免,因此不会触发报错;生产构建时会执行全量TypeScript校验,会扫描到所有类型不兼容问题。
- SVGR默认生成的组件代码在React 18的
@types/react18.x版本下存在类型兼容问题,具名导入SVGProps未标记type导入的写法,会触发TS严格模式下的校验失败。 - 执行SVGR命令时将生成的TSX组件和原始SVG文件放在同一
./assets目录,TSC扫描时会将原始SVG文件作为未声明模块处理;如果构建脚本顺序错误(先执行类型检查再生成图标组件),会直接触发隐式any报错。另外Turborepo多包依赖下如果@types/react版本不统一,也会加剧类型冲突。
修复步骤
按顺序操作即可解决:
调整目录结构和SVGR命令
不要把生成产物和原始SVG混放,先将所有原始SVG文件统一移动到./assets/raw-svg目录,修改SVGR生成命令,将产物输出到源码目录的专属图标文件夹:svgr --typescript --no-dimensions --out-dir ./src/components/icons -- ./assets/raw-svg同时修改项目根目录
tsconfig.json,将原始资源目录加入排除列表,避免TSC扫描非代码文件:{ "exclude": ["node_modules", "./assets/raw-svg"] }修正SVGR生成代码的类型兼容问题
在项目根目录新建.svgrrc.js配置文件,自定义生成模板适配React 18的类型规则:module.exports = { template: (variables, { tpl }) => { return tpl` import * as React from 'react'; import type { SVGProps } from 'react'; const ${variables.componentName} = (props: SVGProps<SVGSVGElement>) => ( ${variables.jsx} ); export default ${variables.componentName}; ` } }配置中对
SVGProps使用type导入,修正了默认生成代码中类型导入的语法问题,完全匹配React 18的类型校验要求。调整构建脚本顺序
检查package.json中的脚本配置,必须保证先执行SVGR生成图标组件,再执行Next.js构建和类型检查,避免TSC找不到生成的组件文件报错,参考配置:{ "scripts": { "gen:icons": "svgr --typescript --no-dimensions --out-dir ./src/components/icons -- ./assets/raw-svg", "dev": "yarn gen:icons && next dev", "build": "yarn gen:icons && next build" } }统一Turborepo下的React类型版本
如果是Monorepo结构,在根目录package.json中添加resolutions字段,强制所有子包使用统一版本的React类型定义,避免多版本类型冲突:{ "resolutions": { "@types/react": "18.2.0", "@types/react-dom": "18.2.0" } }修改后执行
yarn install重新安装依赖,再执行构建命令即可。
不想修改SVGR配置的话,也可以直接在项目全局类型声明文件(
next-env.d.ts或自定义的global.d.ts)中添加兜底模块声明,跳过SVG组件的类型校验:import type { SVGProps } from 'react'; declare module '*.svg' { const component: React.FC<SVGProps<SVGSVGElement>>; export default component; }
内容的提问来源于stack exchange,提问作者Louis Charles
相关产品推荐
相关产品推荐

