如何将 SVG 导入 Next.js 组件?

Posted

技术标签:

【中文标题】如何将 SVG 导入 Next.js 组件?【英文标题】:How to import SVG into Next.js component? 【发布时间】:2019-10-10 01:55:33 【问题描述】:

我正在尝试将 SVG 图像从文件导入 Next.js 组件。

在资产文件夹中我有 google.svg(图标):

<svg className="svgIcon-use"   viewBox="0 0 25 25">
    <g fill="none" fillRule="evenodd">
      <path
        d="M20.66 12.693c0-.603-.054-1.182-.155-1.738H12.5v3.287h4.575a3.91 3.91 0 0 1-1.697 2.566v2.133h2.747c1.608-1.48 2.535-3.65 2.535-6.24z"
        fill="#4285F4"
      />
      <path
        d="M12.5 21c2.295 0 4.22-.76 5.625-2.06l-2.747-2.132c-.76.51-1.734.81-2.878.81-2.214 0-4.088-1.494-4.756-3.503h-2.84v2.202A8.498 8.498 0 0 0 12.5 21z"
        fill="#34A853"
      />
      <path
        d="M7.744 14.115c-.17-.51-.267-1.055-.267-1.615s.097-1.105.267-1.615V8.683h-2.84A8.488 8.488 0 0 0 4 12.5c0 1.372.328 2.67.904 3.817l2.84-2.202z"
        fill="#FBBC05"
      />
      <path
        d="M12.5 7.38c1.248 0 2.368.43 3.25 1.272l2.437-2.438C16.715 4.842 14.79 4 12.5 4a8.497 8.497 0 0 0-7.596 4.683l2.84 2.202c.668-2.01 2.542-3.504 4.756-3.504z"
        fill="#EA4335"
      />
    </g>
  </svg>

我需要在 Next.js 组件的内部导入该 SVG:

import googleLogo from '../assets/google.svg';

class Login extends React.Component 
  render() 
    return (
      <LoginLayout title="Login Page">
        <div>
          <Link href="/auth/google">
            <a className="button">
              <div>
                <span className="svgIcon t-popup-svg">
                  googleLogo   // <---- import here icon
                </span>
                
              </div>
            </a>
          </Link>
        </div>
      </LoginLayout>
    );
  

我安装了这个包:https://www.npmjs.com/package/next-images

并根据next.config.js 中的文档设置配置:

const withCSS = require('@zeit/next-css');
const withSass = require('@zeit/next-sass');
const withImages = require('next-images');

module.exports = withCSS(
  withSass(
    webpack: (config) => config,
    distDir: '../_next'
  ),
  withImages(
    exclude: path.resolve(__dirname, 'client/assets/svg'),
    webpack(config, options) 
      return config;
    
  )
);

为什么我的 SVG 导入不起作用?

【问题讨论】:

为什么要在 webpack 配置中排除您尝试使用的 svg 文件夹? 那是错误的,我复制粘贴代码时并没有这样做。 在网上尝试了一些配置后,我发现很容易将 svg 图像的位置传递给从 'next/image' 导入的 img 标签或 &lt;Image /&gt; 【参考方案1】:

另一种方法是为您的 svg 创建一个组件。我喜欢这种方法,因为如果 svg 需要,我可以轻松地传递宽度、高度颜色等属性。

//GoogleLogo.js
import React from "react";
export default function GoogleLogo() 
  return (
    <svg className="svgIcon-use"   viewBox="0 0 25 25">
      <g fill="none" fillRule="evenodd">
        <path
          d="M20.66 12.693c0-.603-.054-1.182-.155-1.738H12.5v3.287h4.575a3.91 3.91 0 0 1-1.697 2.566v2.133h2.747c1.608-1.48 2.535-3.65 2.535-6.24z"
          fill="#4285F4"
        />
        <path
          d="M12.5 21c2.295 0 4.22-.76 5.625-2.06l-2.747-2.132c-.76.51-1.734.81-2.878.81-2.214 0-4.088-1.494-4.756-3.503h-2.84v2.202A8.498 8.498 0 0 0 12.5 21z"
          fill="#34A853"
        />
        <path
          d="M7.744 14.115c-.17-.51-.267-1.055-.267-1.615s.097-1.105.267-1.615V8.683h-2.84A8.488 8.488 0 0 0 4 12.5c0 1.372.328 2.67.904 3.817l2.84-2.202z"
          fill="#FBBC05"
        />
        <path
          d="M12.5 7.38c1.248 0 2.368.43 3.25 1.272l2.437-2.438C16.715 4.842 14.79 4 12.5 4a8.497 8.497 0 0 0-7.596 4.683l2.84 2.202c.668-2.01 2.542-3.504 4.756-3.504z"
          fill="#EA4335"
        />
      </g>
    </svg>
  );

从上方进入您的文件。

  import GoogleLogo from "./GoogleLogo";

  class Login extends React.Component 
    render() 
      return (
        <LoginLayout title="Login Page">
          <div>
            <Link href="/auth/google">
              <a className="button">
                <div>
                  <span className="svgIcon t-popup-svg">
                    <GoogleLogo />
                  </span>

                </div>
              </a>
            </Link>
          </div>
        </LoginLayout>
      );
    
  

【讨论】:

这是很棒的解决方案,我也喜欢。但是需要在diff方式上做。需要有 google.svg 文件,该文件将包含 svg 部分代码,并以这种方式导入。【参考方案2】:

我最近自己添加了这个。我按照 Next.js 存储库中的示例进行操作。

https://github.com/zeit/next.js/tree/master/examples/svg-components

有几个步骤 -

1) 你需要安装以下依赖:

babel-plugin-inline-react-svg

2) 在您的.babelrc 中,您需要添加插件babel-plugin-inline-react-svg

  "plugins": [
    "inline-react-svg",
  ]

然后您应该能够将您的 SVG 导入到您的组件中。这是我使用它的类似内容的要点。

https://gist.github.com/iamchristough/493c60112770058566d559e6860dc4c9

注意——你需要将它声明为自己的组件&lt;GoogleLogo /&gt;,如果你刚刚做了GoogleLogo,它会出错。 babel 转换 SVG 的方式也存在问题,因此 SVG 文件中的任何更改都不会出现。您需要重命名文件才能让捆绑程序看到更改。

希望这会有所帮助。

【讨论】:

cannot install "inline-react-svg" 这在 npm 注册表中不存在 我不认为svg-inline-react 是必要的,它不相关,没有一个包以任何方式相互提及。 顺便说一句,要点链接已失效。【参考方案3】:

您可以使用@svgr/webpack 插件将 svg 导入转换为 react 组件。

这将允许您执行以下操作:

import Icon from './icon.svg';

<Icon />

【讨论】:

如果你这样做,不要忘记在你的 webpack 配置中添加 @svgr/webpack 到 next.config.js【参考方案4】:

您可以使用 svgr 将 svg 转换为组件 https://github.com/gregberge/svgr

【讨论】:

SVGR + Next.js - 官方文档:react-svgr.com/docs/next

以上是关于如何将 SVG 导入 Next.js 组件?的主要内容,如果未能解决你的问题,请参考以下文章

将 next.js 添加到组件库中以使用 Next.js 功能

Next.js:如何将仅外部客户端的 React 组件动态导入到开发的服务器端渲染应用程序中?

如何使用 Next.js 在组件级别导入 SCSS

如何将 svg 文件导入 Vue 组件?

如何忽略 Next.js 组件中导致单元测试中的解析错误的 CSS 模块导入

如何将 svg 从文件导入 Angular 5 中的组件?