generate-nodejs-dependencies.js 4.4 KB

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