javascript - 使用 webpack 5 将 SVG 导入为 React 组件

标签 javascript reactjs svg babel-loader webpack-5

我想在我的应用程序中使用 SVG 作为 React 组件。
我正在使用: react 17.0.2、Webpack 5.57.1​​、@svgr/webpack 6.2.1。
我按照在 webpack.config 文件中添加 svgr 的步骤操作,如 svgr 文档 svgr-doc但是控制台开发工具中有一个错误:

react-dom.development.js:67 Warning: <data:image/svg+xml;base64,dmFyIF9wYXRoOwoKZnVuY3Rpb24gX2V4dGVuZHMoKSB7IF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTsgcmV0dXJuIF9leHRlbmRzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0KCmltcG9ydCAqIGFzIFJlYWN0IGZyb20gInJlYWN0IjsKCnZhciBTdmdDYWxlbmRhciA9IGZ1bmN0aW9uIFN2Z0NhbGVuZGFyKHByb3BzKSB7CiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KCJzdmciLCBfZXh0ZW5kcyh7CiAgICB4bWxuczogImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiwKICAgIHdpZHRoOiAxNiwKICAgIGhlaWdodDogMTYsCiAgICBmaWxsOiAiY3VycmVudENvbG9yIgogIH0sIHByb3BzKSwgX3BhdGggfHwgKF9wYXRoID0gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoInBhdGgiLCB7CiAgICBkOiAiTTExLjMzMyAyLjY2N0gxNGEuNjY3LjY2NyAwIDAgMSAuNjY3LjY2NlYxNGEuNjY3LjY2NyAwIDAgMS0uNjY3LjY2N0gyQS42NjcuNjY3IDAgMCAxIDEuMzMzIDE0VjMuMzMzQS42NjcuNjY3IDAgMCAxIDIgMi42NjdoMi42NjdWMS4zMzNINnYxLjMzNGg0VjEuMzMzaDEuMzMzdjEuMzM0ek0xMCA0SDZ2MS4zMzNINC42NjdWNGgtMnYyLjY2N2gxMC42NjZWNGgtMnYxLjMzM0gxMFY0em0zLjMzMyA0SDIuNjY3djUuMzMzaDEwLjY2NlY4eiIKICB9KSkpOwp9OwoKZXhwb3J0IHsgU3ZnQ2FsZW5kYXIgYXMgUmVhY3RDb21wb25lbnQgfTsKZXhwb3J0IGRlZmF1bHQgImRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEhOMlp3b2dJQ0FnSUNBZ0lIaHRiRzV6UFNKb2RIUndPaTh2ZDNkM0xuY3pMbTl5Wnk4eU1EQXdMM04yWnlJS0lDQWdJQ0FnSUNCM2FXUjBhRDBpTVRZaUNpQWdJQ0FnSUNBZ2FHVnBaMmgwUFNJeE5pSUtJQ0FnSUNBZ0lDQm1hV3hzUFNKamRYSnlaVzUwUTI5c2IzSWlDaUFnSUNBZ0lDQWdkbWxsZDBKdmVEMGlNQ0F3SURFMklERTJJZ28rQ2lBZ0lDQThjR0YwYUFvZ0lDQWdJQ0FnSUNBZ0lDQmtQU0pOTVRFdU16TXpJREl1TmpZM1NERTBZUzQyTmpjdU5qWTNJREFnTURFdU5qWTNMalkyTmxZeE5HRXVOalkzTGpZMk55QXdJREF4TFM0Mk5qY3VOalkzU0RKQkxqWTJOeTQyTmpjZ01DQXdNVEV1TXpNeklERTBWak11TXpNelFTNDJOamN1TmpZM0lEQWdNREV5SURJdU5qWTNhREl1TmpZM1ZqRXVNek16U0RaMk1TNHpNelJvTkZZeExqTXpNMmd4TGpNek0zWXhMak16TkhwTk1UQWdORWcyZGpFdU16TXpTRFF1TmpZM1ZqUm9MVEoyTWk0Mk5qZG9NVEF1TmpZMlZqUm9MVEoyTVM0ek16TklNVEJXTkhwdE15NHpNek1nTkVneUxqWTJOM1kxTGpNek0yZ3hNQzQyTmpaV09Ib2lMejRLUEM5emRtYysiOw== /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.
并且 SVG 不显示。
我无法将它作为 React 组件导入。
我的应用程序:
import React from 'react';
import ReactDOM from 'react-dom';

