For AI agents: the complete documentation index is available at /zh/llms.txt, the full documentation bundle is available at /zh/llms-full.txt, and this page is available as Markdown at /zh/guides/basic-features/static-assets/svg-assets.md.
  • 简体中文
  • 引用 SVG 资源

    Modern.js 支持在代码中引用 SVG 资源,并将 SVG 图片转换为 React 组件或 URL。

    什么是 SVG

    SVG 是 Scalable Vector Graphics 的缩写,意为可伸缩矢量图形。SVG 是一种用来描述二维矢量图形的 XML-based 格式,可以用来创建可以无限放大或缩小而不失真的图像。因为 SVG 图形是由矢量图形元素组成的,所以可以轻松地在各种尺寸和分辨率下渲染。

    在 JS 文件中引用

    默认导入

    如果你使用默认导入来引用 SVG,它会被当做静态资源来处理,你会得到一个 URL 字符串:

    src/component/Logo.tsx
    import logoURL from './static/logo.svg';
    
    console.log(logoURL); // => "/static/logo.6c12aba3.png"

    转换 React 组件

    在 JS 文件中引用 SVG 资源时,如果导入的路径包含 ?react 后缀,Modern.js 会调用 SVGR,将 SVG 图片转换为一个 React 组件:

    src/component/Logo.tsx
    import Logo from './logo.svg?react';
    
    export default () => <Logo />;

    Modern.js 也支持以下用法,通过具名导入 ReactComponent 来转换 SVG 为 React 组件:

    src/component/Logo.tsx
    import { ReactComponent as Logo } from './static/logo.svg';
    
    export default () => <Logo />;

    修改默认导出

    你可以通过 tools.svgr 的 svgrOptions.exportType 来修改 SVG 文件默认导出的内容,比如把默认导出的内容设置为 React 组件:

    export default {
      tools: {
        svgr: {
          svgrOptions: {
            exportType: 'default',
          },
        },
      },
    };

    旧的 output.svgDefaultExport 配置项仍然生效,但已废弃。

    此时再使用默认导入,你会得到一个 React 组件,而不是 URL:

    src/component/Logo.tsx
    import Logo from './static/logo.svg';
    
    export default () => <Logo />;

    在 CSS 文件中引用

    在 CSS 文件中引用 SVG 资源时,SVG 会被当做一个普通的静态资源来处理,你会得到一个 URL:

    .logo {
      background-image: url('../static/logo.svg');
    }

    静态资源处理

    当 SVG 不是作为 React 组件,而是作为一个普通的静态资源被引用时,它的处理逻辑和其他静态资源完全一致,也会受到静态资源内联、URL 前缀等规则的影响。

    请阅读 引用静态资源 章节来了解静态资源的处理规则。

    禁用 SVGR 处理

    默认情况下,在 JS 文件中引用 SVG 资源时,Modern.js 会调用 SVGR,将 SVG 图片转换为一个 React 组件。

    如果你确定项目内的所有 SVG 资源都没有当成 React 组件使用时,可以通过将 tools.svgr 设置为 false 来关闭此项转换,以提升构建性能。

    export default {
      tools: {
        svgr: false,
      },
    };

    添加类型声明

    当你在 TypeScript 代码中引用 SVG 资源时,TypeScript 可能会提示该模块缺少类型定义:

    TS2307: Cannot find module './logo.svg' or its corresponding type declarations.

    此时你需要为 SVG 资源添加类型声明文件,请在项目中创建 src/global.d.ts 文件,并添加相应的类型声明:

    declare module '*.svg' {
      export const ReactComponent: React.FunctionComponent<
        React.SVGProps<SVGSVGElement>
      >;
    
      const content: string;
      export default content;
    }
    
    declare module '*.svg?react' {
      const ReactComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
      export default ReactComponent;
    }

    如果你将 svgDefaultExport 设置为 'component',则将类型声明修改为:

    declare module '*.svg' {
      export const ReactComponent: React.FunctionComponent<
        React.SVGProps<SVGSVGElement>
      >;
    
      export default ReactComponent;
    }

    添加类型声明后,如果依然存在上述错误提示,请尝试重启当前 IDE,或者调整 global.d.ts 所在的目录,使 TypeScript 能够正确识别类型定义。

    修改 SVGR 配置

    当启用 SVGR 时,其默认配置如下:

    {
      svgo: true,
      svgoConfig: {
        plugins: [
          {
            name: 'preset-default',
            params: {
              overrides: {
                removeViewBox: false,
              },
            },
          },
          'prefixIds',
        ],
      },
    }

    如果需要修改 SVGR 配置,可通过 tools.svgr 的 svgrOptions 设置。传入的 svgoConfig.plugins 会按插件名与默认配置深度合并,因此只需写出要改动的部分:

    export default {
      tools: {
        svgr: {
          svgrOptions: {
            svgoConfig: {
              plugins: [
                {
                  name: 'preset-default',
                  params: {
                    overrides: {
                      // 在默认的 preset-default 之上追加一项 override
                      removeUselessDefs: false,
                    },
                  },
                },
              ],
            },
          },
        },
      },
    };