@4399ywkf/cli 0.0.5 → 0.0.8
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 +201 -84
- package/package.json +6 -5
package/bin/cli.js
CHANGED
|
@@ -52,9 +52,11 @@ function printFinalInstructions(projectName) {
|
|
|
52
52
|
chalk.cyan("接下来的步骤:"),
|
|
53
53
|
chalk.gray(" 1. 进入项目目录"),
|
|
54
54
|
chalk.white(` cd ${projectName}`),
|
|
55
|
-
chalk.gray(" 2.
|
|
55
|
+
chalk.gray(" 2. 切换Node版本"),
|
|
56
|
+
chalk.white(" nvm use"),
|
|
57
|
+
chalk.gray(" 3. 安装依赖"),
|
|
56
58
|
chalk.white(" pnpm i"),
|
|
57
|
-
chalk.gray("
|
|
59
|
+
chalk.gray(" 4. 启动项目"),
|
|
58
60
|
chalk.white(" pnpm start"),
|
|
59
61
|
"",
|
|
60
62
|
chalk.magenta("🚀 开始你的开发之旅吧!"),
|
|
@@ -73,10 +75,24 @@ function printFinalInstructions(projectName) {
|
|
|
73
75
|
|
|
74
76
|
function cloneRepository(repoUrl, destination) {
|
|
75
77
|
return new Promise((resolve, reject) => {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
+
// 确保URL格式正确,移除可能的末尾斜杠
|
|
79
|
+
const cleanUrl = repoUrl.replace(/\/$/, "");
|
|
80
|
+
const command = `git clone ${cleanUrl} ${destination}`;
|
|
81
|
+
|
|
82
|
+
// 设置子进程选项
|
|
83
|
+
const options = {
|
|
84
|
+
cwd: process.cwd(),
|
|
85
|
+
env: process.env,
|
|
86
|
+
stdio: "pipe",
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
exec(command, options, (error, stdout, stderr) => {
|
|
78
90
|
if (error) {
|
|
79
|
-
|
|
91
|
+
console.error(`命令执行失败: ${command}`);
|
|
92
|
+
console.error(`错误代码: ${error.code}`);
|
|
93
|
+
console.error(`错误信息: ${error.message}`);
|
|
94
|
+
console.error(`stderr: ${stderr}`);
|
|
95
|
+
reject(`Error cloning repository: ${stderr || error.message}`);
|
|
80
96
|
} else {
|
|
81
97
|
resolve(`Repository cloned successfully: ${stdout}`);
|
|
82
98
|
}
|
|
@@ -92,10 +108,10 @@ async function updateEnvTemplate(filePath, config) {
|
|
|
92
108
|
|
|
93
109
|
// 替换模板变量
|
|
94
110
|
const replacements = {
|
|
95
|
-
"{{APP_CNAME}}":
|
|
96
|
-
"{{APP_NAME}}":
|
|
97
|
-
"{{SENTRY_ENABLED}}":
|
|
98
|
-
"{{SENTRY_DSN}}":
|
|
111
|
+
"{{APP_CNAME}}": `${config.appCname}`,
|
|
112
|
+
"{{APP_NAME}}": `${config.appName}`,
|
|
113
|
+
"{{SENTRY_ENABLED}}": `${config.sentryEnabled ? "true" : "false"}`,
|
|
114
|
+
"{{SENTRY_DSN}}": `${config.sentryDsn}`,
|
|
99
115
|
};
|
|
100
116
|
|
|
101
117
|
// 执行替换
|
|
@@ -242,33 +258,44 @@ program
|
|
|
242
258
|
|
|
243
259
|
// 模拟异步获取模版数据
|
|
244
260
|
const templates = {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
261
|
+
microFrontend: {
|
|
262
|
+
webpack: {
|
|
263
|
+
main: [
|
|
264
|
+
{
|
|
265
|
+
value:
|
|
266
|
+
"https://ywgit.gz4399.com/ywkf/webpack-mainApplicate_demo.git",
|
|
267
|
+
name: "webpack-mainApplicate_demo",
|
|
268
|
+
},
|
|
269
|
+
],
|
|
270
|
+
sub: [
|
|
271
|
+
{
|
|
272
|
+
value:
|
|
273
|
+
"https://ywgit.gz4399.com/ywkf/webpack-subApplicate_demo.git",
|
|
274
|
+
name: "webpack-subApplicate_demo",
|
|
275
|
+
},
|
|
276
|
+
],
|
|
277
|
+
},
|
|
278
|
+
vite: {
|
|
279
|
+
main: [
|
|
280
|
+
{
|
|
281
|
+
value:
|
|
282
|
+
"https://ywgit.gz4399.com/ywkf/vite-mainApplicate_demo.git",
|
|
283
|
+
name: "vite-mainApplicate_demo",
|
|
284
|
+
},
|
|
285
|
+
],
|
|
286
|
+
sub: [
|
|
287
|
+
{
|
|
288
|
+
value: "https://ywgit.gz4399.com/ywkf/vite-subApplicate_demo.git",
|
|
289
|
+
name: "vite-subApplicate_demo",
|
|
290
|
+
},
|
|
291
|
+
],
|
|
292
|
+
},
|
|
260
293
|
},
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
{
|
|
264
|
-
value: "https://ywgit.gz4399.com/ywkf/vite-mainApplicate_demo.git",
|
|
265
|
-
name: "vite-mainApplicate_demo",
|
|
266
|
-
},
|
|
267
|
-
],
|
|
268
|
-
sub: [
|
|
294
|
+
standalone: {
|
|
295
|
+
nextjs: [
|
|
269
296
|
{
|
|
270
|
-
value: "https://ywgit.gz4399.com/ywkf/
|
|
271
|
-
name: "
|
|
297
|
+
value: "https://ywgit.gz4399.com/ywkf/next-dome.git",
|
|
298
|
+
name: "next-demo",
|
|
272
299
|
},
|
|
273
300
|
],
|
|
274
301
|
},
|
|
@@ -295,68 +322,154 @@ program
|
|
|
295
322
|
}
|
|
296
323
|
printInfo(`项目名称:${chalk.bold(projectName)}`);
|
|
297
324
|
|
|
298
|
-
// 2.
|
|
299
|
-
const {
|
|
325
|
+
// 2. 选择架构类型
|
|
326
|
+
const { architectureType } = await inquirer.prompt({
|
|
300
327
|
type: "list",
|
|
301
|
-
name: "
|
|
302
|
-
message: chalk.cyan("
|
|
328
|
+
name: "architectureType",
|
|
329
|
+
message: chalk.cyan("🏗️ 请选择架构类型:"),
|
|
303
330
|
choices: [
|
|
304
331
|
{
|
|
305
|
-
name: `${chalk.blue("
|
|
306
|
-
value: "
|
|
332
|
+
name: `${chalk.blue("🧩 微前端架构")} - 支持主应用和子应用`,
|
|
333
|
+
value: "microFrontend",
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
name: `${chalk.green("📱 独立应用")} - 单体应用架构`,
|
|
337
|
+
value: "standalone",
|
|
307
338
|
},
|
|
308
|
-
{ name: `${chalk.green("⚡ Vite")} - 快速的构建工具`, value: "vite" },
|
|
309
|
-
],
|
|
310
|
-
});
|
|
311
|
-
printInfo(`工具类型:${chalk.bold(toolType)}`);
|
|
312
|
-
|
|
313
|
-
// 3. 选择应用方向
|
|
314
|
-
const { appDirection } = await inquirer.prompt({
|
|
315
|
-
type: "list",
|
|
316
|
-
name: "appDirection",
|
|
317
|
-
message: chalk.cyan("🎯 请选择应用方向:"),
|
|
318
|
-
choices: [
|
|
319
|
-
{ name: `${chalk.magenta("🏠 主应用")} - 微前端主应用`, value: "main" },
|
|
320
|
-
{ name: `${chalk.yellow("🧩 子应用")} - 微前端子应用`, value: "sub" },
|
|
321
339
|
],
|
|
322
340
|
});
|
|
323
341
|
printInfo(
|
|
324
|
-
|
|
342
|
+
`架构类型:${chalk.bold(
|
|
343
|
+
architectureType === "microFrontend" ? "微前端架构" : "独立应用"
|
|
344
|
+
)}`
|
|
325
345
|
);
|
|
326
346
|
|
|
327
|
-
// 4. 选择模版
|
|
328
347
|
let projectTemplate;
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
348
|
+
let toolType, appDirection;
|
|
349
|
+
|
|
350
|
+
if (architectureType === "microFrontend") {
|
|
351
|
+
// 微前端架构流程
|
|
352
|
+
// 3. 选择工具类型
|
|
353
|
+
const toolTypeResult = await inquirer.prompt({
|
|
354
|
+
type: "list",
|
|
355
|
+
name: "toolType",
|
|
356
|
+
message: chalk.cyan("🔧 请选择工具类型:"),
|
|
357
|
+
choices: [
|
|
358
|
+
{
|
|
359
|
+
name: `${chalk.blue("📦 Webpack")} - 成熟稳定的打包工具`,
|
|
360
|
+
value: "webpack",
|
|
361
|
+
},
|
|
362
|
+
{ name: `${chalk.green("⚡ Vite")} - 快速的构建工具`, value: "vite" },
|
|
363
|
+
],
|
|
364
|
+
});
|
|
365
|
+
toolType = toolTypeResult.toolType;
|
|
366
|
+
printInfo(`工具类型:${chalk.bold(toolType)}`);
|
|
367
|
+
|
|
368
|
+
// 4. 选择应用方向
|
|
369
|
+
const appDirectionResult = await inquirer.prompt({
|
|
370
|
+
type: "list",
|
|
371
|
+
name: "appDirection",
|
|
372
|
+
message: chalk.cyan("🎯 请选择应用方向:"),
|
|
373
|
+
choices: [
|
|
374
|
+
{
|
|
375
|
+
name: `${chalk.magenta("🏠 主应用")} - 微前端主应用`,
|
|
376
|
+
value: "main",
|
|
377
|
+
},
|
|
378
|
+
{ name: `${chalk.yellow("🧩 子应用")} - 微前端子应用`, value: "sub" },
|
|
379
|
+
],
|
|
380
|
+
});
|
|
381
|
+
appDirection = appDirectionResult.appDirection;
|
|
382
|
+
printInfo(
|
|
383
|
+
`应用方向:${chalk.bold(appDirection === "main" ? "主应用" : "子应用")}`
|
|
333
384
|
);
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
385
|
+
|
|
386
|
+
// 5. 选择模版
|
|
387
|
+
if (options.template) {
|
|
388
|
+
const foundTemplate = templates.microFrontend[toolType][
|
|
389
|
+
appDirection
|
|
390
|
+
].find((template) => template.name === options.template);
|
|
391
|
+
if (foundTemplate) {
|
|
392
|
+
projectTemplate = foundTemplate.value;
|
|
393
|
+
printSuccess(`使用指定模版:${chalk.bold(options.template)}`);
|
|
394
|
+
} else {
|
|
395
|
+
printWarning(`未找到指定模版 "${options.template}",请重新选择`);
|
|
396
|
+
}
|
|
339
397
|
}
|
|
340
|
-
}
|
|
341
398
|
|
|
342
|
-
|
|
343
|
-
|
|
399
|
+
if (!projectTemplate) {
|
|
400
|
+
const availableTemplates =
|
|
401
|
+
templates.microFrontend[toolType][appDirection];
|
|
402
|
+
|
|
403
|
+
// 如果只有一个模版,直接使用它
|
|
404
|
+
if (availableTemplates.length === 1) {
|
|
405
|
+
projectTemplate = availableTemplates[0].value;
|
|
406
|
+
} else {
|
|
407
|
+
// 多个模版时让用户选择
|
|
408
|
+
const { template } = await inquirer.prompt({
|
|
409
|
+
type: "list",
|
|
410
|
+
name: "template",
|
|
411
|
+
message: chalk.cyan("📋 请选择模版:"),
|
|
412
|
+
choices: availableTemplates.map((t) => ({
|
|
413
|
+
name: `${chalk.white(t.name)}`,
|
|
414
|
+
value: t.value,
|
|
415
|
+
})),
|
|
416
|
+
});
|
|
417
|
+
projectTemplate = template;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
} else {
|
|
421
|
+
// 独立应用架构流程
|
|
422
|
+
// 3. 选择框架类型
|
|
423
|
+
const { frameworkType } = await inquirer.prompt({
|
|
424
|
+
type: "list",
|
|
425
|
+
name: "frameworkType",
|
|
426
|
+
message: chalk.cyan("⚛️ 请选择框架类型:"),
|
|
427
|
+
default: "nextjs",
|
|
428
|
+
choices: [
|
|
429
|
+
{
|
|
430
|
+
name: `${chalk.black("▲")} ${chalk.white(
|
|
431
|
+
"Next.js"
|
|
432
|
+
)} - React 全栈框架`,
|
|
433
|
+
value: "nextjs",
|
|
434
|
+
},
|
|
435
|
+
// 可以在这里添加更多独立应用框架
|
|
436
|
+
],
|
|
437
|
+
});
|
|
438
|
+
printInfo(`框架类型:${chalk.bold(frameworkType)}`);
|
|
439
|
+
|
|
440
|
+
// 4. 选择模版
|
|
441
|
+
if (options.template) {
|
|
442
|
+
const foundTemplate = templates.standalone[frameworkType].find(
|
|
443
|
+
(template) => template.name === options.template
|
|
444
|
+
);
|
|
445
|
+
if (foundTemplate) {
|
|
446
|
+
projectTemplate = foundTemplate.value;
|
|
447
|
+
printSuccess(`使用指定模版:${chalk.bold(options.template)}`);
|
|
448
|
+
} else {
|
|
449
|
+
printWarning(`未找到指定模版 "${options.template}",请重新选择`);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
344
452
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
453
|
+
if (!projectTemplate) {
|
|
454
|
+
const availableTemplates = templates.standalone[frameworkType];
|
|
455
|
+
|
|
456
|
+
// 如果只有一个模版,直接使用它
|
|
457
|
+
if (availableTemplates.length === 1) {
|
|
458
|
+
projectTemplate = availableTemplates[0].value;
|
|
459
|
+
printInfo(`使用模版:${chalk.bold(availableTemplates[0].name)}`);
|
|
460
|
+
} else {
|
|
461
|
+
// 多个模版时让用户选择
|
|
462
|
+
const { template } = await inquirer.prompt({
|
|
463
|
+
type: "list",
|
|
464
|
+
name: "template",
|
|
465
|
+
message: chalk.cyan("📋 请选择模版:"),
|
|
466
|
+
choices: availableTemplates.map((t) => ({
|
|
467
|
+
name: `${chalk.white(t.name)}`,
|
|
468
|
+
value: t.value,
|
|
469
|
+
})),
|
|
470
|
+
});
|
|
471
|
+
projectTemplate = template;
|
|
472
|
+
}
|
|
360
473
|
}
|
|
361
474
|
}
|
|
362
475
|
|
|
@@ -389,7 +502,7 @@ program
|
|
|
389
502
|
});
|
|
390
503
|
loading.start();
|
|
391
504
|
|
|
392
|
-
//
|
|
505
|
+
// 6. 开始下载模版
|
|
393
506
|
try {
|
|
394
507
|
const result = await cloneRepository(projectTemplate, dest);
|
|
395
508
|
loading.succeed();
|
|
@@ -403,7 +516,11 @@ program
|
|
|
403
516
|
}
|
|
404
517
|
|
|
405
518
|
// 新添加:如果是 webpack 子应用,进行环境配置
|
|
406
|
-
if (
|
|
519
|
+
if (
|
|
520
|
+
architectureType === "microFrontend" &&
|
|
521
|
+
toolType === "webpack" &&
|
|
522
|
+
appDirection === "sub"
|
|
523
|
+
) {
|
|
407
524
|
console.log(); // 空行
|
|
408
525
|
await configureWebpackSubApp(dest, projectName);
|
|
409
526
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@4399ywkf/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "运维开发部脚手架",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -16,15 +16,16 @@
|
|
|
16
16
|
"author": "",
|
|
17
17
|
"license": "ISC",
|
|
18
18
|
"dependencies": {
|
|
19
|
+
"@changesets/cli": "^2.29.5",
|
|
20
|
+
"boxen": "^5.1.2",
|
|
21
|
+
"chalk": "^4.1.2",
|
|
19
22
|
"child_process": "^1.0.2",
|
|
20
23
|
"commander": "^10.0.1",
|
|
21
24
|
"download-git-repo": "^3.0.2",
|
|
25
|
+
"figlet": "^1.5.2",
|
|
22
26
|
"fs-extra": "^11.1.1",
|
|
23
27
|
"inquirer": "^8.2.5",
|
|
24
|
-
"ora": "^5.4.1"
|
|
25
|
-
"chalk": "^4.1.2",
|
|
26
|
-
"boxen": "^5.1.2",
|
|
27
|
-
"figlet": "^1.5.2"
|
|
28
|
+
"ora": "^5.4.1"
|
|
28
29
|
},
|
|
29
30
|
"files": [
|
|
30
31
|
"bin"
|