import CalendarIcon from './Calendar.svg'

const App = () => (
   <div>
       Test
       <CalendarIcon/>
   </div>
);

ReactDOM.render(<App />, document.getElementById('app'));

webpack 文件:
const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

const deps = require('./package.json').dependencies;

module.exports = {
  output: {
    filename: '[name].[contenthash:20].esm.js',
    chunkFilename: '[name].[chunkhash:20].esm.js',
    hashFunction: 'xxhash64',
    pathinfo: false,
    crossOriginLoading: false,
    clean: true,
    publicPath: 'auto',
  },

  resolve: {
    extensions: ['.tsx', '.ts', '.jsx', '.js', '.json'],
  },

  devServer: {
    port: 3011,
    historyApiFallback: true,
  },

  module: {
    rules: [
      {
        test: /\.m?js/,
        type: 'javascript/auto',
        resolve: {
          fullySpecified: false,
        },
      },
      {
        test: /\.(css|s[ac]ss)$/i,
        use: ['style-loader', 'css-loader', 'postcss-loader'],
      },
      {
        test: /\.(ts|tsx|js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
        },
      },
      {
        test: /\.svg$/i,
        issuer: /\.[jt]sx?$/,
        use: ['@svgr/webpack'],
      },
      {
        test: /\.(?:ico|gif|png|jpg|jpeg)$/i,
        type: 'asset/resource',
      },
      {
        test: /\.(woff(2)?|eot|ttf|otf|svg|)$/,
        type: 'asset/inline',
      },
    ],
  },
  plugins: [
    new ModuleFederationPlugin({
      name: 'sidebar',
      filename: 'remoteEntry.js',
      remotes: {},
      exposes: {
        './SideBar': './src/components/Sidebar/index.tsx',
      },
      shared: {
        ...deps,
        react: {
          singleton: true,
          requiredVersion: deps.react,
        },
        'react-dom': {
          singleton: true,
          requiredVersion: deps['react-dom'],
        },
      },
    }),
    new HtmlWebPackPlugin({
      template: './src/index.html',
    }),
  ],
};
babelrc 文件:
{
  "presets": ["@babel/preset-typescript", "@babel/preset-react", "@babel/preset-env"],
  "plugins": [
    ["@babel/transform-runtime"],
    "babel-plugin-styled-components"
  ]
}

最佳答案

从你的 webpack rules配置,看起来您与最后一条规则的名称冲突 type: "asset/inline" ,它也根据您的 test 处理 svg案子。
要解决此问题,您可以删除 svg在最后一条规则中,使其变为

test: /\.(woff(2)?|eot|ttf|otf|)$/,
或者您可以配置 webpack 以使用带有附加约束的两个规则,如 in the SVGR docs. 所述如果您在应用程序的其他位置需要文件内容,建议您这样做。为此,添加
resourceQuery: /url/, // *.svg?url
到最后一条规则和
resourceQuery: { not: [/url/] }, // exclude react component if *.svg?url
致您的@svgr/webpack规则。

关于javascript - 使用 webpack 5 将 SVG 导入为 React 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71820229/

相关文章:

SVG:内部模式的非缩放笔划不起作用?

android - 从适配器中的 Assets 文件夹添加 SVG 图像

javascript - ASP.NET MVC 3 单页应用程序使用 Javascript/jQuery AJAX : Memory and Detached DOM Issues

javascript - 直接从 firebase rtdb 获取数据时出现 TypeError : Cannot read property 'setState' of null,

svg - viewBox 中的描边宽度

reactjs - useState加载在异步之前不更新

javascript - 理智错误 : `dataset` must be provided to perform queries with React

javascript - recharts 在 MultiBarChart 中沿 Y 轴的每个条形图添加关闭按钮以关闭条形图

php - 将js文件另存为php

javascript - 加载时修改模态窗口中的数据