【generate】如何维护一套icon组件库,直接输出svg为react component

news2025/1/20 5:53:50

https://github.com/ant-design/ant-design-web3/pull/761/files
实现了icon-preview(通过jsdoc, 鼠标放在组件上可以看到icon的样式),因为打包方式、产物以及命名上有一些不同,可能需要稍加改造。

这个同步脚本应该后续也用得上,略加改造同步 svg 可以提高后续添加 svg 的效率直接拖入图片就可以转成组件代码,降低cv和命名心智。
在这里插入图片描述

  1. 在package.json中设置命令可以直接执行ts脚本
"icons:generate": "NODE_OPTIONS='--experimental-specifier-resolution=node' node --loader ts-node/esm ./packages/icons/scripts/generate.ts"
  1. 通过 mport * as allIconDefs from '@ant-design/web3-icons' 获取所有组件,使用camelToKebab函数转换需要符合自己命名需求的组件
    在这里插入图片描述
  2. 通过 template 设置render模版
import pkg from 'lodash';
const { template } = pkg;

全部代码

import * as fs from 'fs';
import * as path from 'path';
import { promisify } from 'util';
import * as allIconDefs from '@ant-design/web3-icons';
import pkg from 'lodash';

const __dirname = new URL(import.meta.url).pathname;
const { template } = pkg;

const writeFile = promisify(fs.writeFile);

interface IconDefinition {
  [key: string]: any;
}
interface IconDefinitionWithIdentifier extends IconDefinition {
  svgIdentifier: string;
  svgBase64: string | null;
}

function camelToKebab(camelCaseString: string) {
  return camelCaseString
    .replace(/([a-z\d])([A-Z][a-z\d])|([A-Z]+(?![a-z\d]))/g, '$1$3-$2')
    .toLowerCase();
}

function detectRealPath(_path: string) {
  try {
    return fs.existsSync(_path) ? _path : null;
  } catch (e) {
    return null;
  }
}

function svg2base64(svgPath: string, size = 50) {
  const svg = fs.readFileSync(svgPath, 'utf-8');
  const svgWithStyle = svg.replace(/<svg/, `<svg width="${size}" height="${size}" fill="#cacaca"`);

  const base64 = Buffer.from(svgWithStyle).toString('base64');
  return `data:image/svg+xml;base64,${base64}`;
}

function walk<T>(fn: (iconDef: IconDefinitionWithIdentifier) => Promise<T>) {
  return Promise.all(
    Object.keys(allIconDefs).map((svgIdentifier) => {
      const iconDef = (allIconDefs as { [id: string]: IconDefinition })[svgIdentifier];
      const svgPathToKebab = camelToKebab(svgIdentifier);
      const realSvgPath = detectRealPath(
        path.resolve(__dirname, `../../src/svgs/${svgPathToKebab}.svg`),
      );

      let svgBase64: string | null = null;

      if (realSvgPath) {
        try {
          svgBase64 = svg2base64(realSvgPath);
        } catch (e) {}
      }
      return fn({ svgIdentifier, svgBase64, svgPathToKebab, ...iconDef });
    }),
  );
}

async function generateIcons() {
  const iconsDir = path.join(__dirname, '../../src/svgs');

  try {
    await promisify(fs.access)(iconsDir);
  } catch (err) {
    await promisify(fs.mkdir)(iconsDir);
  }

  const render = template(
    `
// GENERATE BY ./scripts/generate.ts
// DON NOT EDIT IT MANUALLY
import * as React from 'react';
import AntdIcon from '@ant-design/icons';
import { type IconBaseProps } from '@ant-design/icons/lib/components/Icon';
import { ConfigProvider } from 'antd';
import classnames from 'classnames';

import SVGComponent from '../svgs/<%= svgPathToKebab %>.svg';

<% if (svgBase64) { %> /**![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=%3C%25%3D%20svgBase64%20%25%3E&pos_id=img-c6iaG6Dw-1712112320363) */ <% } %>
export const <%= svgIdentifier %> = React.forwardRef<HTMLSpanElement, IconBaseProps>((props, ref) => {
  const { getPrefixCls } = React.useContext(ConfigProvider.ConfigContext);
  const prefixCls = getPrefixCls('web3-icon-<%= svgPathToKebab %>');

  return (
    <AntdIcon
      {...props}
      className={classnames(prefixCls, props.className)}
      ref={ref}
      component={SVGComponent}
    />
  );
});

<%= svgIdentifier %>.displayName = '<%= svgIdentifier %>';

`.trim(),
  );

  await walk(async (item) => {
    // generate icon file
    const svgPathToKebab = camelToKebab(item.svgIdentifier);

    try {
      await writeFile(
        path.resolve(__dirname, `../../src/components/${svgPathToKebab}.tsx`),
        render(item),
      );
    } catch (error) {}
  });

  // generate icon index
  const entryText = Object.keys(allIconDefs)
    .sort()
    .map((svgIdentifier) => `export * from './components/${camelToKebab(svgIdentifier)}';`)
    .join('\n');

  await promisify(fs.appendFile)(
    path.resolve(__dirname, '../../src/index.ts'),
    `
  // GENERATE BY ./scripts/generate.ts
  // DON NOT EDIT IT MANUALLY

  ${entryText}
      `.trim(),
  );
}

