如何使用 webpack 设置内联 svg

问题描述 投票:0回答:10

我想知道如何使用 webpack 设置内联 svg?

我正在关注 react-webpack-cookbook

我已使用 文件加载器正确设置了 webpack.config

但是该示例显示使用如下背景图像:

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

工作正常,但我想要一个内联 svg 图像,如何才能将我的 logo.svg 内联包含在我的 React 组件中?

import React, { Component } from 'react'

class Header extends Component {

  render() {
    return (
        <div className='header'>
            <img src={'./logo.svg'} />
        </div>
    );
  }
};

export default Header
javascript svg reactjs webpack loader
10个回答
40
投票

这是一个简单的非反应解决方案。

  1. 安装Svg内联加载器
  2. 在 webpack.config.js 中添加
    { test: /\.svg$/, loader: 'svg-inline-loader' }
  3. 在你的js文件中导入svg图像并将其添加到DOM元素中
  import Svg from './svg.svg';

  function component() {
    const element = document.createElement('div');

    element.innerHTML = Svg;

    return element;
  }

  document.body.appendChild(component());

36
投票

实际上 Michelle 的回答为我指明了正确的方向,这对于使用 webpack 加载 svg 文件并将其用作您的

<img>
src 来说非常有效

但是要真正获得内联 svg,我需要执行以下操作:

使用

svg-inline-loader 作为您的 svg 加载器,而不是文件加载器:

{ test: /\.svg$/, loader: 'svg-inline-loader' }



然后将 svg 内联加载到组件中:

import React, { Component } from 'react' import logo from "./logo.svg"; class Header extends Component { render() { return ( <div className='header'> <span dangerouslySetInnerHTML={{__html: logo}} /> </div> ); } }; export default Header

看起来有一个用于反应的内联 svg 包装器

svg-inline-react 这将是另一种选择,而不是 <div dangerouslySetInnerHTML={{__html: mySvg}} />


    


33
投票
我希望我迟来的答案对某人仍然有用,因为我不喜欢上述任何选项。

react-svg-loader webpack 加载器允许您导入 SVG 图标,如 JSX 组件:

import Logo from './logo.svg'; class App extends Component { render() { return ( <div className="App"> <Logo fill="red" className="logo" width={50} height={50} /> </div> ); } }

最小配置如下所示:

{ test: /\.svg$/, use: [ { loader: "babel-loader" }, { loader: "react-svg-loader", options: { jsx: true // true outputs JSX tags } } ] }

最好的部分是它只输出 svg 文件内容,代码中没有任何额外的包装器和

dangerouslySetInnerHTML


21
投票
老问题,但我在任何地方都没有看到这个解决方案,所以我决定发布它,希望它能帮助别人。

如果您希望能够设计这些 SVG 图标的样式,您可能需要使用原始加载器加载它们:

webpack.config.js:

{ test: /\.svg$/, loader: 'raw-loader' }

我认为的导入:

import closeIcon from 'svg/ic_close_black_24px.svg';

模板(Mustache 使用 3 个括号插入未编码的 SVG 数据(URL)):

<button id="closeModal"> {{{closeIcon}}} </button>

这样,SVG 数据将被插入而不是括号,如下所示:

<button id="closeModal"> <svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"> <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path> <path d="M0 0h24v24H0z" fill="none"></path> </svg> </button>

我正在使用带有 Mustache 模板引擎的 Backbone 和 Webpack 2.5.1


12
投票
如果我没记错的话,由于您正在使用文件加载器,因此您可以像任何其他需求一样使用它。 Webpack 会将

require("./logo.svg")

 转换为文件的路径,在打包时会发出该路径。

import React, { Component } from 'react' import mySvg from './logo.svg' class Header extends Component { render() { return ( <div className='header'> <img src={mySvg} /> </div> ); } }; export default Header
    

6
投票
与使用 React 的另一个答案类似,还有一个方便的 Vue 插件。

vue-svg-loader 只需将其放入您的配置中即可开始使用。好处是它还会通过 SVGO 运行您的 svg 来优化它。

配置

{ test: /\.svg$/, loader: 'vue-svg-loader', // `vue-svg` for webpack 1.x options: { // optional [svgo](https://github.com/svg/svgo) options svgo: { plugins: [ {removeDoctype: true}, {removeComments: true} ] } } }

用法

<template> <nav id="menu"> <a href="..."> <SomeIcon class="icon" /> Some page </a> </nav> </template> <script> import SomeIcon from './assets/some-icon.svg'; export default { name: 'menu', components: { SomeIcon, }, }; </script>
    

1
投票
Angular 解决方案(2019):使用

svg-sprite-loader 将 SVG 组合成一个与 Webpack 包一起延迟加载的 sprite。

Webpack

{ test: /\.svg$/, use: [ 'svg-sprite-loader', 'svgo-loader' // Optimize SVGs (optional) ] }

HTML

<svg> <use xlink:href="#arrow"/> </svg>

角度分量

export * from 'assets/images/icons/arrow.svg';

我使用导出(而不是导入)来防止 AOT 编译器在树摇动期间删除导入,同时允许组件中的代码最少,但如果您愿意,可以

使用导入

要以这种方式使用导出,您必须将编译器配置为预期 package.json 中的 SVG 文件会产生副作用(即您不能使用“sideEffects”: false)。请参阅

Webpack Tree Shaking 指南

"sideEffects": [ "*.svg", ],
    

1
投票

@svgr/webpack (npm) 是 create-react-app 使用的内联 svg 加载器。

将规则添加到您的 webpack 配置中:

{ test: /\.svg$/, use: ['@svgr/webpack'], }

然后你可以导入 svgs 作为 React 组件:

import Star from './star.svg' const App = () => ( <div> <Star /> </div> )
    

1
投票
使用

svg-inline-loader

 并遇到“找不到模块”错误的人们尝试安装 
babel-plugin-inline-react-svg
 并将其添加到 babel 插件中:

"plugins": [ ... ["inline-react-svg", {}] ], ...
    

0
投票
老问题,但当

需要 SVG 资源中的字符串时仍然相关。使用 webpack > 5 源资源 是简单地做到这一点的方法。

如果使用像 SVGR 这样的加载器来获取一些 SVG 作为 React 组件导入,您

仍然可以获得源资源。为此,请使用 oneOf

 规则。编辑
webpack.config.js

module: { rules: [ { test: /\.svg$/, oneOf: [ { issuer: /\.[jt]sx?$/, resourceQuery: /react/, // *.svg?react to get a component use: ["@svgr/webpack", "url-loader"], }, { type: "asset/source", parser: { dataUrlCondition: { maxSize: 200, }, }, }, ], }, // ... ] }
请注意,导入资源时,它们会作为一个“模块”进入,其中仅包含文本。它可以根据需要动态/异步导入,如下所示:

const { default: image } = await import("/assets/myimage.svg");
现在变量

image

将包含SVG文本内容。

console.log(image);
结果:

<?xml version="1.0" encoding="utf-8"?> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 500 275"> <g> <circle class="st0" cx="423.536" cy="192.862" r="76.464"/> </g> </svg>
    
© www.soinside.com 2019 - 2024. All rights reserved.