create-tengits-app 1.0.7 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +22 -0
- package/bin/setup-ttos.js +492 -0
- package/package.json +3 -2
- package/packages/docs/.prettierrc +4 -0
- package/packages/docs/README.md +22 -0
- package/packages/docs/index.html +12 -0
- package/packages/docs/package.json +31 -0
- package/packages/docs/pages/$.mdx +364 -0
- package/packages/docs/pages/_theme.tsx +42 -0
- package/packages/docs/pages/api/api$.md +100 -0
- package/packages/docs/pages/designs/designs$.md +307 -0
- package/packages/docs/pages/develop/develop$.md +867 -0
- package/packages/docs/pages/logs/logs$.md +629 -0
- package/packages/docs/pages/requirements/requirements$.md +1000 -0
- package/packages/docs/pages/test/test$.md +1058 -0
- package/packages/docs/pages/vite-env.d.ts +1 -0
- package/packages/docs/tsconfig.json +10 -0
- package/packages/docs/vite.config.ts +13 -0
- package/packages/main/.env +1 -1
- package/packages/main/dist/manifest.json +6 -6
- package/packages/main/package.json +44 -42
package/bin/cli.js
CHANGED
|
@@ -36,6 +36,28 @@ const createProject = async () => {
|
|
|
36
36
|
console.log('🚀 欢迎使用 Tengits 前端脚手架!');
|
|
37
37
|
console.log('');
|
|
38
38
|
|
|
39
|
+
// 询问是否需要安装ttos
|
|
40
|
+
const installTtos = await getUserInput('是否需要安装 ttos?(默认: 否,如果其他项目安装过ttos,则不需要再安装)[y/N]: ');
|
|
41
|
+
const shouldInstallTtos = installTtos.toLowerCase() === 'y' || installTtos.toLowerCase() === 'yes';
|
|
42
|
+
|
|
43
|
+
if (shouldInstallTtos) {
|
|
44
|
+
console.log('\n🔧 正在安装 ttos...');
|
|
45
|
+
try {
|
|
46
|
+
const setupScriptPath = path.join(__dirname, 'setup-ttos.js');
|
|
47
|
+
if (fs.existsSync(setupScriptPath)) {
|
|
48
|
+
execSync(`node "${setupScriptPath}"`, { stdio: 'inherit' });
|
|
49
|
+
console.log('✅ ttos 安装完成!');
|
|
50
|
+
} else {
|
|
51
|
+
console.log('❌ setup-ttos.js 脚本不存在!');
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.error('❌ ttos 安装失败:', error.message);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
console.log('');
|
|
59
|
+
}
|
|
60
|
+
|
|
39
61
|
// 获取项目名称
|
|
40
62
|
const projectName = await getUserInput('请输入项目名称(默认: my-react-app): ') || 'my-react-app';
|
|
41
63
|
|
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* TTOS项目结构设置脚本
|
|
5
|
+
*
|
|
6
|
+
* 功能:
|
|
7
|
+
* 1. 创建TTOS目录
|
|
8
|
+
* 2. 在TTOS下创建BI、lightRag、liteFlow、saas、tuiLowCode等子目录
|
|
9
|
+
* 3. 为每个目录初始化git仓库(如果不存在)
|
|
10
|
+
* 4. 从远程仓库拉取/更新代码
|
|
11
|
+
* 5. 执行pnpm install安装依赖
|
|
12
|
+
* 6. 将项目暴露到全局(pnpm link -g)
|
|
13
|
+
* 7. 引用全局依赖(pnpm link bi -g)
|
|
14
|
+
* 8. 支持重复执行,自动检测现有仓库并更新
|
|
15
|
+
*
|
|
16
|
+
* 使用方法:
|
|
17
|
+
* 1. 修改下方CONFIG配置中的远程仓库地址、分支和安装目录
|
|
18
|
+
* 2. 运行: node bin/setup-ttos.js
|
|
19
|
+
*
|
|
20
|
+
* 注意事项:
|
|
21
|
+
* - 确保已安装git和pnpm
|
|
22
|
+
* - 确保有访问远程仓库的权限
|
|
23
|
+
* - 确保网络连接正常
|
|
24
|
+
* - Windows系统会自动使用where命令检查工具是否存在
|
|
25
|
+
* - 脚本支持重复执行,会自动检测现有仓库并更新代码
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
const fs = require('fs');
|
|
29
|
+
const path = require('path');
|
|
30
|
+
const { execSync } = require('child_process');
|
|
31
|
+
|
|
32
|
+
// ==================== 配置区域 ====================
|
|
33
|
+
// 请根据实际情况修改以下配置
|
|
34
|
+
//
|
|
35
|
+
// 分支配置说明:
|
|
36
|
+
// - 每个项目可以独立配置分支(branch字段)
|
|
37
|
+
// - 如果项目没有指定branch,将使用全局默认分支(GIT.defaultBranch)
|
|
38
|
+
// - 如果指定分支不存在,会尝试备用分支(GIT.fallbackBranch)
|
|
39
|
+
//
|
|
40
|
+
// 安装目录配置说明:
|
|
41
|
+
// - 每个项目可以独立配置安装依赖的目录(installDir字段)
|
|
42
|
+
// - 如果项目没有指定installDir,将在项目根目录下安装依赖
|
|
43
|
+
// - installDir是相对于项目根目录的路径,如:'src/frontend'
|
|
44
|
+
//
|
|
45
|
+
// 全局链接配置说明:
|
|
46
|
+
// - 所有项目依赖安装完成后,会统一执行全局链接操作
|
|
47
|
+
// - 每个项目都会执行 pnpm link -g 将项目暴露到全局
|
|
48
|
+
// - 每个项目可以独立配置 linkGlobalCommand 来引用特定的全局依赖
|
|
49
|
+
// - 全局链接操作在所有项目依赖安装完成后统一执行
|
|
50
|
+
|
|
51
|
+
const CONFIG = {
|
|
52
|
+
// TTOS根目录名称
|
|
53
|
+
TTOS_DIR: 'TTOS',
|
|
54
|
+
|
|
55
|
+
// 项目配置列表 - 请替换为实际的远程仓库地址
|
|
56
|
+
PROJECTS: [
|
|
57
|
+
{
|
|
58
|
+
name: 'BI',
|
|
59
|
+
remoteUrl: 'https://codeup.aliyun.com/tengits/biqianduan/BI.git',
|
|
60
|
+
description: 'BI数据分析平台',
|
|
61
|
+
linkGlobalCommand: 'pnpm link bisheng -g' // 项目独立的全局链接命令
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: 'Bisheng',
|
|
65
|
+
remoteUrl: 'https://codeup.aliyun.com/tengits/bisheng.git',
|
|
66
|
+
description: '毕昇AI',
|
|
67
|
+
branch: 'tengits_0620', // 项目独立分支配置
|
|
68
|
+
installDir: 'src/frontend/platform', // 指定安装依赖的目录
|
|
69
|
+
linkGlobalCommand: 'pnpm link tui-bi -g' // 项目独立的全局链接命令
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: 'liteFlow',
|
|
73
|
+
remoteUrl: 'https://codeup.aliyun.com/tengits/yewuliuqianduan/lite-flow-editor.git',
|
|
74
|
+
description: '轻量级工作流引擎',
|
|
75
|
+
// linkGlobalCommand: 'pnpm link liteflow -g' // 项目独立的全局链接命令
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'saas',
|
|
79
|
+
remoteUrl: 'https://codeup.aliyun.com/tengits/basicplatform/basic_saas.git',
|
|
80
|
+
description: 'SaaS服务平台',
|
|
81
|
+
linkGlobalCommand: 'pnpm link tui-low-code lite-flow tui-bi -g' // 项目独立的全局链接命令
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'tuiLowCode',
|
|
85
|
+
remoteUrl: 'https://codeup.aliyun.com/tengits/basicplatform/tui-low-code.git',
|
|
86
|
+
description: 'TUI低代码平台',
|
|
87
|
+
linkGlobalCommand: 'pnpm link tui-bi -g' // 项目独立的全局链接命令
|
|
88
|
+
}
|
|
89
|
+
],
|
|
90
|
+
|
|
91
|
+
// Git配置
|
|
92
|
+
GIT: {
|
|
93
|
+
defaultBranch: 'master', // 默认分支
|
|
94
|
+
fallbackBranch: 'develop' // 备用分支
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
// 包管理器配置
|
|
98
|
+
PACKAGE_MANAGER: {
|
|
99
|
+
command: 'pnpm',
|
|
100
|
+
installCommand: 'pnpm install',
|
|
101
|
+
linkCommand: 'pnpm link -g',
|
|
102
|
+
linkGlobalCommand: 'pnpm link bi -g' // 引用全局依赖的命令
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
// ==================== 脚本逻辑 ====================
|
|
107
|
+
|
|
108
|
+
// 颜色输出函数
|
|
109
|
+
const colors = {
|
|
110
|
+
reset: '\x1b[0m',
|
|
111
|
+
bright: '\x1b[1m',
|
|
112
|
+
red: '\x1b[31m',
|
|
113
|
+
green: '\x1b[32m',
|
|
114
|
+
yellow: '\x1b[33m',
|
|
115
|
+
blue: '\x1b[34m',
|
|
116
|
+
magenta: '\x1b[35m',
|
|
117
|
+
cyan: '\x1b[36m'
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
function log(message, color = 'reset') {
|
|
121
|
+
console.log(`${colors[color]}${message}${colors.reset}`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function logStep(step, message) {
|
|
125
|
+
log(`[${step}] ${message}`, 'cyan');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function logSuccess(message) {
|
|
129
|
+
log(`✅ ${message}`, 'green');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function logError(message) {
|
|
133
|
+
log(`❌ ${message}`, 'red');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function logWarning(message) {
|
|
137
|
+
log(`⚠️ ${message}`, 'yellow');
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// 检查目录是否已存在且包含git仓库
|
|
141
|
+
function checkExistingRepository(projectPath) {
|
|
142
|
+
try {
|
|
143
|
+
const gitPath = path.join(projectPath, '.git');
|
|
144
|
+
return fs.existsSync(projectPath) && fs.existsSync(gitPath);
|
|
145
|
+
} catch (error) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// 更新现有git仓库
|
|
151
|
+
function updateExistingRepository(projectPath, remoteUrl, projectBranch) {
|
|
152
|
+
try {
|
|
153
|
+
logStep('UPDATE', '更新现有git仓库...');
|
|
154
|
+
|
|
155
|
+
// 检查远程仓库是否已配置
|
|
156
|
+
try {
|
|
157
|
+
execSync('git remote get-url origin', { cwd: projectPath, stdio: 'ignore' });
|
|
158
|
+
} catch {
|
|
159
|
+
// 如果远程仓库未配置,添加它
|
|
160
|
+
if (!executeCommand(`git remote add origin ${remoteUrl}`, projectPath, '添加远程仓库')) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// 获取最新代码
|
|
166
|
+
const targetBranch = projectBranch || CONFIG.GIT.defaultBranch;
|
|
167
|
+
|
|
168
|
+
// 先fetch所有分支
|
|
169
|
+
if (!executeCommand('git fetch origin', projectPath, '获取远程更新')) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// 检查目标分支是否存在
|
|
174
|
+
try {
|
|
175
|
+
execSync(`git rev-parse --verify origin/${targetBranch}`, { cwd: projectPath, stdio: 'ignore' });
|
|
176
|
+
} catch {
|
|
177
|
+
logWarning(`远程分支 ${targetBranch} 不存在,尝试 ${CONFIG.GIT.fallbackBranch}...`);
|
|
178
|
+
const fallbackBranch = CONFIG.GIT.fallbackBranch;
|
|
179
|
+
try {
|
|
180
|
+
execSync(`git rev-parse --verify origin/${fallbackBranch}`, { cwd: projectPath, stdio: 'ignore' });
|
|
181
|
+
// 使用备用分支
|
|
182
|
+
if (!executeCommand(`git checkout -B ${fallbackBranch} origin/${fallbackBranch}`, projectPath, `切换到${fallbackBranch}分支`)) {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
logSuccess(`代码更新成功: ${projectPath} (分支: ${fallbackBranch})`);
|
|
186
|
+
return true;
|
|
187
|
+
} catch {
|
|
188
|
+
logError(`远程分支 ${targetBranch} 和 ${fallbackBranch} 都不存在`);
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// 切换到目标分支并拉取最新代码
|
|
194
|
+
if (!executeCommand(`git checkout -B ${targetBranch} origin/${targetBranch}`, projectPath, `切换到${targetBranch}分支`)) {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
logSuccess(`代码更新成功: ${projectPath} (分支: ${targetBranch})`);
|
|
199
|
+
return true;
|
|
200
|
+
} catch (error) {
|
|
201
|
+
logError(`Git仓库更新失败: ${projectPath}`);
|
|
202
|
+
logError(`错误信息: ${error.message}`);
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// 检查命令是否存在
|
|
208
|
+
function checkCommand(command) {
|
|
209
|
+
try {
|
|
210
|
+
// Windows使用where命令,Unix系统使用which命令
|
|
211
|
+
const checkCmd = process.platform === 'win32' ? `where ${command}` : `which ${command}`;
|
|
212
|
+
execSync(checkCmd, { stdio: 'ignore' });
|
|
213
|
+
return true;
|
|
214
|
+
} catch {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// 执行命令并处理错误
|
|
220
|
+
function executeCommand(command, cwd = process.cwd(), description = '') {
|
|
221
|
+
try {
|
|
222
|
+
logStep('EXEC', `${description || command}`);
|
|
223
|
+
execSync(command, {
|
|
224
|
+
cwd,
|
|
225
|
+
stdio: 'inherit',
|
|
226
|
+
encoding: 'utf8'
|
|
227
|
+
});
|
|
228
|
+
return true;
|
|
229
|
+
} catch (error) {
|
|
230
|
+
logError(`命令执行失败: ${command}`);
|
|
231
|
+
logError(`错误信息: ${error.message}`);
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// 创建目录
|
|
237
|
+
function createDirectory(dirPath) {
|
|
238
|
+
try {
|
|
239
|
+
if (!fs.existsSync(dirPath)) {
|
|
240
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
241
|
+
logSuccess(`目录创建成功: ${dirPath}`);
|
|
242
|
+
return true;
|
|
243
|
+
} else {
|
|
244
|
+
logWarning(`目录已存在: ${dirPath}`);
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
247
|
+
} catch (error) {
|
|
248
|
+
logError(`目录创建失败: ${dirPath}`);
|
|
249
|
+
logError(`错误信息: ${error.message}`);
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// 初始化git仓库并拉取代码
|
|
255
|
+
function setupGitRepository(projectPath, remoteUrl, projectBranch) {
|
|
256
|
+
try {
|
|
257
|
+
// 初始化git仓库
|
|
258
|
+
if (!executeCommand('git init', projectPath, '初始化git仓库')) {
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// 添加远程仓库
|
|
263
|
+
if (!executeCommand(`git remote add origin ${remoteUrl}`, projectPath, '添加远程仓库')) {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// 使用项目指定的分支,如果没有指定则使用全局默认分支
|
|
268
|
+
const targetBranch = projectBranch || CONFIG.GIT.defaultBranch;
|
|
269
|
+
|
|
270
|
+
// 拉取代码
|
|
271
|
+
if (!executeCommand(`git pull origin ${targetBranch}`, projectPath, `拉取${targetBranch}分支代码`)) {
|
|
272
|
+
// 如果指定分支不存在,尝试备用分支
|
|
273
|
+
logWarning(`${targetBranch}分支拉取失败,尝试${CONFIG.GIT.fallbackBranch}分支...`);
|
|
274
|
+
if (!executeCommand(`git pull origin ${CONFIG.GIT.fallbackBranch}`, projectPath, `拉取${CONFIG.GIT.fallbackBranch}分支代码`)) {
|
|
275
|
+
logError('无法拉取代码,请检查远程仓库地址和网络连接');
|
|
276
|
+
logError(`尝试的分支: ${targetBranch}, ${CONFIG.GIT.fallbackBranch}`);
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
logSuccess(`代码拉取成功: ${projectPath} (分支: ${targetBranch})`);
|
|
282
|
+
return true;
|
|
283
|
+
} catch (error) {
|
|
284
|
+
logError(`Git仓库设置失败: ${projectPath}`);
|
|
285
|
+
logError(`错误信息: ${error.message}`);
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// 安装依赖
|
|
291
|
+
function installDependencies(projectPath, installDir = null) {
|
|
292
|
+
try {
|
|
293
|
+
// 确定安装目录
|
|
294
|
+
const installPath = installDir ? path.join(projectPath, installDir) : projectPath;
|
|
295
|
+
|
|
296
|
+
logStep('DEBUG', `项目路径: ${projectPath}`);
|
|
297
|
+
logStep('DEBUG', `安装目录: ${installDir || '根目录'}`);
|
|
298
|
+
logStep('DEBUG', `实际安装路径: ${installPath}`);
|
|
299
|
+
|
|
300
|
+
// 检查package.json是否存在
|
|
301
|
+
const packageJsonPath = path.join(installPath, 'package.json');
|
|
302
|
+
logStep('DEBUG', `检查package.json: ${packageJsonPath}`);
|
|
303
|
+
|
|
304
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
305
|
+
logWarning(`未找到package.json文件: ${installPath}`);
|
|
306
|
+
logWarning(`请检查路径是否正确: ${packageJsonPath}`);
|
|
307
|
+
return true; // 不是错误,只是跳过
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
logSuccess(`找到package.json文件: ${packageJsonPath}`);
|
|
311
|
+
|
|
312
|
+
// 执行包管理器安装命令
|
|
313
|
+
const installDescription = installDir ?
|
|
314
|
+
`在 ${installDir} 目录下安装项目依赖` :
|
|
315
|
+
'安装项目依赖';
|
|
316
|
+
|
|
317
|
+
logStep('INSTALL', `准备在 ${installPath} 执行: ${CONFIG.PACKAGE_MANAGER.installCommand}`);
|
|
318
|
+
|
|
319
|
+
if (!executeCommand(CONFIG.PACKAGE_MANAGER.installCommand, installPath, installDescription)) {
|
|
320
|
+
logError(`依赖安装失败: ${installPath}`);
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// 将项目暴露到全局
|
|
325
|
+
logStep('LINK', `将项目暴露到全局...`);
|
|
326
|
+
executeCommand(CONFIG.PACKAGE_MANAGER.linkCommand, installPath, '暴露项目到全局');
|
|
327
|
+
|
|
328
|
+
const successMessage = installDir ?
|
|
329
|
+
`依赖安装成功: ${projectPath} (目录: ${installDir})` :
|
|
330
|
+
`依赖安装成功: ${projectPath}`;
|
|
331
|
+
logSuccess(successMessage);
|
|
332
|
+
return true;
|
|
333
|
+
} catch (error) {
|
|
334
|
+
logError(`依赖安装失败: ${projectPath}`);
|
|
335
|
+
logError(`错误信息: ${error.message}`);
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// 执行全局链接操作
|
|
341
|
+
function executeGlobalLinking(projectPath, project) {
|
|
342
|
+
try {
|
|
343
|
+
const installPath = project.installDir ? path.join(projectPath, project.installDir) : projectPath;
|
|
344
|
+
|
|
345
|
+
logStep('LINK', `处理项目 ${project.name} 的全局链接...`);
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
// 引用全局依赖(如果配置了)
|
|
349
|
+
if (project.linkGlobalCommand) {
|
|
350
|
+
if (!executeCommand(project.linkGlobalCommand, installPath, `引用 ${project.name} 的全局依赖`)) {
|
|
351
|
+
logWarning(`项目 ${project.name} 全局依赖引用失败`);
|
|
352
|
+
return false;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
logSuccess(`项目 ${project.name} 全局链接完成`);
|
|
357
|
+
return true;
|
|
358
|
+
} catch (error) {
|
|
359
|
+
logError(`项目 ${project.name} 全局链接失败`);
|
|
360
|
+
logError(`错误信息: ${error.message}`);
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// 主函数
|
|
366
|
+
async function main() {
|
|
367
|
+
log('🚀 开始设置TTOS项目结构...', 'bright');
|
|
368
|
+
log('', 'reset');
|
|
369
|
+
|
|
370
|
+
// 检查必要的命令
|
|
371
|
+
logStep('CHECK', '检查必要的命令...');
|
|
372
|
+
if (!checkCommand('git')) {
|
|
373
|
+
logError('Git未安装或不在PATH中');
|
|
374
|
+
process.exit(1);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
if (!checkCommand(CONFIG.PACKAGE_MANAGER.command)) {
|
|
378
|
+
logError(`${CONFIG.PACKAGE_MANAGER.command}未安装或不在PATH中`);
|
|
379
|
+
logWarning(`请先安装${CONFIG.PACKAGE_MANAGER.command}: npm install -g ${CONFIG.PACKAGE_MANAGER.command}`);
|
|
380
|
+
if (process.platform === 'win32') {
|
|
381
|
+
logWarning('Windows用户也可以使用: npm install -g pnpm');
|
|
382
|
+
}
|
|
383
|
+
process.exit(1);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
logSuccess('所有必要命令检查通过');
|
|
387
|
+
|
|
388
|
+
// 创建TTOS目录
|
|
389
|
+
logStep('CREATE', '创建TTOS目录...');
|
|
390
|
+
const ttosPath = path.join(process.cwd(), CONFIG.TTOS_DIR);
|
|
391
|
+
if (!createDirectory(ttosPath)) {
|
|
392
|
+
process.exit(1);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// 处理每个项目
|
|
396
|
+
let successCount = 0;
|
|
397
|
+
let totalCount = CONFIG.PROJECTS.length;
|
|
398
|
+
const successfulProjects = []; // 存储成功安装依赖的项目
|
|
399
|
+
|
|
400
|
+
for (const project of CONFIG.PROJECTS) {
|
|
401
|
+
log('', 'reset');
|
|
402
|
+
log(`📁 处理项目: ${project.name}`, 'magenta');
|
|
403
|
+
|
|
404
|
+
const projectPath = path.join(ttosPath, project.name);
|
|
405
|
+
|
|
406
|
+
// 检查是否已存在git仓库
|
|
407
|
+
const isExistingRepo = checkExistingRepository(projectPath);
|
|
408
|
+
|
|
409
|
+
if (isExistingRepo) {
|
|
410
|
+
logStep('EXIST', `发现现有仓库: ${project.name}`);
|
|
411
|
+
|
|
412
|
+
// 更新现有仓库
|
|
413
|
+
if (!updateExistingRepository(projectPath, project.remoteUrl, project.branch)) {
|
|
414
|
+
logError(`项目 ${project.name} 更新失败`);
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
} else {
|
|
418
|
+
// 创建项目目录
|
|
419
|
+
if (!createDirectory(projectPath)) {
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// 设置新的git仓库并拉取代码
|
|
424
|
+
if (!setupGitRepository(projectPath, project.remoteUrl, project.branch)) {
|
|
425
|
+
logError(`项目 ${project.name} 设置失败`);
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// 安装依赖(无论新旧仓库都需要)
|
|
431
|
+
if (!installDependencies(projectPath, project.installDir)) {
|
|
432
|
+
logError(`项目 ${project.name} 依赖安装失败`);
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
successCount++;
|
|
437
|
+
successfulProjects.push({ projectPath, project });
|
|
438
|
+
logSuccess(`项目 ${project.name} 处理完成`);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// 所有项目依赖安装完成后,执行全局链接操作
|
|
442
|
+
log('', 'reset');
|
|
443
|
+
log('🔗 开始执行全局链接操作...', 'bright');
|
|
444
|
+
|
|
445
|
+
let linkSuccessCount = 0;
|
|
446
|
+
for (const { projectPath, project } of successfulProjects) {
|
|
447
|
+
log('', 'reset');
|
|
448
|
+
log(`🔗 处理项目: ${project.name}`, 'cyan');
|
|
449
|
+
|
|
450
|
+
if (executeGlobalLinking(projectPath, project)) {
|
|
451
|
+
linkSuccessCount++;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// 输出总结
|
|
456
|
+
log('', 'reset');
|
|
457
|
+
log('📊 设置完成总结:', 'bright');
|
|
458
|
+
log(`✅ 项目设置成功: ${successCount}/${totalCount} 个项目`, 'green');
|
|
459
|
+
log(`🔗 全局链接成功: ${linkSuccessCount}/${successfulProjects.length} 个项目`, 'cyan');
|
|
460
|
+
|
|
461
|
+
if (successCount < totalCount) {
|
|
462
|
+
log(`❌ 项目设置失败: ${totalCount - successCount} 个项目`, 'red');
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
if (linkSuccessCount < successfulProjects.length) {
|
|
466
|
+
log(`⚠️ 全局链接失败: ${successfulProjects.length - linkSuccessCount} 个项目`, 'yellow');
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
log('', 'reset');
|
|
470
|
+
log(`📂 TTOS目录位置: ${ttosPath}`, 'cyan');
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// 错误处理
|
|
474
|
+
process.on('uncaughtException', (error) => {
|
|
475
|
+
logError(`未捕获的异常: ${error.message}`);
|
|
476
|
+
process.exit(1);
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
480
|
+
logError(`未处理的Promise拒绝: ${reason}`);
|
|
481
|
+
process.exit(1);
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
// 运行主函数
|
|
485
|
+
if (require.main === module) {
|
|
486
|
+
main().catch((error) => {
|
|
487
|
+
logError(`脚本执行失败: ${error.message}`);
|
|
488
|
+
process.exit(1);
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
module.exports = { main };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-tengits-app",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "🚀 快速创建基于 React + Rsbuild + TypeScript + Tailwind CSS + Antd 的现代前端项目脚手架",
|
|
5
5
|
"author": "",
|
|
6
6
|
"license": "MIT",
|
|
@@ -42,7 +42,8 @@
|
|
|
42
42
|
"preview": "pnpm --filter main preview",
|
|
43
43
|
"doctor": "pnpm --filter main doctor",
|
|
44
44
|
"install-all": "pnpm install",
|
|
45
|
-
"test-cli": "node bin/cli.js"
|
|
45
|
+
"test-cli": "node bin/cli.js",
|
|
46
|
+
"setup-ttos": "node bin/setup-ttos.js"
|
|
46
47
|
},
|
|
47
48
|
"dependencies": {
|
|
48
49
|
"fs-extra": "^11.2.0",
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
## vite-pages app starter
|
|
2
|
+
|
|
3
|
+
This is a demo project for [vite-plugin-react-pages](https://github.com/vitejs/vite-plugin-react-pages).
|
|
4
|
+
This project demonstrate how to develop a React app using [vite-plugin-react-pages](https://github.com/vitejs/vite-plugin-react-pages) as framework.
|
|
5
|
+
|
|
6
|
+
You can run this demo in [StackBlitz](https://stackblitz.com/fork/github/vitejs/vite-plugin-react-pages/tree/main/packages/create-project/template-app?file=README.md&terminal=dev), entirely in your browser!
|
|
7
|
+
|
|
8
|
+
# How to use
|
|
9
|
+
|
|
10
|
+
`npm install` or `pnpm install` or `yarn`
|
|
11
|
+
|
|
12
|
+
`npm run dev` You can now play with the local develop environment.
|
|
13
|
+
|
|
14
|
+
Edit `pages/page1$.tsx` or other source files, the playground will inflect your change instantly.
|
|
15
|
+
|
|
16
|
+
`npm run build` The app are built and served.
|
|
17
|
+
|
|
18
|
+
`npm run ssr` The app are built into a static site (Static-Site Generation) and served.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
Checkout [vite-plugin-react-pages](https://github.com/vitejs/vite-plugin-react-pages) for more info.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>腾路项目管理</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="root"></div>
|
|
10
|
+
<script type="module" src="/@pages-infra/main.js"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "app-demo",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite serve",
|
|
8
|
+
"build": "rimraf dist && vite build --outDir dist && serve -s dist",
|
|
9
|
+
"ssr": "rimraf dist && vite-pages ssr && serve dist"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [],
|
|
12
|
+
"author": "",
|
|
13
|
+
"license": "ISC",
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@vitejs/plugin-react-swc": "^4.1.0",
|
|
16
|
+
"react": "^18.2.0",
|
|
17
|
+
"react-dom": "^18.2.0",
|
|
18
|
+
"react-router-dom": "^6.21.3"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@mdx-js/react": "^3.0.0",
|
|
22
|
+
"@types/node": "^20.11.5",
|
|
23
|
+
"@types/react": "^18.2.48",
|
|
24
|
+
"@vitejs/plugin-react": "^4.2.1",
|
|
25
|
+
"rimraf": "^5.0.5",
|
|
26
|
+
"serve": "^14.2.1",
|
|
27
|
+
"vite": "^5.0.12",
|
|
28
|
+
"vite-pages-theme-doc": "^5.0.0",
|
|
29
|
+
"vite-plugin-react-pages": "^5.0.0"
|
|
30
|
+
}
|
|
31
|
+
}
|