generate-nodejs-dependencies.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #!/usr/bin/env node
  2. /**
  3. * 根据 x64 和 arm64 架构分别生成 dependencies.txt
  4. * 功能:从 node_modules 读取已安装包,按架构替换平台相关包,分别写入 x64 和 arm64 目录
  5. */
  6. const fs = require('fs');
  7. const path = require('path');
  8. const scriptDir = __dirname;
  9. const projectRoot = path.dirname(path.dirname(scriptDir));
  10. const nodeModulesPath = path.join(projectRoot, 'node_modules');
  11. const x64Dir = path.join(scriptDir, 'x64');
  12. const arm64Dir = path.join(scriptDir, 'arm64');
  13. // 平台相关包的映射(x64 ↔ arm64 一一对应)
  14. const X64_TO_ARM64 = {
  15. '@esbuild/win32-x64': '@esbuild/win32-arm64',
  16. '@parcel/watcher-win32-x64': '@parcel/watcher-win32-arm64',
  17. '@rollup/rollup-win32-x64-gnu': '@rollup/rollup-win32-arm64-gnu',
  18. '@rollup/rollup-win32-x64-msvc': '@rollup/rollup-win32-arm64-msvc'
  19. };
  20. const ARM64_TO_X64 = Object.fromEntries(
  21. Object.entries(X64_TO_ARM64).map(([k, v]) => [v, k])
  22. );
  23. const colors = {
  24. reset: '\x1b[0m',
  25. green: '\x1b[32m',
  26. yellow: '\x1b[33m',
  27. cyan: '\x1b[36m'
  28. };
  29. function log(message, color = 'reset') {
  30. console.log(`${colors[color]}${message}${colors.reset}`);
  31. }
  32. function collectPackagesFromNodeModules() {
  33. const packages = new Map();
  34. if (!fs.existsSync(nodeModulesPath)) {
  35. return packages;
  36. }
  37. function scan(dir, prefix = '') {
  38. const entries = fs.readdirSync(dir, { withFileTypes: true });
  39. for (const entry of entries) {
  40. if (entry.isDirectory() && !entry.name.startsWith('.')) {
  41. const fullName = prefix ? `${prefix}/${entry.name}` : entry.name;
  42. const pkgPath = path.join(dir, entry.name, 'package.json');
  43. if (fs.existsSync(pkgPath)) {
  44. try {
  45. const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
  46. if (pkg.name && pkg.version) {
  47. packages.set(pkg.name.toLowerCase(), `${pkg.name}==${pkg.version}`);
  48. }
  49. } catch (_) {}
  50. }
  51. if (entry.name.startsWith('@')) {
  52. scan(path.join(dir, entry.name), entry.name);
  53. }
  54. }
  55. }
  56. }
  57. scan(nodeModulesPath);
  58. return packages;
  59. }
  60. function buildArchList(packagesMap, targetArch) {
  61. const toExclude = targetArch === 'x64' ? Object.values(X64_TO_ARM64) : Object.keys(X64_TO_ARM64);
  62. const swapMap = targetArch === 'x64' ? ARM64_TO_X64 : X64_TO_ARM64;
  63. const result = [];
  64. for (const [nameLower, nameVersion] of packagesMap) {
  65. if (toExclude.some(p => nameLower === p.toLowerCase())) {
  66. continue;
  67. }
  68. result.push(nameVersion);
  69. }
  70. // 若 node_modules 中有对方架构的平台包,为目标架构添加对应的同版本包
  71. for (const [fromPkg, toPkg] of Object.entries(swapMap)) {
  72. const fromEntry = [...packagesMap.entries()].find(([k]) => k === fromPkg.toLowerCase());
  73. if (fromEntry) {
  74. const ver = fromEntry[1].includes('==') ? fromEntry[1].split('==')[1] : 'latest';
  75. const line = `${toPkg}==${ver}`;
  76. if (!result.some(r => r.startsWith(toPkg + '=='))) {
  77. result.push(line);
  78. }
  79. }
  80. }
  81. return [...new Set(result)].sort();
  82. }
  83. function main() {
  84. log('Generating x64 and arm64 dependencies.txt...', 'cyan');
  85. const packagesMap = collectPackagesFromNodeModules();
  86. if (packagesMap.size === 0) {
  87. log('[WARN] node_modules not found or empty. Run npm install first.', 'yellow');
  88. process.exit(1);
  89. }
  90. const x64List = buildArchList(packagesMap, 'x64');
  91. const arm64List = buildArchList(packagesMap, 'arm64');
  92. if (!fs.existsSync(x64Dir)) fs.mkdirSync(x64Dir, { recursive: true });
  93. if (!fs.existsSync(arm64Dir)) fs.mkdirSync(arm64Dir, { recursive: true });
  94. const x64File = path.join(x64Dir, 'dependencies.txt');
  95. const arm64File = path.join(arm64Dir, 'dependencies.txt');
  96. fs.writeFileSync(x64File, x64List.join('\n') + '\n', 'utf-8');
  97. fs.writeFileSync(arm64File, arm64List.join('\n') + '\n', 'utf-8');
  98. log(`[OK] x64/dependencies.txt: ${x64List.length} packages`, 'green');
  99. log(`[OK] arm64/dependencies.txt: ${arm64List.length} packages`, 'green');
  100. }
  101. main();