generateIcons();

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

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

相关文章

装饰工程管理系统|基于Springboot的装饰工程管理系统设计与实现(源码+数据库+文档)

装饰工程管理系统-项目立项子系统目录 目录 基于Springboot的装饰工程管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员功能实现 &#xff08;2&#xff09;合同报价管理 &#xff08;3&#xff09;装饰材料总计划管理 &#xff08;4&#xff0…

深度解析GPT中的Tokenizer

继学习完深度解析大语言模型中的词向量后&#xff0c;让我们继续学习大语言模型中另外几个重要概念&#xff1a;token&#xff08;词元&#xff09;、tokenization&#xff08;词元化&#xff09;、tokenizer&#xff08;词元生成器&#xff09;。 在GPT模型中&#xff0c;toke…

Minikube本地搭建单节点Kubernetes集群

1、什么是 Minikube Minikube 是一个开源工具&#xff0c;旨在为开发者提供一种便捷的方式在本地环境中搭建单节点的 Kubernetes 集群。它主要用于开发、测试和学习 Kubernetes 应用程序&#xff0c;无需依赖大型的硬件资源或复杂的多节点集群配置。minikube 使用轻量级虚拟化技…

小林coding图解计算机网络|基础篇02|键入网址到网页显示,期间发生了什么?

小林coding网站通道&#xff1a;入口 本篇文章摘抄应付面试的重点内容&#xff0c;详细内容还请移步&#xff1a;小林coding网站通道 文章目录 孤单小弟——HTTP真实地址查询——DNS指南好帮手——协议栈可靠传输——TCP远程定位——IP两点传输——MAC出口——网卡送别者——交…

如何优化TCP?TCP的可靠传输机制是什么?

在网络世界中&#xff0c;传输层协议扮演着至关重要的角色&#xff0c;特别是TCP协议&#xff0c;以其可靠的数据传输特性而广受青睐。然而&#xff0c;随着网络的发展和数据量的激增&#xff0c;传统的TCP协议在效率方面遭遇了挑战。小编将深入分析TCP的可靠性传输机制&#x…

CentOS7安装MySQL8.0.28(持续)

第一步 &#xff1a;下载mysql MySQL https://www.mysql.com/

【剑指offr--C/C++】JZ59 滑动窗口的最大值

一、题目 二、思路及代码 暴力解法是依次往后滑动一位&#xff0c;然后比较窗口内的值。 我这里考虑&#xff1a;窗口每次往后移动一位&#xff0c;那么如果当前窗口的最大值max在窗口内部&#xff0c;那么再滑动到下一个窗口的时候&#xff0c;窗口内只有最新进来的一个元素没…

操作系统导论课后作业-第十七章答案

课程作业-第十七章&#xff1a; 17.1首先以标志flag -n 10 -H 0 -p BEST -s 0运行程序来产生一些随机的分配和空闲。你能预测malloc()/free()会返回什么吗&#xff1f;你可以在每次请求后猜测空闲列表的状态吗&#xff1f;随着时间的推移&#xff0c;你对空闲列表有什么发现&a…

Windows 11安装kb5035853补丁时,提示错误0x800f0922,并且弹出“某些操作未按计划进行,不必担心,正在撤消更改。请不要关机”

Windows 11安装kb5035853补丁时&#xff0c;提示错误0x800f0922&#xff0c;并且还在重启后弹出“某些操作未按计划进行&#xff0c;不必担心&#xff0c;正在撤消更改。请不要关机”&#xff0c;按微软官方的作法是&#xff1a;https://learn.microsoft.com/zh-cn/windows/rel…

