实际上就是渲染了一个 SVG ,自定义的程度会很高
https://github.com/tanem/react-svg
https://www.npmjs.com/package/react-svg
https://zhuanlan.zhihu.com/p/33918621

  1. import React from 'react'
  2. import { ReactSVG } from 'react-svg'
  3. import userSvg from './user.svg'
  4. function App() {
  5. function beforeInjection(error, svg) {
  6. if (error) return;
  7. svg.classList.add('svgStyle')
  8. svg.setAttribute('style', 'fill: red')
  9. }
  10. return (
  11. <div>
  12. <ReactSVG src={userSvg} />
  13. <ReactSVG
  14. src={userSvg}
  15. className="wrapper"
  16. onClick={() => {}}
  17. wrapper={'a'}
  18. beforeInjection={beforeInjection}
  19. />
  20. </div>
  21. )
  22. }

image.png
css修改 svg样式

  1. .wrapper svg {
  2. width: 100px;
  3. height: 100px;
  4. }
  5. .wrapper path {
  6. fill: red;
  7. stroke: red;
  8. width: 80px;
  9. height: 80px;
  10. }

批量导入 svg

webpack的 require.context 函数可以获取一个上下文;
从而实现工程自动化(遍历文件夹的文件,从中获取指定文件,自动导入模块;
如果一个文件夹中的模块,需要频繁引用时可以使用 require.context 一次性引入

  1. import React from 'react'
  2. import { ReactSVG } from 'react-svg'
  3. function SvgIcon(context) {
  4. const files = context.keys();
  5. if (!files.length) return {};
  6. return files
  7. .reduce((prev, path, index) => {
  8. const svgName = path.replace(/\.svg$/, '');
  9. prev[svgName] = (props) => {
  10. const svgPath = files.map(context)[index];
  11. return (
  12. <ReactSvg
  13. src={svgPath}
  14. {...props}
  15. />
  16. )
  17. }
  18. return prev;
  19. }, {})
  20. }
  21. const paths = require.context('./icons', false, /\.svg$/);
  22. export default SvgIcon(paths)

require.context(dirname, useSubdirectories, RegExp)
require.context('./icons', false, /\.svg$/)

dirname String 需要读取模块的文件的所在目录
useSubdirectories Boolean 是否遍历子目录
RegExp RegExp 匹配的规则(正则表达式)

require.context 返回结果

属性 类型 说明
resolve Function 接受一个参数request,request为文件夹下面匹配文件的相对路径,
返回这个匹配文件相对于整个工程的相对路径
keys Function 返回一个数组,由匹配成功的文件所组成的数组
id String 执行环境的 id

字符串导入 svg

缺点:不能修改颜色,其实就是直接用 img 加载了 svg 文件

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

import 导入 svg

实际上就是渲染了一个 SVG ,自定义的程度会很高,使用限制

  • react-scripts 版本要大于 @2.0.0
  • react 版本大于 @16.3.0 ```jsx import { ReactComponent as Logo } from ‘./logo.svg’

import { default as logo } from ‘./logo.svg’; ReactSVG - 图2

  1. - ReactComponent是必需的魔法字符串
  2. - Logo现在是一个组件
  3. ![Logo.jpg](https://cdn.nlark.com/yuque/0/2021/jpeg/112859/1633360724583-97634bd1-2cca-44c6-bd70-6e6057525531.jpeg#averageHue=%23fbf9f9&clientId=u707c6882-dba7-4&from=drop&height=244&id=u0fa035d2&originHeight=488&originWidth=1124&originalType=binary&ratio=1&rotation=0&showTitle=false&size=107360&status=done&style=none&taskId=uc36833cd-4f5a-4dcf-ba29-b39db0c916e&title=&width=562)
  4. <a name="lA6kC"></a>
  5. ## @svgr/webpack
  6. [https://react-svgr.com/docs/webpack/](https://react-svgr.com/docs/webpack/)<br />将 svg图标作为 React组件导入
  7. ```bash
  8. yarn add babel-plugin-named-asset-import
  9. yarn add @svgr/webpack --dev

create-react-app 配置 @svgr/webpack

create-react-app 进行 eject , 需要给 webpack 加入配置

  1. [
  2. require.resolve('babel-plugin-named-asset-import'),
  3. {
  4. loaderMap: {
  5. svg: {
  6. ReactComponent: '@svgr/webpack?-svgo,+ref![path]',
  7. },
  8. },
  9. },
  10. ],
  11. {
  12. test: /\.svg$/,
  13. use: ['@svgr/webpack'],
  14. }

image.png
如果svg文件的存放是和jpg以及png等图片同一目录的,

  • 则需要在url-loader或file-loader的配置中使用exclude去除svg的匹配,
  • 因为如果不去除会导致svg经过hash指纹重命名之后,loader找不到svg文件,进而导致报错

umijs chainWebpack配置

  1. chainWebpack(config) {
  2. config.module
  3. .rule('svg')
  4. .test(/\.svg$/)
  5. .use('svgr')
  6. .loader('@svgr/webpack')
  7. // 图片配置
  8. config.module
  9. .rule('image')
  10. .test(/\.(png|gif|jpe?g|webp)$/)
  11. .use('url-loader')
  12. .loader('url-loader')
  13. .options({
  14. limit: 10000,
  15. name: '[name].[hash:7].[ext]',
  16. })
  17. }

@craco/craco @svgr配置

安装 @svgr/webpack

  1. module.exports = {
  2. plugins: [],
  3. webpack: {
  4. configure: (config, { env, paths }) => {
  5. config.module
  6. .rules
  7. .push({
  8. test: /\.svg$/,
  9. use: ["@svgr/webpack"]
  10. });
  11. return config;
  12. }
  13. }
  14. }

ts项目配置 svg

在项目根目录 加一个 custom.d.ts 文件声明

  1. import * as React from 'react';
  2. declare interface SvgrComponent extends React.StatelessComponent<React.SVGAttributes<SVGElement>> {}
  3. declare module '*.svg' {
  4. const content: SvgrComponent
  5. export default content
  6. }
  7. // 其他语法
  8. declare module '*.svg' {
  9. import React = require('react');
  10. export const ReactComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
  11. const src: string;
  12. export default src;
  13. }


然后在 tsconfig.json 中加入

  1. "files": ["custom.d.ts"]

https://blog.csdn.net/baidu_39067385/article/details/106311737
https://stackoverflow.com/questions/60074103/adding-svgr-to-create-react-app-via-craco
https://create-react-app.dev/docs/adding-images-fonts-and-files/#adding-svgs
https://www.pluralsight.com/guides/how-to-load-svg-with-react-and-webpack