我想知道如何使用 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
这是一个简单的非反应解决方案。
{ test: /\.svg$/, loader: 'svg-inline-loader' }
import Svg from './svg.svg';
function component() {
const element = document.createElement('div');
element.innerHTML = Svg;
return element;
}
document.body.appendChild(component());
实际上 Michelle 的回答为我指明了正确的方向,这对于使用 webpack 加载 svg 文件并将其用作您的
<img>
src 来说非常有效
但是要真正获得内联 svg,我需要执行以下操作:使用
svg-inline-loader 作为您的 svg 加载器,而不是文件加载器:
{ test: /\.svg$/, loader: 'svg-inline-loader' }
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}} />
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
。
如果您希望能够设计这些 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
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
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>
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)。请参阅"sideEffects": [
"*.svg",
],
@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>
)
svg-inline-loader
并遇到“找不到模块”错误的人们尝试安装
babel-plugin-inline-react-svg
并将其添加到 babel 插件中:
"plugins": [
...
["inline-react-svg", {}]
],
...
需要 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>