| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- #!/usr/bin/env node
- const fs = require('fs');
- const path = require('path');
- const glob = require('glob');
- /**
- * React 19 构建脚本
- * 只进行版本激活,不进行其他操作
- */
- const REACT_18_START = /\/\* REACT_18_START \*\/([\s\S]*?)\/\* REACT_18_END \*\//g;
- const REACT_19_START = /\/\* REACT_19_START \*\/([\s\S]*?)\/\* REACT_19_END \*\//g;
- const outputDir = 'packages/semi-ui-19';
- function processReact19Code(content) {
- // 移除 React 18 的代码块
- content = content.replace(REACT_18_START, '');
-
- // 启用 React 19 的代码块(移除注释标记和注释符号)
- content = content.replace(REACT_19_START, (match, codeBlock) => {
- // 移除每行开头的 // (注意处理缩进)
- return codeBlock.replace(/^(\s*)\/\/ /gm, '$1').trim();
- });
-
- return content;
- }
- function processReact18Code(content) {
- // 移除 React 19 的代码块
- content = content.replace(REACT_19_START, '');
-
- // 启用 React 18 的代码块(仅移除标记)
- content = content.replace(REACT_18_START, (match, codeBlock) => {
- return codeBlock.trim();
- });
-
- return content;
- }
- function generateReact19PackageJson(sourcePackageJsonPath, outputPackageJsonPath) {
- const packageJson = JSON.parse(fs.readFileSync(sourcePackageJsonPath, 'utf8'));
-
- // 修改包名
- packageJson.name = '@douyinfe/semi-ui-19';
-
- // 修改描述
- packageJson.description = packageJson.description + ' (React 19 Compatible)';
-
- // 添加 React 19 相关的 peerDependencies
- if (!packageJson.peerDependencies) {
- packageJson.peerDependencies = {};
- }
- packageJson.peerDependencies.react = '^19.0.0';
- packageJson.peerDependencies['react-dom'] = '^19.0.0';
-
- // 添加 React 19 相关的 devDependencies
- if (!packageJson.devDependencies) {
- packageJson.devDependencies = {};
- }
- packageJson.devDependencies['@types/react'] = '^19.0.0';
- packageJson.devDependencies['@types/react-dom'] = '^19.0.0';
- packageJson.devDependencies['react'] = '^19.0.0';
- packageJson.devDependencies['react-dom'] = '^19.0.0';
-
- // 更新 null-loader 版本以兼容 webpack 5
- packageJson.devDependencies['null-loader'] = '4.0.1';
-
- // 添加 React 19 相关的 engines
- if (!packageJson.engines) {
- packageJson.engines = {};
- }
- packageJson.engines.node = '>=18.0.0';
-
- // 添加 React 19 相关的 keywords
- if (!packageJson.keywords) {
- packageJson.keywords = [];
- }
- if (!packageJson.keywords.includes('react-19')) {
- packageJson.keywords.push('react-19', 'react19');
- }
-
- // 写入文件
- fs.writeFileSync(outputPackageJsonPath, JSON.stringify(packageJson, null, 2));
- console.log(' ✅ 生成 package.json (React 19 版本)');
- }
- /**
- * 生成 React 19 版本的 package.json
- */
- function generatePackageJson() {
- const sourcePackageJsonPath = 'packages/semi-ui/package.json';
- const outputPackageJsonPath = path.join(outputDir, 'package.json');
-
- if (fs.existsSync(sourcePackageJsonPath)) {
- generateReact19PackageJson(sourcePackageJsonPath, outputPackageJsonPath);
- } else {
- console.error('❌ 源 package.json 文件不存在');
- process.exit(1);
- }
- }
- function buildForReact19() {
- const sourceDir = 'packages/semi-ui';
- const targetDir = outputDir;
-
- // 需要过滤的目录
- const excludeDirs = ['node_modules', 'lib', '.git', 'dist', 'build'];
-
- // 确保输出目录存在
- if (!fs.existsSync(targetDir)) {
- fs.mkdirSync(targetDir, { recursive: true });
- }
-
- // 递归复制所有文件和目录
- function copyDirectory(src, dest) {
- if (!fs.existsSync(dest)) {
- fs.mkdirSync(dest, { recursive: true });
- }
-
- const items = fs.readdirSync(src);
-
- items.forEach(item => {
- // 跳过需要过滤的目录
- if (excludeDirs.includes(item)) {
- console.log(` ⏭️ 跳过目录 ${item}`);
- return;
- }
-
- const srcPath = path.join(src, item);
- const destPath = path.join(dest, item);
- const stat = fs.statSync(srcPath);
-
- if (stat.isDirectory()) {
- // 递归复制子目录
- copyDirectory(srcPath, destPath);
- } else {
- // 复制文件
- const relativePath = path.relative(sourceDir, srcPath);
- const isTsFile = /\.(ts|tsx)$/.test(item);
- const isScssScript = item.includes('compileScss.js');
- if (isTsFile || isScssScript) {
- // 对 .ts/.tsx 文件进行 React 19 转换
- const content = fs.readFileSync(srcPath, 'utf8');
- const processedContent = processReact19Code(content);
- fs.writeFileSync(destPath, processedContent);
- } else {
- // 直接复制其他文件
- fs.copyFileSync(srcPath, destPath);
- }
- }
- });
- }
-
- // 开始复制整个目录
- console.log('开始复制所有文件...');
- copyDirectory(sourceDir, targetDir);
-
- // 生成 React 19 版本的 package.json(覆盖已复制的)
- generatePackageJson();
-
- console.log('✅ React 19 版本构建完成');
- }
- function buildForReact18() {
- const sourcePattern = 'packages/semi-ui/**/*.{ts,tsx}';
-
- const files = glob.sync(sourcePattern);
-
- files.forEach(filePath => {
- const content = fs.readFileSync(filePath, 'utf8');
-
- // 只处理版本激活
- const processedContent = processReact18Code(content);
-
- // 直接覆盖原文件
- fs.writeFileSync(filePath, processedContent);
- });
-
- console.log('✅ React 18 版本构建完成');
- }
- // 命令行参数处理
- const args = process.argv.slice(2);
- const version = args[0];
- if (version === '19') {
- buildForReact19();
- } else if (version === '18') {
- buildForReact18();
- } else {
- console.log('用法: node scripts/react19-build.js [18|19]');
- console.log(' 18: 构建 React 18 兼容版本');
- console.log(' 19: 构建 React 19 兼容版本到 packages/semi-ui-19');
- }
|