首页 > 解决方案 > 将 svg-url-loader 与 Create React App 一起使用

问题描述

我正在使用 Create React App,我想将我的 SVG 内联作为数据 URI。

我知道 CRA 允许我将 SVG 作为组件导入和渲染,例如:

import { ReactComponent as Logo } from './logo.svg';
// <Logo />

而且我知道我可以获得 SVG 的 URL:

import Logo from './logo.svg';
// <img src={Logo} />

但我想做的是将 SVG 的内容嵌入为数据 URI,如下所示:

<img src="data:image/svg+xml;utf8,<svg>...</svg>">

我知道svg-url-loader可以做到这一点。所以我设置了它(使用Rescripts,因为 CRA 限制修改 Webpack 配置):

function addSvgLoader(config) {
  config.module.rules.push({
    test: /\.svg/,
    use: {
      loader: "svg-url-loader",
      options: {
        limit: 15000,
      },
    },
  });

  return config;
}

module.exports = [addSvgLoader];

有了这个,理论上,我应该能够使用上面的第二个示例,而不是获取指纹 URL,而是获取内联数据 URI。但是,指纹 URL 仍然呈现,SVG 文件的内容现在看起来像这样:

module.exports = "data:image/svg+xml,%3Csvg role='img' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 24V0h24v24H0zM ... [truncated] ... 03h-.52l-.23.02z'/%3E%3C/svg%3E"

我怀疑这是 CRA 的 loader 之间的冲突svg-url-loader,但我一直无法找到解决方案。如果有替代方案,svg-url-loader我也会考虑。

标签: reactjssvgwebpackcreate-react-app

解决方案


这确实是 CRA 的 svg 加载器与您尝试使用的加载器之间的冲突。但是,webpack 规则可以有一个oneOf部分,它将仅应用第一个匹配规则 - CRA 的 svg 规则在其中(我的版本是3.4.1)。

此外,规则的顺序很重要,您的规则应位于 CRA 定义的规则之前。

牢记这两点,我修改了 webpack 配置,如下所示:

let oneOfRule = config.module.rules.find((r) => r.oneOf);
oneOfRule.oneOf.splice(0, 0, {
  test: /\.svg$/,
  use: ['svg-url-loader'],
});

我用 svg-sprite-loader 而不是 svg-url-loader 对此进行了测试,但一般原理保持不变,它应该可以工作。


推荐阅读