如何使用 webpack 设置内联 svg
Posted
技术标签:
【中文标题】如何使用 webpack 设置内联 svg【英文标题】:how to set up an inline svg with webpack 【发布时间】:2016-03-19 09:19:48 【问题描述】:我想知道?
我正在关注react-webpack-cookbook。
我的 webpack.config 使用 文件加载器 正确设置。
但是,该示例显示使用这样的背景图像:
.icon
background-image: url(./logo.svg);
效果很好,但我想要一个内联的 svg 图像,我该怎么做才能在我的反应组件中包含我的 logo.svg 内联?
import React, Component from 'react'
class Header extends Component
render()
return (
<div className='header'>
<img src='./logo.svg' />
</div>
);
;
export default Header
【问题讨论】:
【参考方案1】:如果我没记错的话,由于您使用的是文件加载器,因此您可以像使用其他任何需要一样使用它。 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
【讨论】:
它对我不起作用:(你能发布你的 webpack.config.js 吗?也许我可以在那里发现我的错误。 仅在我重新启动后才为我工作npm start
这增加了 svg 内联?还是将 svg 包装在图像标签中?【参考方案2】:
实际上 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-inline-react 的内联 svg 包装器,这将是另一个选项,而不是 <div dangerouslySetInnerHTML=__html: mySvg />
【讨论】:
只是一个注释,这对服务器渲染根本不起作用......所以不像我曾经想象的那么有用。我已经回到使用 svg 作为背景图像。它似乎也像内联 svg 一样使 javascript 包膨胀,当然这取决于 svg 的优化程度。 Twitter 发布了一个很好的案例研究,说明了为什么您应该不使用 'dangerouslySetInnerHTML' 来显示 SVG:medium.com/@paularmstrong/…【参考方案3】:老问题,但我在任何地方都没有看到这个解决方案,所以我决定发布它,希望它会对某人有所帮助。
如果您希望能够为这些 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" viewBox="0 0 24 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>
我正在使用带有 Webpack 2.5.1 的 Mustache 模板引擎的 Backbone
【讨论】:
将使用基于字符串模板的库,如骨干 + mustache 或 vue,但不使用 react,因为它使用 JSX 而不是原始字符串。可能确实适用于“dangerouslySetInnerHTML”...【参考方案4】:我希望我迟到的答案仍然对某人有用,因为我不喜欢上述任何选项。
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
。
【讨论】:
这适用于最新的 React 16.10 和 Webpack 4.41。谢谢!【参考方案5】:与使用 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>
【讨论】:
【参考方案6】:这是一个简单的非反应解决方案。
-
安装Svg inline loader
在 webpack.config.js 中添加
test: /\.svg$/, loader: 'svg-inline-loader'
在您的 js 文件中导入 svg 图像并将其添加到这样的 DOM 元素中
import Svg from './svg.svg';
function component()
const element = document.createElement('div');
element.innerHTML = Svg;
return element;
document.body.appendChild(component());
【讨论】:
感谢您不依赖 react 并展示 vanilla ECMAScript【参考方案7】:Angular 解决方案(2019 年):使用 svg-sprite-loader 将 SVG 组合成一个单独的精灵,该精灵与您的 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 编译器在 tree-shaking 期间删除导入,同时允许组件中的代码最少,但如果您愿意,可以use import。
要以这种方式使用导出,您必须将编译器配置为预期 package.json 中 SVG 文件的副作用(即,您不能使用“sideEffects”:false)。见Webpack Tree Shaking Guide
"sideEffects": [
"*.svg",
],
【讨论】:
【参考方案8】:@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>
)
【讨论】:
【参考方案9】:使用 svg-inline-loader
并遇到“找不到模块”错误的人尝试安装 babel-plugin-inline-react-svg
并将其添加到 babel 插件中:
"plugins": [
...
["inline-react-svg", ]
],
...
【讨论】:
以上是关于如何使用 webpack 设置内联 svg的主要内容,如果未能解决你的问题,请参考以下文章
如何在 mouseover/mouseout (SMIL) 上为内联 SVG 的填充属性设置动画
Webpack QuillJS 输出 SVG 路径而不是内联它