generate-icons.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /**
  2. * PWA 图标生成脚本
  3. *
  4. * 使用说明:
  5. * 1. 准备一个 1024x1024 的原始图标文件(推荐使用 PNG 或 SVG)
  6. * 2. 将文件命名为 icon-source.png 并放在 public 目录
  7. * 3. 运行: node scripts/generate-icons.js
  8. *
  9. * 如果没有安装 sharp,请先安装:
  10. * npm install -D sharp
  11. */
  12. import fs from 'fs';
  13. import path from 'path';
  14. import { fileURLToPath } from 'url';
  15. // 获取当前文件的目录(ES 模块中需要手动获取 __dirname)
  16. const __filename = fileURLToPath(import.meta.url);
  17. const __dirname = path.dirname(__filename);
  18. // 检查是否安装了 sharp
  19. let sharp;
  20. try {
  21. const sharpModule = await import('sharp');
  22. sharp = sharpModule.default;
  23. } catch (error) {
  24. console.error('❌ 未安装 sharp 库');
  25. console.log('请运行: npm install -D sharp');
  26. process.exit(1);
  27. }
  28. // 图标尺寸配置
  29. const sizes = [72, 96, 128, 144, 152, 192, 384, 512];
  30. // 输入和输出目录
  31. const sourceIcon = path.join(__dirname, '../public/icon-source.png');
  32. const outputDir = path.join(__dirname, '../public/icons');
  33. // 创建输出目录
  34. if (!fs.existsSync(outputDir)) {
  35. fs.mkdirSync(outputDir, { recursive: true });
  36. }
  37. // 检查源文件是否存在
  38. if (!fs.existsSync(sourceIcon)) {
  39. console.error(`❌ 源图标文件不存在: ${sourceIcon}`);
  40. console.log('\n请准备一个 1024x1024 的图标文件:');
  41. console.log('1. 命名为 icon-source.png');
  42. console.log('2. 放在 public 目录下');
  43. console.log('3. 重新运行此脚本');
  44. process.exit(1);
  45. }
  46. // 生成图标
  47. async function generateIcons() {
  48. console.log('🎨 开始生成 PWA 图标...\n');
  49. try {
  50. for (const size of sizes) {
  51. const outputPath = path.join(outputDir, `icon-${size}x${size}.png`);
  52. await sharp(sourceIcon)
  53. .resize(size, size, {
  54. fit: 'contain',
  55. background: { r: 15, g: 23, b: 42, alpha: 1 } // 深色背景
  56. })
  57. .png({ quality: 90 })
  58. .toFile(outputPath);
  59. console.log(`✅ 生成 ${size}x${size} 图标`);
  60. }
  61. // 生成 Apple Touch Icon (180x180)
  62. const appleTouchIcon = path.join(__dirname, '../public/apple-touch-icon.png');
  63. await sharp(sourceIcon)
  64. .resize(180, 180, {
  65. fit: 'contain',
  66. background: { r: 15, g: 23, b: 42, alpha: 1 }
  67. })
  68. .png({ quality: 90 })
  69. .toFile(appleTouchIcon);
  70. console.log('✅ 生成 Apple Touch Icon (180x180)');
  71. // 生成 Favicon (32x32)
  72. const favicon = path.join(__dirname, '../public/favicon.ico');
  73. await sharp(sourceIcon)
  74. .resize(32, 32)
  75. .png()
  76. .toFile(favicon);
  77. console.log('✅ 生成 Favicon (32x32)');
  78. console.log('\n🎉 所有图标生成完成!');
  79. console.log(`📁 输出目录: ${outputDir}`);
  80. } catch (error) {
  81. console.error('❌ 生成图标时出错:', error);
  82. process.exit(1);
  83. }
  84. }
  85. // 运行脚本
  86. generateIcons();