react19-build.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #!/usr/bin/env node
  2. const fs = require('fs');
  3. const path = require('path');
  4. const glob = require('glob');
  5. /**
  6. * React 19 构建脚本
  7. * 只进行版本激活,不进行其他操作
  8. */
  9. const REACT_18_START = /\/\* REACT_18_START \*\/([\s\S]*?)\/\* REACT_18_END \*\//g;
  10. const REACT_19_START = /\/\* REACT_19_START \*\/([\s\S]*?)\/\* REACT_19_END \*\//g;
  11. const outputDir = 'packages/semi-ui-19';
  12. function processReact19Code(content) {
  13. // 移除 React 18 的代码块
  14. content = content.replace(REACT_18_START, '');
  15. // 启用 React 19 的代码块(移除注释标记和注释符号)
  16. content = content.replace(REACT_19_START, (match, codeBlock) => {
  17. // 移除每行开头的 // (注意处理缩进)
  18. return codeBlock.replace(/^(\s*)\/\/ /gm, '$1').trim();
  19. });
  20. return content;
  21. }
  22. function processReact18Code(content) {
  23. // 移除 React 19 的代码块
  24. content = content.replace(REACT_19_START, '');
  25. // 启用 React 18 的代码块(仅移除标记)
  26. content = content.replace(REACT_18_START, (match, codeBlock) => {
  27. return codeBlock.trim();
  28. });
  29. return content;
  30. }
  31. function generateReact19PackageJson(sourcePackageJsonPath, outputPackageJsonPath) {
  32. const packageJson = JSON.parse(fs.readFileSync(sourcePackageJsonPath, 'utf8'));
  33. // 修改包名
  34. packageJson.name = '@douyinfe/semi-ui-19';
  35. // 修改描述
  36. packageJson.description = packageJson.description + ' (React 19 Compatible)';
  37. // 添加 React 19 相关的 peerDependencies
  38. if (!packageJson.peerDependencies) {
  39. packageJson.peerDependencies = {};
  40. }
  41. packageJson.peerDependencies.react = '^19.0.0';
  42. packageJson.peerDependencies['react-dom'] = '^19.0.0';
  43. // 添加 React 19 相关的 devDependencies
  44. if (!packageJson.devDependencies) {
  45. packageJson.devDependencies = {};
  46. }
  47. packageJson.devDependencies['@types/react'] = '^19.0.0';
  48. packageJson.devDependencies['@types/react-dom'] = '^19.0.0';
  49. packageJson.devDependencies['react'] = '^19.0.0';
  50. packageJson.devDependencies['react-dom'] = '^19.0.0';
  51. // 更新 null-loader 版本以兼容 webpack 5
  52. packageJson.devDependencies['null-loader'] = '4.0.1';
  53. // 添加 React 19 相关的 engines
  54. if (!packageJson.engines) {
  55. packageJson.engines = {};
  56. }
  57. packageJson.engines.node = '>=18.0.0';
  58. // 添加 React 19 相关的 keywords
  59. if (!packageJson.keywords) {
  60. packageJson.keywords = [];
  61. }
  62. if (!packageJson.keywords.includes('react-19')) {
  63. packageJson.keywords.push('react-19', 'react19');
  64. }
  65. // 写入文件
  66. fs.writeFileSync(outputPackageJsonPath, JSON.stringify(packageJson, null, 2));
  67. console.log(' ✅ 生成 package.json (React 19 版本)');
  68. }
  69. /**
  70. * 生成 React 19 版本的 package.json
  71. */
  72. function generatePackageJson() {
  73. const sourcePackageJsonPath = 'packages/semi-ui/package.json';
  74. const outputPackageJsonPath = path.join(outputDir, 'package.json');
  75. if (fs.existsSync(sourcePackageJsonPath)) {
  76. generateReact19PackageJson(sourcePackageJsonPath, outputPackageJsonPath);
  77. } else {
  78. console.error('❌ 源 package.json 文件不存在');
  79. process.exit(1);
  80. }
  81. }
  82. function buildForReact19() {
  83. const sourceDir = 'packages/semi-ui';
  84. const targetDir = outputDir;
  85. // 需要过滤的目录
  86. const excludeDirs = ['node_modules', 'lib', '.git', 'dist', 'build'];
  87. // 确保输出目录存在
  88. if (!fs.existsSync(targetDir)) {
  89. fs.mkdirSync(targetDir, { recursive: true });
  90. }
  91. // 递归复制所有文件和目录
  92. function copyDirectory(src, dest) {
  93. if (!fs.existsSync(dest)) {
  94. fs.mkdirSync(dest, { recursive: true });
  95. }
  96. const items = fs.readdirSync(src);
  97. items.forEach(item => {
  98. // 跳过需要过滤的目录
  99. if (excludeDirs.includes(item)) {
  100. console.log(` ⏭️ 跳过目录 ${item}`);
  101. return;
  102. }
  103. const srcPath = path.join(src, item);
  104. const destPath = path.join(dest, item);
  105. const stat = fs.statSync(srcPath);
  106. if (stat.isDirectory()) {
  107. // 递归复制子目录
  108. copyDirectory(srcPath, destPath);
  109. } else {
  110. // 复制文件
  111. const relativePath = path.relative(sourceDir, srcPath);
  112. const isTsFile = /\.(ts|tsx)$/.test(item);
  113. const isScssScript = item.includes('compileScss.js');
  114. if (isTsFile || isScssScript) {
  115. // 对 .ts/.tsx 文件进行 React 19 转换
  116. const content = fs.readFileSync(srcPath, 'utf8');
  117. const processedContent = processReact19Code(content);
  118. fs.writeFileSync(destPath, processedContent);
  119. } else {
  120. // 直接复制其他文件
  121. fs.copyFileSync(srcPath, destPath);
  122. }
  123. }
  124. });
  125. }
  126. // 开始复制整个目录
  127. console.log('开始复制所有文件...');
  128. copyDirectory(sourceDir, targetDir);
  129. // 生成 React 19 版本的 package.json(覆盖已复制的)
  130. generatePackageJson();
  131. console.log('✅ React 19 版本构建完成');
  132. }
  133. function buildForReact18() {
  134. const sourcePattern = 'packages/semi-ui/**/*.{ts,tsx}';
  135. const files = glob.sync(sourcePattern);
  136. files.forEach(filePath => {
  137. const content = fs.readFileSync(filePath, 'utf8');
  138. // 只处理版本激活
  139. const processedContent = processReact18Code(content);
  140. // 直接覆盖原文件
  141. fs.writeFileSync(filePath, processedContent);
  142. });
  143. console.log('✅ React 18 版本构建完成');
  144. }
  145. // 命令行参数处理
  146. const args = process.argv.slice(2);
  147. const version = args[0];
  148. if (version === '19') {
  149. buildForReact19();
  150. } else if (version === '18') {
  151. buildForReact18();
  152. } else {
  153. console.log('用法: node scripts/react19-build.js [18|19]');
  154. console.log(' 18: 构建 React 18 兼容版本');
  155. console.log(' 19: 构建 React 19 兼容版本到 packages/semi-ui-19');
  156. }