无法将 SVG 导入 Next.js

新手上路,请多包涵

当我尝试导入 SVG 图像时,会显示以下错误。我必须使用哪个加载器来导入 SVG 图像?

 ./static/Rolling-1s-200px.svg 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2000 2000"><filter id="b"><feGaussianBlur stdDeviation="12" /></filter><path fill="#817c70" d="M0 0h2000v2000H0z"/><g filter="url(#b)" transform="translate(4 4) scale(7.8125)" fill-opacity=".5"><ellipse fill="#000210" rx="1" ry="1" transform="matrix(50.41098 -3.7951 11.14787 148.07886 107 194.6)"/><ellipse fill="#eee3bb" rx="1" ry="1" transform="matrix(-56.38179 17.684 -24.48514 -78.06584 205 110.1)"/><ellipse fill="#fff4bd" rx="1" ry="1" transform="matrix(35.40604 -5.49219 14.85017 95.73337 16.4 123.6)"/><ellipse fill="#79c7db" cx="21" cy="39" rx="65" ry="65"/><ellipse fill="#0c1320" cx="117" cy="38" rx="34" ry="47"/><ellipse fill="#5cb0cd" rx="1" ry="1" transform="matrix(-39.46201 77.24476 -54.56092 -27.87353 219.2 7.9)"/><path fill="#e57339" d="M271 159l-123-16 43 128z"/><ellipse fill="#47332f" cx="214" cy="237" rx="242" ry="19"/></g></svg>

原文由 Shifut Hossain 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.6k
2 个回答

您需要提供一个处理 SVG 导入的 webpack 加载器,其中一个著名的就是 svgr

为了将其配置为使用 next,您需要将加载程序的用法添加到您的 next.config.js 文件中,如下所示:

 // next.config.js

module.exports = {
  webpack(config) {
    config.module.rules.push({
      test: /\.svg$/,
      issuer: {
        test: /\.(js|ts)x?$/,
       // for webpack 5 use
       // { and: [/\.(js|ts)x?$/] }
      },

      use: ['@svgr/webpack'],
    });

    return config;
  },
};

有关更多配置信息, 请查看文档

别忘 了先安装 @svgr/webpack

 $ npm install --save-dev @svgr/webpack

编辑

我添加了一个 issuer 部分,该部分仅将这些 svg 作为组件严格用于从 js / ts 文件导入的 svg。这允许您为从其他文件类型(例如 .css )导入的 svg 配置其他行为

原文由 felixmosh 发布,翻译遵循 CC BY-SA 4.0 许可协议

快捷方式: <img><Image>

不适用于交互式 SVG 或者如果您打算通过外部 CSS/JS 操作 SVG

可以使用官方 next/image 组件或 img 标签(如本 答案 中所述)。

您只需要将 svg 文件移动到 public 而不是 static ,然后执行如下操作:

 import Image from 'next/image';

// ...

<Image src="/Rolling-1s-200px.svg" width="2000" height="2000" />

但是通过使用这种方法, svg 文件的内容将不会直接出现在响应中;浏览器将获得一个 <img src="..." ...></img> 标签。

还需要指定 widthheight ,但您可以从 viewbox 属性计算。

在 Next.js v11 及更高版本上,您还可以执行以下操作:

 import Image from 'next/image';

import Illustration from '../static/Rolling-1s-200px.svg';

// ...

<Image src={Illustration} />

// one needs to use `Illustration.src` to get the source URL
// <img src={Illustration.src} ... />


在 HTML 中包含 SVG(适用于 webpack-5、TS)

接受的答案 显示了如何使用 webpack-4 执行此操作,但由于 webpack-5 现在是默认设置,我正在共享适当的配置。您可以在安装后使用它 @svgr/webpackyarn add -D @svgr/webpacknpm install @svgr/webpack --save-dev ):

 // next.config.js
// https://github.com/gregberge/svgr/issues/551#issuecomment-839772396

module.exports = {
  // other configs...

  // future: { webpack5: true }, // -- not needed since Next.js v11.0.0
  webpack(config) {
    config.module.rules.push({
      test: /\.svg$/i,
      issuer: { and: [/\.(js|ts|md)x?$/] },
      use: [
        {
          loader: '@svgr/webpack',
          options: {
            prettier: false,
            svgo: true,
            svgoConfig: { plugins: [{ removeViewBox: false }] },
            titleProp: true,
          },
        },
      ],
    });
    return config;
  },
};

如果您没有使用 options 作为加载器,那么您可以简单地这样写:

 use: ['@svgr/webpack']

如果您使用的是 @svgr/webpack 的 v6,那么您需要像这样指定 SVGO 配置:

 // ...

plugins: [
  {
    name: 'preset-default',
    params: {
      overrides: { removeViewBox: false },
    },
  },
],

// ...

如果使用打字稿,您需要定义适当的模块(在您导入的目录中 svg ,或者可能将其添加到根目录中 <some-name>.d.ts 并包含它 tsconfig ):

 // index.d.ts

declare module '*.svg' {
  const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
  export default ReactComponent;
}

然后你可以像这样使用它:

 import Illustration from '../static/Rolling-1s-200px.svg';

// ...

<Illustration />

注意:Next.js v11.0.1+ 已将 SVG 声明为模块导出 any 。您的自定义配置不会覆盖 next-env.d.ts 设置的类型,除非您排除后者。请参考 这个

[ 过时(已 修复 ]更新:

如果您使用的是 Next.js v11.0.0,那么您在导入 SVG 时可能会遇到错误。请更新至 v11.0.1 或更高版本。请遵循 此评论 中提到的解决方法。

原文由 brc-dd 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题