1import fs from 'fs/promises'; 2import path from 'path'; 3import * as url from "node:url"; 4 5 6function toCamelCase(str) { 7 // 将下划线和中划线统一替换为空格 8 let camelCaseStr = str.replace(/[-_]/g, ' '); 9 10 // 将每个单词的首字母大写,其余字母小写 11 camelCaseStr = camelCaseStr.split(' ').map(word => { 12 return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); 13 }).join(''); 14 15 return camelCaseStr; 16} 17 18// 读取所有的icon 19const basePath = path.resolve(url.fileURLToPath(import.meta.url), '../../src/assets/icons') 20 21// 读取所有的svg 22const icons = await fs.readdir(basePath) 23 24const assets = icons.map(it => ({ 25 componentName: toCamelCase(it.slice(0, -path.extname(it).length)) + "Icon", 26 filePath: `@/assets/icons/${it}`, 27 name: it.slice(0, -path.extname(it).length) 28})) 29 30let scriptTemplate = `// This file is generated by generate-assets.mjs. DO NOT MODIFY. 31import {SvgProps} from 'react-native-svg'; 32 33${assets.map(asset => `import ${asset.componentName} from '${asset.filePath}';`).join('\n')} 34 35export type IIconName = ${assets.map(asset => `'${asset.name}'`).join(' | ')}; 36 37interface IProps extends SvgProps { 38 /** 图标名称 */ 39 name: IIconName; 40 /** 图标大小 */ 41 size?: number; 42} 43 44const iconMap = { 45${assets.map(asset => ` '${asset.name}': ${asset.componentName}`).join(',\n')} 46} as const; 47 48export default function Icon(props: IProps) { 49 const {name, size} = props; 50 51 const newProps = { 52 ...props, 53 width: props.width ?? size, 54 height: props.width ?? size 55 } as SvgProps; 56 57 const Component = iconMap[name]; 58 59 return <Component {...newProps}></Component>; 60} 61` 62 63const targetPath = path.resolve(url.fileURLToPath(import.meta.url), '../../src/components/base/icon.tsx'); 64await fs.writeFile(targetPath, scriptTemplate, 'utf8'); 65 66console.log(`Generate Succeed. ${assets.length} assets.`)