同态加密算法的概念与应用

同态加密算法的基本概念 同态加密算法是一种特殊的加密算法&#xff0c;允许对加密状态下的数据进行计算&#xff0c;得到的结果仍然是加密的状态&#xff0c;而不是解密后的明文。同态加密算法的核心原理是将明文数据映射到一个特定的数学空间中&#xff0c;在该数学空间中实…

mac电脑安装redis教程

1、下载地址 Download | RedisRedisYou can download the last Redis source files here. For additional options, see the Redis downloads section below.Stable (7.2)Redis 7.2 …https://redis.io/download/#redis-downloads 2、安装 2.1 解压下载后的压缩文件 2.2 进入…

基于 Docker 的 go grpc quickstart

工作之后一直使用的 RPC 框架是 Apache 的 thrift&#xff0c;现在发现 grpc 更流行&#xff0c;所以也要学习一下&#xff0c;先来简单的跑一下 demo。在本地安装运行也很方便&#xff0c;不过因为有了 docker&#xff0c;所以在 docker 里面安装运行隔离性更好&#xff0c;顺…

构建第一个ArkTS应用(Stage模型)

创建ArkTS工程 若首次打开DevEco Studio&#xff0c;请点击Create Project创建工程。如果已经打开了一个工程&#xff0c;请在菜单栏选择File > New > Create Project来创建一个新工程。选择Application应用开发&#xff08;本文以应用开发为例&#xff0c;Atomic Servi…

运筹学经典问题(八):CVRP和VRP-TW

文章目录 问题描述问题建模决策变量数学建模基于容量的消除子环的约束 &#xff08;load-based SECs&#xff09; CVRP完整的数学模型加上时间窗限制的CVRP 问题描述 给定一个图&#xff0c;图上的点代表客户&#xff0c;边代表客户之间的路线&#xff0c;边的权重代表客户之间…

生成式人工智能与 LangChain(预览)(上)

原文&#xff1a;Generative AI with LangChain 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 一、生成模型是什么&#xff1f; 人工智能&#xff08;AI&#xff09;取得了重大进展&#xff0c;影响着企业、社会和个人。在过去的十年左右&#xff0c;深度学习已经发…

联达动力OA 多处任意文件上传漏洞复现

0x01 产品简介 联达动力OA是PHPOA推出的新一代OA系统,系统支持性好、安全、数据高速缓存化;支持100+应用自行安装与定义,应用表单自定义,支持应用无代码开发,支持多语言。 0x02 漏洞概述 联达动力OA /FileManage/UpLoadFile.aspx、/Hosp_Portal/uploadLogo.aspx、/Dept_Por…

基于51单片机智能加湿器控制系统

基于51单片机智能加湿器控制系统 &#xff08;仿真&#xff0b;程序&#xff0b;原理图&#xff09; 功能介绍 具体功能&#xff1a; 1.LCD1602实时显示湿度值&#xff08;湿度范围10%-95%&#xff09;和湿度阈值&#xff1b; 2.可以通过按键设置湿度阈值范围&#xff1b; 3…

ES6展开运算符

1.展开可迭代对象&#xff08;简单理解为数组和伪数组&#xff09;&#xff0c;如数组、 NodeList 、arguments。 可以通过展开运算符把一个伪数组转换为数组 const a [...document.body.children]; console.log(a); console.log(Array.isArray(a));2.实现数组的浅拷贝 cons…

什么?穷哥们没钱RLHF?跟我一起DPO吧,丐版一样用

本次DPO训练采用TRL的方式来进行训练 Huggingface TRL是一个基于peft的库&#xff0c;它可以让RL步骤变得更灵活、简单&#xff0c;你可以使用这个算法finetune一个模型去生成积极的评论、减少毒性等等。 本次进行DPO的模型是一个500M的GPT-2&#xff0c;目的是训练快&#x…

Anaconda如何切换国内镜像源

一、anaconda如何切换阿里镜像源 在Anaconda中切换到阿里云镜像源可以通过以下步骤进行&#xff1a; 1、打开终端&#xff08;Windows&#xff09;或者命令行界面&#xff08;macOS/Linux&#xff09;。 2、执行以下命令来配置阿里云镜像源&#xff1a; conda config --add…