NextJS引用含SVG的外部npm包时构建失败的技术问询
解决Next.js引入外部npm包时SVG解析失败的问题
嘿,我之前也碰到过几乎一模一样的问题!本质原因是Next.js的webpack配置默认不会处理node_modules目录下的SVG文件,你自己项目里的SVG能正常加载,是因为next-images和@svgr/webpack的规则只作用于你项目自身的文件,而外部包ThePackage编译后用require引入SVG时,Next.js会把这个SVG当成JS模块去解析,自然就炸出<语法错误了——哪怕你没用到那个组件,webpack遍历依赖树的时候还是会加载到它。
下面给你几个可行的解决办法,按推荐程度排序:
方法1:修改webpack配置,让它处理ThePackage里的SVG
这是最直接的方案,调整你的next.config.js,明确告诉webpack要处理ThePackage目录下的SVG:
const withSourceMaps = require("@zeit/next-source-maps"); const withImages = require("next-images"); module.exports = withImages( withSourceMaps({ env: { *** redacted *** }, publicRuntimeConfig: { *** redacted *** }, webpack: (config, options) => { if (!options.isServer) { config.resolve.alias["@sentry/node"] = "@sentry/browser"; } // 先移除默认的SVG规则,避免和next-images的规则冲突 config.module.rules = config.module.rules.filter(rule => !(rule.test && rule.test.test('.svg')) ); // 添加新的SVG处理规则,同时包含项目自身和ThePackage的文件 config.module.rules.push({ test: /\.svg$/, include: [ __dirname, // 你自己的项目目录 /node_modules\/ThePackage/ // 指定要处理ThePackage里的SVG ], use: ["@svgr/webpack"] }); return config; } }) );
改完之后重新跑next build,应该就能正常编译了——webpack会把ThePackage里的SVG也转成React组件,不会再把它当JS解析。
方法2:调整ThePackage的打包配置(根源解决)
如果你有权限修改ThePackage的代码,那最好从源头解决:让ThePackage在打包时就把SVG转成React组件,而不是保留对SVG文件的引用。
在ThePackage的webpack配置里添加SVG处理规则:
module.exports = { // ...其他已有配置 module: { rules: [ // 新增SVG处理规则 { test: /\.svg$/, use: ['@svgr/webpack'] } ] } };
重新编译ThePackage后,它的输出文件里就会直接包含SVG转成的React组件,再也不会有requireSVG的语句,自然就不会触发Next.js的解析错误了。
方法3:临时绕过(仅适合测试)
如果只是临时想跑通项目,不想改配置,可以让webpack忽略ThePackage里的SVG,但这会导致对应的SVG无法显示,仅适合测试场景:
webpack: (config, options) => { // ...其他已有配置 // 只处理项目自身的SVG config.module.rules.push({ test: /\.svg$/, exclude: /node_modules\/ThePackage/, use: ["@svgr/webpack"] }); // 让webpack对ThePackage里的SVG返回空模块 config.resolve.fallback = { ...config.resolve.fallback, '../path/to/the-svg.svg': false // 替换成ThePackage里实际的SVG路径 }; return config; }
额外提醒
babel-plugin-inline-react-svg只处理你项目内的SVG导入,对node_modules里的文件无效,所以别指望它解决外部包的问题。- 你的Next.js 9.2.1和
next-images、@svgr/webpack的版本是兼容的,但后续升级Next.js时记得同步检查插件版本哦。
内容的提问来源于stack exchange,提问作者willem
相关产品推荐
相关产品推荐

