【问题标题】:SVG files are emitted, but appear to be corrupted in a single-spa react module. How to load SVG files in single-spa projects?发出 SVG 文件,但在单水疗反应模块中似乎已损坏。如何在单水疗项目中加载 SVG 文件?
【发布时间】:2021-11-30 06:25:46
【问题描述】:

我正在为模块化 React 应用程序使用 single-spa。我正在使用 Typescript、Webpack 和 svg-url-loader。 SVG 似乎已生成并呈现([hash].svg),但未正确加载(您看不到图像,只是一个占位符)。

这是我的 Webpack 配置:

module.exports = (webpackConfigEnv, argv) => {
  const defaultConfig = singleSpaDefaults({
    orgName: "Daboo1998",
    projectName: "react-module",
    webpackConfigEnv,
    argv,
  });

  return merge(defaultConfig, {
    // modify the webpack config however you'd like to by adding to this object
    module: {
      rules: [
        {
          test: /\.svg$/,
          use: [
            {
              loader: 'svg-url-loader',
              options: {
                limit: 10000000,
              },
            },
          ],
        },
      ]
    }
  });
};

这就是 SVG 声明:

declare module "*.svg" {
  const src: string;
  export default src;
}

以及我如何使用它:

import homeIcon from "./icons/house-4.svg";

...
<img src={homeIcon} />

我做错了什么?如果需要更多信息,请发表评论!

【问题讨论】:

  • 不要使用反应。 ;)

标签: reactjs typescript svg webpack single-spa


【解决方案1】:

由于它在svg(标量矢量图形)中,所以它本身就是一个图像,不需要进入src属性,你可以自己渲染homeIcon。

对于这种情况,我建议您将 Homeicon 创建为组件 (homeIcon.tsx),如下所示(我的示例是使用 EllipsisIcon):

import React from "react";

const EllipsisIcon = () => {
    return (
        <svg
            aria-hidden="true"
            focusable="false"
            data-prefix="fal"
            data-icon="ellipsis-v"
            className="svg-inline--fa fa-ellipsis-v fa-w-2"
            role="img"
            xmlns="http://www.w3.org/2000/svg"
            viewBox="0 0 64 512"
        >
            <path
                fill="currentColor"
                d="M32 224c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zM0 136c0 17.7 14.3 32 32 32s32-14.3 32-32-14.3-32-32-32-32 14.3-32 32zm0 240c0 17.7 14.3 32 32 32s32-14.3 32-32-14.3-32-32-32-32 14.3-32 32z"
            ></path>
        </svg>
    );
};

export default EllipsisIcon;

为了实现它,你将它作为一个普通组件导入并像往常一样在返回中使用它。 从“...”导入 EllipsisIcon 在需要的地方使用它

【讨论】:

    【解决方案2】:

    你可以使用img 元素和 webpack file-loader 显示 SVG,假设你使用的 webpack 低于 5。执行 npm install file-loader --save-dev 并添加到 webpack 配置中的规则数组

     {
        test: /\.(png|jpe?g|gif|svg)$/i,
        use: [
          {
            loader: 'file-loader',
          },
        ],
      },
    

    使用img 元素对 SVG 资产进行样式设置可能会很棘手,因此您最好创建一个反应组件来为您呈现 SVG,如 @Nacho 所述

    【讨论】:

      【解决方案3】:

      React 通常支持 svg 并且不需要 webpack 编辑。

      您可以在src文件夹中定义Svg's

      例如:eye.svg

      
      <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
          <path d="M15.75 12C15.75 12.9946 15.3549 13.9484 14.6517 14.6517C13.9484 15.3549 12.9946 15.75 12 15.75C11.0054 15.75 10.0516 15.3549 9.34835 14.6517C8.64509 13.9484 8.25 12.9946 8.25 12C8.25 11.0054 8.64509 10.0516 9.34835 9.34835C10.0516 8.64509 11.0054 8.25 12 8.25C12.9946 8.25 13.9484 8.64509 14.6517 9.34835C15.3549 10.0516 15.75 11.0054 15.75 12Z" />
          <path fill-rule="evenodd" clip-rule="evenodd" d="M0 12C0 12 4.5 3.75 12 3.75C19.5 3.75 24 12 24 12C24 12 19.5 20.25 12 20.25C4.5 20.25 0 12 0 12ZM12 17.25C13.3924 17.25 14.7277 16.6969 15.7123 15.7123C16.6969 14.7277 17.25 13.3924 17.25 12C17.25 10.6076 16.6969 9.27226 15.7123 8.28769C14.7277 7.30312 13.3924 6.75 12 6.75C10.6076 6.75 9.27226 7.30312 8.28769 8.28769C7.30312 9.27226 6.75 10.6076 6.75 12C6.75 13.3924 7.30312 14.7277 8.28769 15.7123C9.27226 16.6969 10.6076 17.25 12 17.25Z" />
      </svg>
          
      

      注意:使用currentColor 进行更改

      使用ReactComponents 使用svg

      import {ReactComponents as EyeSvg} from '...';
      
      const Component = () => {
          return (
              <button
                  style={{ color: "red" }}
              >
                  <EyeSvg width="18" height="18" />
              </button>
          );
      }
      
      export default Component;
      

      如果您更改您的webpack.config.js

                  // "url" loader works like "file" loader except that it embeds assets
                  // smaller than specified limit in bytes as data URLs to avoid requests.
                  // A missing `test` is equivalent to a match.
                  {
                    test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
                    loader: require.resolve('url-loader'),
                    options: {
                      limit: imageInlineSizeLimit,
                      name: 'static/media/[name].[hash:8].[ext]',
                    },
                  },
                  // Process application JS with Babel.
                  // The preset includes JSX, Flow, TypeScript, and some ESnext features.
                  {
                    test: /\.(js|mjs|jsx|ts|tsx)$/,
                    include: paths.appSrc,
                    loader: require.resolve('babel-loader'),
                    options: {
                      customize: require.resolve(
                        'babel-preset-react-app/webpack-overrides'
                      ),
                      presets: [
                        [
                          require.resolve('babel-preset-react-app'),
                          {
                            runtime: hasJsxRuntime ? 'automatic' : 'classic',
                          },
                        ],
                      ],
                      
                      plugins: [
                        [
                          require.resolve('babel-plugin-named-asset-import'),
                          {
                            loaderMap: {
                              svg: {
                                ReactComponent:
                                  '@svgr/webpack?-svgo,+titleProp,+ref![path]',
                              },
                            },
                          },
                        ],
                        isEnvDevelopment &&
                          shouldUseReactRefresh &&
                          require.resolve('react-refresh/babel'),
                      ].filter(Boolean),
                      // This is a feature of `babel-loader` for webpack (not Babel itself).
                      // It enables caching results in ./node_modules/.cache/babel-loader/
                      // directory for faster rebuilds.
                      cacheDirectory: true,
                      // See #6846 for context on why cacheCompression is disabled
                      cacheCompression: false,
                      compact: isEnvProduction,
                    },
                  },
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多