svg - 在 NextJS 中,引用包含 SVG 的外部 npm 包时如何构建?

标签 svg webpack babeljs next.js

我的 nextjs 项目(我们称之为 TheHost) 引用了另一个 npm 包 (我们称之为 ThePackage)。

在 TheHost 中定义时,SVG 加载良好,但导入 ThePackage 失败,因为 next 尝试将 svg 解释为 javascript...所以我在执行 next build 时收到以下错误:

SyntaxError: Unexpected token '<'

重申一下,当引用 TheHost 本身定义的 svg 时,SVG 可以正常工作。问题似乎是导入包含 SVG 的 npm 包。

我是否从 ThePackage 中导入一个使用 SVG 的组件并不重要,只是在 npm 包中的某处包含一个“import xxx from '../path/to/svg' 就足以破坏 next build .

对于它的值(value),ThePackage 的转译 javascript 读取 svg 如下:
var _mysvg = require("../path/to/the-svg.svg");

很多细节:

下一个构建堆栈跟踪是:
> Using external babel configuration
> Location: "/Users/w/dev/TheHost/.babelrc"
Creating an optimized production build

Compiled successfully.

> Build error occurred
/Users/w/dev/TheHost/node_modules/ThePackage/build/assets/card_background.svg:1
<svg viewBox="0 0 860 382" fill="none" xmlns="http://www.w3.org/2000/svg">
^

SyntaxError: Unexpected token '<'
    at Module._compile (internal/modules/cjs/loader.js:895:18)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
    at Module.load (internal/modules/cjs/loader.js:815:32)
    at Function.Module._load (internal/modules/cjs/loader.js:727:14)
    at Module.require (internal/modules/cjs/loader.js:852:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/Users/w/dev/TheHost/node_modules/TheProject/build/card/style.js:14:47)
    at Module._compile (internal/modules/cjs/loader.js:959:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
    at Module.load (internal/modules/cjs/loader.js:815:32) {
  type: 'SyntaxError'
}
Automatically optimizing pages .%

.babelrc 文件:
{
  "presets": [
    "next/babel"
  ],
  "plugins": [
    "babel-plugin-styled-components",
    "inline-react-svg"
  ]
}

next.config.js 文件:
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";
      }
      config.module.rules.push({
        test: /\.svg$/,
        use: ["@svgr/webpack"]
      });
      return config;
    }
  })
);

nextjs svgr 包版本如下:
"next": "^9.2.1",
"next-images": "^1.3.0",
"@svgr/webpack": "^5.1.0",
"babel-eslint": "^10.0.3",
"babel-plugin-inline-react-svg": "^1.1.1",

ThePackage 使用以下输出配置(webpack)构建:
  entry: './src/index.js',
  output: {
    path: buildFolder,
    filename: 'ThePackage.js',
    library: 'ThePackage',
    libraryTarget: 'umd', /* Note: umd */
    umdNamedDefine: true
  },

最佳答案

NextJS 默认忽略 node_modules,因此您需要特别允许您的配置能够转译您的包。幸运的是,有人已经创建了一个 NextJS 插件来允许这样做:https://github.com/martpie/next-transpile-modules

我还建议使用 Next Compose Plugins 来整理配置。最后,您的 next.config.js 将如下所示:

const withSourceMaps = require("@zeit/next-source-maps");
const withImages = require("next-images");
const withPlugins = require('next-compose-plugins');
const withTM = require('next-transpile-modules')(['ThePackage']);

module.exports = withPlugins([
    withTM,
    [
        withImages,
        {
            exclude: /\.svg$/
        }
    ],
    withSourceMaps
],
{
    env: { *** redacted *** },
    publicRuntimeConfig: { *** redacted *** },
    webpack: (config, options) => {
      if (!options.isServer) {
        config.resolve.alias["@sentry/node"] = "@sentry/browser";
      }
      config.module.rules.push({
        test: /\.svg$/,
        use: ["@svgr/webpack"]
      });
      return config;
    }
});

我还排除了 withImages 处理 SVG。

关于svg - 在 NextJS 中,引用包含 SVG 的外部 npm 包时如何构建?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60300372/

相关文章:

javascript - SVG 路径转换为 ​​JSON

javascript - 如何将 Vuejs 中的仪表板模板集成到 Laravel 5.7 项目中

javascript - token '&&' 在此版本中不是有效的语句分隔符

javascript - Babel - 无法读取未定义的属性 'TYPED_ARRAY_SUPPORT'

javascript - 如何使用javascript在曲线上移动对象

html - 动画发光的 SVG 线条图不能跨浏览器工作

javascript - 当它可见时如何启动此动画?

javascript - webpack 缩小 HtmlWebpackPlugin

npm - 不兼容的 babel-loader 和 babel-core 版本