generate.icons.ts 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import { exec } from 'node:child_process'
  2. import path from 'node:path'
  3. import process from 'node:process'
  4. import { lookupCollection, lookupCollections } from '@iconify/json'
  5. import fs from 'fs-extra'
  6. import inquirer from 'inquirer'
  7. async function generateIcons() {
  8. // 拿到全部图标集的原始数据
  9. const raw = await lookupCollections()
  10. let lastChoose = fs.readFileSync(path.resolve(process.cwd(), 'src/iconify/index.json'), 'utf-8')
  11. lastChoose = JSON.parse(lastChoose)
  12. // 取出可使用的图标集数据用于 inquirer 选择,并按名称排序
  13. const collections = Object.entries(raw).map(([id, item]) => ({
  14. ...item,
  15. id,
  16. })).sort((a, b) => a.name.localeCompare(b.name))
  17. /**
  18. * 分别会在对应目录下生成以下文件,其中(1)(3)用于离线下载并安装图标,(2)用于图标选择器使用
  19. * (1) src/iconify/index.json 记录用户 inquirer 的交互信息
  20. * (2) src/iconify/data.json 包含多个图标集数据,仅记录图标名
  21. * (3) public/icons/*-raw.json 多个图标集的原始数据,独立存放,用于离线使用
  22. */
  23. inquirer.prompt([
  24. {
  25. type: 'checkbox',
  26. message: '请选择需要生成的图标集',
  27. name: 'collections',
  28. choices: collections.map(item => ({
  29. name: `${item.name} (${item.total} icons)`,
  30. value: item.id,
  31. })),
  32. default: lastChoose.collections,
  33. },
  34. {
  35. type: 'confirm',
  36. name: 'isOfflineUse',
  37. message: '是否需要离线使用',
  38. default: false,
  39. },
  40. ]).then(async (answers) => {
  41. await fs.writeJSON(
  42. path.resolve(process.cwd(), 'src/iconify/index.json'),
  43. {
  44. collections: answers.collections,
  45. isOfflineUse: answers.isOfflineUse,
  46. },
  47. )
  48. const outputDir = path.resolve(process.cwd(), 'public/icons')
  49. await fs.ensureDir(outputDir)
  50. await fs.emptyDir(outputDir)
  51. const collectionsMeta: object[] = []
  52. for (const info of answers.collections) {
  53. const setData = await lookupCollection(info)
  54. collectionsMeta.push({
  55. prefix: setData.prefix,
  56. info: setData.info,
  57. icons: Object.keys(setData.icons),
  58. })
  59. const offlineFilePath = path.join(outputDir, `${info}-raw.json`)
  60. if (answers.isOfflineUse) {
  61. await fs.writeJSON(offlineFilePath, setData)
  62. }
  63. }
  64. await fs.writeJSON(
  65. path.resolve(process.cwd(), 'src/iconify/data.json'),
  66. collectionsMeta,
  67. )
  68. exec('eslint src/iconify/data.json src/iconify/index.json --cache --fix')
  69. })
  70. }
  71. generateIcons()