如何在 Next.js 组件中使用 SVG 图像?

Posted

技术标签:

【中文标题】如何在 Next.js 组件中使用 SVG 图像?【英文标题】:How to use SVG images inside a Next.js component? 【发布时间】:2019-10-10 20:11:17 【问题描述】:

next.config.js - 我添加了使用 SVG 图像所需的配置。

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(
      webpack(config, options) 
        return config;
      
    )
  )
);

这是我的 SVG 文件,位于下一个文件夹 /client/assets/googleIcon.svg

可能问题出在 SVG 文件中。我没有使用 SVG 的经验,这个 SVG 是否正确?

<svg version="1.1"   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>

最后我正在导入此文件并尝试以下列方式显示图像:

    googleIcon &lt;img src=googleIcon /&gt;

当我运行应用程序时,我收到以下错误:

./assets/googleIcon.svg 2:0
Module parse failed: Unexpected token (2:0)
You may need an appropriate loader to handle this file type.

【问题讨论】:

【参考方案1】:

您需要将withImages 嵌套到withSass 函数中。这就是为什么这些函数将config 作为参数。

如果您需要提供这些参数中的每一个,可以将它们组合成嵌套最多的函数参数。

module.exports = withCSS(
  withSass(
    withImages(
      distDir: '../_next',
      webpack(config, options) 
        return config;
      
    )
  )
);

【讨论】:

很好,我修复了那个错误,你知道为什么我会收到错误:“Invariant Violation: Invalid tag: data:image/svg+xml;base64”? @MarkJames 你不是在尝试第二种方法吗,&lt;img src=googleIcon /&gt; 我试过了,还是不行。现在 webpack 加载器没有问题。只是图像不显示。我收到警告消息实际上不是错误。 这很难判断,但是这个警告通常发生在base64图像直接在React中渲染时,像googleIcon这样的东西会导致它【参考方案2】:

我建议将您的 svg 包装在一个组件中,然后使用该组件:

function Icon () 
  return (
    <svg version="1.1"   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>
  )


ReactDOM.render(<Icon />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app" />

如果你真的需要加载 svg 作为图片,你需要配置你的 webpack。

npm install @svgr/webpack

然后:

module.exports = 
  webpack(config) 
    config.module.rules.push(
      test: /\.svg$/,
      use: ['@svgr/webpack'],
    );

    return config;
  
;

见this answer。

【讨论】:

我不能那样做,因为这张图片将在 aws S3 上发送,这就是为什么必须是 svg 文件的原因。 然后准确地回答你的问题。 我更新了我的答案,看看***.com/questions/55175445/… 问题是因为我无法显示 svg 图像。我安装了用于读取 svg 图像的模块。那是行不通的。【参考方案3】:

当我将esModule: false 添加到选项时,它会起作用。

config.module.rules.push(
  test: /\.(eot|woff|woff2|ttf|svg|png|jpg|gif)$/,
  use: 
    loader: 'url-loader',
    options: 
      limit: 100000,
      name: '[name].[ext]',
      esModule: false,
    ,
  ,
);

【讨论】:

以上是关于如何在 Next.js 组件中使用 SVG 图像?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以制作没有模糊的 Next.js Image 占位符?

(Next.js) 如何在 next/image 中更改 SVG 的颜色?

如何在 next.js 中获取图像宽度/高度?

如何使用 Next.js 将 PNG 徽标添加到 Tailwind CSS 导航栏?

如何从 Strapi API 引用 Next JS 中的图像组件?

如何在材质ui卡媒体中使用Next JS IMAGE