@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.
Files changed (2) hide show
  1. package/bin/cli.js +201 -84
  2. 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(" 3. 启动项目"),
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
- const command = `git clone ${repoUrl} ${destination}`;
77
- exec(command, (error, stdout, stderr) => {
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
- reject(`Error cloning repository: ${stderr}`);
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}}": `"${config.appCname}"`,
96
- "{{APP_NAME}}": `"${config.appName}"`,
97
- "{{SENTRY_ENABLED}}": `"${config.sentryEnabled ? "true" : "false"}"`,
98
- "{{SENTRY_DSN}}": `"${config.sentryDsn}"`,
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
- webpack: {
246
- main: [
247
- {
248
- value:
249
- "https://ywgit.gz4399.com/ywkf/webpack-mainApplicate_demo.git",
250
- name: "webpack-mainApplicate_demo",
251
- },
252
- ],
253
- sub: [
254
- {
255
- value:
256
- "https://ywgit.gz4399.com/ywkf/webpack-subApplicate_demo.git",
257
- name: "webpack-subApplicate_demo",
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
- vite: {
262
- main: [
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/vite-subApplicate_demo",
271
- name: "vite-subApplicate_demo",
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 { toolType } = await inquirer.prompt({
325
+ // 2. 选择架构类型
326
+ const { architectureType } = await inquirer.prompt({
300
327
  type: "list",
301
- name: "toolType",
302
- message: chalk.cyan("🔧 请选择工具类型:"),
328
+ name: "architectureType",
329
+ message: chalk.cyan("🏗️ 请选择架构类型:"),
303
330
  choices: [
304
331
  {
305
- name: `${chalk.blue("📦 Webpack")} - 成熟稳定的打包工具`,
306
- value: "webpack",
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
- `应用方向:${chalk.bold(appDirection === "main" ? "主应用" : "子应用")}`
342
+ `架构类型:${chalk.bold(
343
+ architectureType === "microFrontend" ? "微前端架构" : "独立应用"
344
+ )}`
325
345
  );
326
346
 
327
- // 4. 选择模版
328
347
  let projectTemplate;
329
-
330
- if (options.template) {
331
- const foundTemplate = templates[toolType][appDirection].find(
332
- (template) => template.name === options.template
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
- if (foundTemplate) {
335
- projectTemplate = foundTemplate.value;
336
- printSuccess(`使用指定模版:${chalk.bold(options.template)}`);
337
- } else {
338
- printWarning(`未找到指定模版 "${options.template}",请重新选择`);
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
- if (!projectTemplate) {
343
- const availableTemplates = templates[toolType][appDirection];
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
- if (availableTemplates.length === 1) {
347
- projectTemplate = availableTemplates[0].value;
348
- } else {
349
- // 多个模版时让用户选择
350
- const { template } = await inquirer.prompt({
351
- type: "list",
352
- name: "template",
353
- message: chalk.cyan("📋 请选择模版:"),
354
- choices: availableTemplates.map((t) => ({
355
- name: `${chalk.white(t.name)}`,
356
- value: t.value,
357
- })),
358
- });
359
- projectTemplate = template;
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
- // 5. 开始下载模版
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 (toolType === "webpack" && appDirection === "sub") {
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.5",
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"