【React】React18+Typescript+craco配置最小化批量引入Svg并应用的组件

news2024/11/25 20:48:01

React18+Typescript+craco配置最小化批量引入Svg并应用的组件

    • 前言
    • 创建React + Typescript项目
    • 通过require.context实现批量引入Svg
    • 安装[@types/webpack-env](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/README.zh-Hans.md)解决类型报错
    • 安装[craco](https://craco.js.org/docs/getting-started/#start-configuring),覆盖React原有的webpack配置文件
    • 修改package.json脚本快捷方式为craco启动项目
    • 安装[svg-sprite-loader](https://github.com/JetBrains/svg-sprite-loader)生成Svg雪碧图
    • 安装[svgo-loader](https://github.com/svg/svgo-loader)去除Svg的fill和stroke属性
    • 新增craco.config.js配置文件
    • 封装Icon组件应用Svg图标
    • 在index.tsx入口文件中引入批量引入Svg的函数
    • 在App.tsx中引入Icon组件并应用
    • 修改tsconfig.json新增别名@解决报错
    • 启动项目,目录结构如下
    • 参考
    • 总结

前言

无论是哪种 Web UI 框架都不可避免的要与 Svg 打交道,那么批量引入才更方便管理 Svg

创建React + Typescript项目

npx create-react-app my-ts-app --template typescript

通过require.context实现批量引入Svg

// src/assets/icons/index.ts
const requireAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().map(requireContext)
const icons = require.context('./', false, /\.svg$/)
requireAll(icons)

export {}

在这里插入图片描述

安装@types/webpack-env解决类型报错

npm install --save @types/webpack-env

安装craco,覆盖React原有的webpack配置文件

npm i -D @craco/craco @craco/types

修改package.json脚本快捷方式为craco启动项目

"scripts": {
-  "start": "react-scripts start"
+  "start": "craco start"
-  "build": "react-scripts build"
+  "build": "craco build"
-  "test": "react-scripts test"
+  "test": "craco test"
}

安装svg-sprite-loader生成Svg雪碧图

npm install svg-sprite-loader -D

安装svgo-loader去除Svg的fill和stroke属性

npm install svgo-loader --save-dev

新增craco.config.js配置文件

const path = require('path');

module.exports = {
    webpack: {
        alias: {
            '@': path.resolve(__dirname, 'src'),
        },
        configure: (webpackConfig) => {
            const oneOfRule = webpackConfig.module.rules.find((rule) => rule.oneOf)
            if (oneOfRule) {
                oneOfRule.oneOf.splice(0, 0, {
                    test: /\.svg$/,
                    include: path.resolve(__dirname, "src/assets/icons"),
                    use: [
                        {
                            loader: 'svg-sprite-loader',
                            options: {
                                symbolId: "icon-[name]"
                            }
                        },
                        {
                            loader: 'svgo-loader', options: {
                                plugins: [
                                    {
                                        name: 'removeAttrs',
                                        params: {
                                            attrs: '(fill|stroke)'
                                        }
                                    }
                                ]
                            }
                        }
                    ]
                })
            }
            return webpackConfig
        },
    }
}

封装Icon组件应用Svg图标

// src/components/Icon/index.tsx
import React from "react";
import classes from './index.module.css'

interface IconProps {
    name: string
    width: string
    height?: string
    fill?: string
}

const Icon = ({ name, width, height, fill }: IconProps) => {
    return (
        <svg className={classes.icon} aria-hidden="true" width={width} height={height}>
            <use xlinkHref={'#icon-' + name} style={{color: fill}}></use>
        </svg>
    )
}

export default Icon
/* src/components/Icon/index.module.css */
.icon {
    vertical-align: -0.15em;
    fill: currentColor;
    overflow: hidden;
    font-size: 0;
}

在index.tsx入口文件中引入批量引入Svg的函数

// src/index.tsx
import '@/assets/icons/index';

在App.tsx中引入Icon组件并应用

// src/App.tsx
import React from 'react';
import Icon from '@/components/Icon/index'
import './App.css';

function App() {
    return (
        <div className="App">
            <Icon name='p_ding' width="30px" height='30px' fill="red" />
            <Icon name='p_book' width="30px" height='30px' />
        </div>
    );
}

export default App;

在这里插入图片描述

修改tsconfig.json新增别名@解决报错

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "baseUrl": "./src",
    "paths": {
        "@/*": ["./*"]
    }
  },
  "include": [
    "src"
  ]
}

在这里插入图片描述

启动项目,目录结构如下

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

参考

  • https://ryanhutzley.medium.com/dynamic-svg-imports-in-create-react-app-d6d411f6d6c6
  • https://github.com/airbnb/babel-plugin-inline-react-svg/issues/51
  • https://blog.shianqi.com/2017/12/13/Webpack/SVG-sprite/
  • https://pganalyze.com/blog/building-svg-components-in-react
  • https://juejin.cn/post/6844904194747400199
  • https://blog.csdn.net/qq_44883318/article/details/132202175
  • https://juejin.cn/post/7035808121272893477
  • https://github.com/dilanx/craco/issues/395
  • https://segmentfault.com/a/1190000023807589
  • https://blog.csdn.net/qq_39953537/article/details/93760188
  • https://juejin.cn/post/7207336474150273061
  • https://juejin.cn/post/6918723151732391950#heading-0
  • https://juejin.cn/post/6981836039463632932
  • https://segmentfault.com/a/1190000039850941

总结

  1. 配置别名需要tsconfig.json和craco.config.js一起配合
  2. 批量引入组件或者资源通过require.context函数实现
  3. module css实现组件的私有样式,相当于Vue中 scoped 作用域

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1589471.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何免费搭建幻兽帕鲁服务器?

雨云是一家国内的云计算服务提供商&#xff0c;为了吸引用户推出了积分兑换云产品活动&#xff0c;只需要完成简单积分任务即可获得积分&#xff0c;积分可以兑换免费游戏云、对象存储或者虚拟主机。本文将给大家分享雨云免费游戏云领取及幻兽帕鲁开服教程。 第一步&#xff1a…

每日一题---OJ题: 合并两个有序链表

嗨!小伙伴们,好久不见啦! 今天我们来看看一道很有意思的一道题---合并两个有序链表 嗯,题目看上去好像不难,我们一起画图分析分析吧! 上图中,list1有3个结点,分别为1,2,3 ; list2中有3个结点,分别为1,3,4, 题目要求我们要将这两个链表合并到一起,并且是升序,最后将链表返回。 …

【JAVA基础篇教学】第六篇:Java异常处理

博主打算从0-1讲解下java基础教学&#xff0c;今天教学第五篇&#xff1a; Java异常处理。 异常处理是Java编程中重要的一部分&#xff0c;它允许开发人员在程序运行时检测和处理各种错误情况&#xff0c;以保证程序的稳定性和可靠性。在Java中&#xff0c;异常被表示为对象&am…

大型网站系统架构演化

大型网站质量属性优先级&#xff1a;高性能 高可用 可维护 应变 安全 一、单体架构 应用程序&#xff0c;数据库&#xff0c;文件等所有资源都在一台服务器上。 二、垂直架构 应用和数据分离&#xff0c;使用三台服务器&#xff1a;应用服务器、文件服务器、数据服务器 应用服…

TCM SRAM等五块内存的使用和动态分配

TCM SRAM等五块内存的使用和动态分配 配置sct文件内存使用动态内存分配rtx_lib.hrtx_memory.cmain.c 配置sct文件 LR_IROM1 0x08000000 0x00200000 { ; load region size_regionER_IROM1 0x08000000 0x00200000 { ; load address execution address*.o (RESET, First)*(InRoo…

1113. 红与黑--Flood Fill 算法

目录 1113. 红与黑--Flood Fill 算法---宽搜&#xff08;BFS&#xff09;或DFS&#xff09; 输入格式 输出格式 数据范围 输入样例&#xff1a; 输出样例&#xff1a; 思路&#xff1a; 1.BFS 思路&#xff1a; 2.DFS 思路 方法一&#xff1a;&#xff08;BFS&#x…

玉伯也创业了,曾经的互联网高P也慢慢的落幕了

玉伯是真创业还是被动创业&#xff1f;毕竟&#xff0c;在阿里的时候&#xff0c;他可是Ant Design和语雀的大佬&#xff0c;风光无限&#xff0c;谁都知道他的大名。但后来&#xff0c;他去了字节&#xff0c;待了不到一年就跑了&#xff0c;现在选择出来创业。是不是曾经的那…

文章分享:《二代测序临床报告解读指引》

&#xff3b;摘要&#xff3d; 二代测序&#xff08;next generation sequencing&#xff0c;NGS&#xff09;已成为中国临床肿瘤医生常用检测工具&#xff0c;而中国超 90%临床医生需要 NGS 报告解读支持。因此&#xff0c;为提升临床医生 NGS 报告解读能力&#xff0c;特编写…

ETL结合飞书快速实现业务信息同步

一、ETL工具介绍 ETLCloud数据集成平台是一款针对IT以及数据工程师推出的全域数据集成平台产品。它是集实时数据集成和离线数据集成以及API发布为一体的数据集成平台。与其他开源数据集成工具相比&#xff0c;系统采用轻量化架构、具有更快的部署速度、更快的数据传输速度、更…

宏景eHR customreport/tree SQL注入漏洞复现

0x01 产品简介 宏景eHR人力资源管理软件是一款人力资源管理与数字化应用相融合,满足动态化、协同化、流程化、战略化需求的软件。 0x02 漏洞概述 宏景eHR customreport/tree 接口处存在SQL注入漏洞,未经过身份认证的远程攻击者可利用此漏洞执行任意SQL指令,从而窃取数据库…

HarmonyOS-数据请求(http / axios)

一、http数据请求 步骤&#xff1a; 1.在module.json5中申请ohos.permission.INTERNET权限 "module": {"requestPermissions": [{ "name": "ohos.permission.INTERNET" }],...} 2.在xxx.ets页面中导入&#xff1a;import http fro…

RPC简单介绍

Rpc框架&#xff0c;来为模块间远程功能交互提供⽀撑&#xff1b; 这个Rpc框架中有诸如RpcServer、RpcService、RpcSystem、RpcEndpoint等⼤量设计封装&#xff1b; 1. 基本概念 RPC&#xff1a;远程过程调⽤&#xff08;Remote Procedure Call&#xff09;&#xff1b; •…

库、框架、脚手架和IDE一文讲明白

在区分上面几个问题前&#xff0c;咱们先看看几个疑问。 一、常见问题汇总 js css直接复制到服务器 然后引用不就行了么&#xff1f; 为什么还需要安装&#xff1f; 引入js不就是引入了框架了吗&#xff1f;框架就是js&#xff1f; 脚手架和框架都有架&#xff0c;是不是一…

国家留学基金委(CSC)2024-2025年度中加学者交换项目开始申报

4月3日&#xff0c;国家留学基金委&#xff08;CSC&#xff09;发布了2024-2025年度中加学者交换项目遴选通知。根据通知精神&#xff0c;选派规模&#xff1a;100人月&#xff0c;留学及资助期限&#xff1a;4-12个月&#xff0c;网上报名截止日期至2024年6月30日。以下知识人…

基于SSM+Vue实现的宠物销售系统

基于SSMVue实现的宠物销售系统 系统介绍 系统演示 点击查看视频演示 基于SSMVue实现的宠物销售系统&#xff0c;主要实现的功能有以下几点&#xff1a;管理员&#xff1b;首页、个人中心、宠物分类管理、商品分类管理、宠物用品管理、宠物商店管理、宠物领养管理、用户管理…

UI状态伪类选择器

1.div::selection{background:yellow;color: red; } 鼠标选中后高亮状态的样式 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge">&…

题目:建造房屋 (蓝桥OJ3362)

问题描述: 代码: #include<bits/stdc.h> using namespace std; int n, m, k, ans, mod 1e9 7; long long dp[55][2605]; /*dp[i][j]&#xff1a;第i个街道上建j个房屋的总方案数枚举所有的转移&#xff0c;累加到dp[n][k]即总方案数 */ int main() {cin >> n &…

JavaEE 初阶篇-深入了解 CAS 机制与12种锁的特征(如乐观锁和悲观锁、轻量级锁与重量级锁、自旋锁与挂起等待锁、可重入锁与不可重入锁等等)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 乐观锁与悲观锁概述 1.1 悲观锁&#xff08;Pessimistic Locking&#xff09; 1.2 乐观锁&#xff08;Optimistic Locking&#xff09; 1.3 区别与适用场景 2.0 轻…

Linux虚拟网络设备:底层原理与性能优化深度解析

在深入探讨Linux虚拟网络设备的底层原理之前&#xff0c;重要的是要理解这些设备如何在Linux内核中实现&#xff0c;以及它们如何与操作系统的其他部分交互以提供高效且灵活的网络功能。虚拟网络设备在现代网络架构中发挥着关键作用&#x1f511;&#xff0c;特别是在云计算☁️…

Playwright录制脚本 —— web自动化测试!

简介&#xff1a; 在编写 web 自动化测试用例时&#xff0c;代码编写的速度是否快&#xff0c;会影响框架的使用体验。现在很多的框架都会提供一些辅助功能&#xff0c;帮助我们更快的去编写自动化测试代码&#xff0c;而录制功能是几乎所有的web自动化工具都会带的功能。在实际…