check-node-version.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #!/usr/bin/env node
  2. import fs from 'node:fs';
  3. import path from 'node:path';
  4. import { fileURLToPath } from 'node:url';
  5. const __filename = fileURLToPath(import.meta.url);
  6. const __dirname = path.dirname(__filename);
  7. const projectRoot = path.join(__dirname, '..');
  8. let preferredVersion;
  9. let supportedRange;
  10. try {
  11. preferredVersion = fs.readFileSync(path.join(projectRoot, '.nvmrc'), 'utf8').trim();
  12. const packageJson = JSON.parse(fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf8'));
  13. supportedRange = packageJson.engines?.node || preferredVersion;
  14. } catch (error) {
  15. console.error('错误: 无法读取 Node.js 版本配置');
  16. process.exit(1);
  17. }
  18. const currentVersion = process.version.slice(1); // 移除版本号前的 'v'
  19. console.log(`检查 Node.js 版本...`);
  20. console.log(`当前版本: ${currentVersion}`);
  21. console.log(`推荐版本: ${preferredVersion}`);
  22. console.log(`支持范围: ${supportedRange}`);
  23. const parseVersion = (version) => {
  24. const match = String(version).trim().replace(/^v/, '').match(/^(\d+)(?:\.(\d+))?(?:\.(\d+))?/);
  25. if (!match) {
  26. throw new Error(`Invalid version: ${version}`);
  27. }
  28. return {
  29. major: Number(match[1]),
  30. minor: Number(match[2] || 0),
  31. patch: Number(match[3] || 0)
  32. };
  33. };
  34. const current = parseVersion(currentVersion);
  35. const compareVersions = (left, right) => {
  36. for (const key of ['major', 'minor', 'patch']) {
  37. if (left[key] > right[key]) return 1;
  38. if (left[key] < right[key]) return -1;
  39. }
  40. return 0;
  41. };
  42. const satisfiesComparator = (version, comparator) => {
  43. const match = comparator.match(/^(>=|>|<=|<|=)?(.+)$/);
  44. const operator = match[1] || '=';
  45. const required = parseVersion(match[2]);
  46. const comparison = compareVersions(version, required);
  47. switch (operator) {
  48. case '>=':
  49. return comparison >= 0;
  50. case '>':
  51. return comparison > 0;
  52. case '<=':
  53. return comparison <= 0;
  54. case '<':
  55. return comparison < 0;
  56. case '=':
  57. return comparison === 0;
  58. default:
  59. return false;
  60. }
  61. };
  62. const satisfiesRange = (version, range) => {
  63. return range
  64. .split('||')
  65. .some((rangePart) =>
  66. rangePart
  67. .trim()
  68. .split(/\s+/)
  69. .filter(Boolean)
  70. .every((comparator) => satisfiesComparator(version, comparator))
  71. );
  72. };
  73. if (!satisfiesRange(current, supportedRange)) {
  74. console.error(`\n错误: Node.js 版本不匹配!`);
  75. console.error(`本项目支持 Node.js ${supportedRange}`);
  76. console.error(`当前使用的是 Node.js ${currentVersion}`);
  77. console.error(`\n请尝试以下方法之一:`);
  78. console.error(`1. 如果已安装 nvm: 运行 'nvm install ${preferredVersion} && nvm use ${preferredVersion}'`);
  79. console.error(`2. 使用项目提供的辅助脚本: './scripts/use-node-version.sh node -v'`);
  80. console.error(`3. 从 https://nodejs.org/ 下载并安装 Node.js ${preferredVersion}`);
  81. process.exit(1);
  82. }
  83. console.log(`\n✓ Node.js 版本检查通过! (${currentVersion})`);