简体   繁体   English

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

[英]How to use SVG images inside a Next.js component?

In next.config.js - I added config which is needed for using SVG images.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;
      }
    })
  )
);

And here is my SVG file, under next folders /client/assets/googleIcon.svg .这是我的 SVG 文件,在下一个文件夹/client/assets/googleIcon.svg

Maybe problem is in the SVG file.也许问题出在 SVG 文件中。 I don't have experience with SVG, is this SVG correct?我没有使用 SVG 的经验,这个 SVG 正确吗?

<svg version="1.1" width="100%" height="100%" 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>

And on the end I am importing this file and tried to show image in the followign ways:最后我导入这个文件并尝试以下列方式显示图像:

  1. {googleIcon}
  2. <img src={googleIcon} />

When I run the app I receive the following error:当我运行应用程序时,我收到以下错误:

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

I suggest to wrap your svg in a component, and then use the component:我建议将您的 svg 包装在一个组件中,然后使用该组件:

 function Icon () { return ( <svg version="1.1" width="100%" height="100%" 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" />

If you really need to load svg as image, you need to configure your webpack.如果你真的需要加载 svg 作为图像,你需要配置你的 webpack。

npm install @svgr/webpack

Then:然后:

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

    return config;
  }
};

See this answer .看到这个答案

You will need to nest the withImages into withSass function.您需要将withImages嵌套到withSass函数中。 This is why these functions take config as argument.这就是为什么这些函数将config作为参数。

If you need to provide each of these arguments, they can be combined into the most nested functions argument.如果您需要提供这些参数中的每一个,可以将它们组合成嵌套最多的函数参数。

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

When I add esModule: false to options it works.当我将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,
    },
  },
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM