@4399ywkf/cli 0.0.3 → 0.0.4
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 -69
- package/package.json +17 -7
package/bin/cli.js
CHANGED
|
@@ -1,14 +1,75 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const program = require("commander")
|
|
3
|
-
const inquirer = require("inquirer")
|
|
4
|
-
const path = require("path")
|
|
5
|
-
const ora = require(
|
|
6
|
-
const fs = require(
|
|
7
|
-
const { exec } = require(
|
|
2
|
+
const program = require("commander");
|
|
3
|
+
const inquirer = require("inquirer");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const ora = require("ora");
|
|
6
|
+
const fs = require("fs-extra");
|
|
7
|
+
const { exec } = require("child_process");
|
|
8
|
+
|
|
9
|
+
// 美化输出相关
|
|
10
|
+
const chalk = require("chalk");
|
|
11
|
+
const boxen = require("boxen");
|
|
12
|
+
const figlet = require("figlet");
|
|
8
13
|
|
|
9
14
|
// const templates = require("./templates.js")
|
|
10
|
-
const { getGitReposList } = require(
|
|
11
|
-
const package = require("../package.json")
|
|
15
|
+
const { getGitReposList } = require("./api.js");
|
|
16
|
+
const package = require("../package.json");
|
|
17
|
+
|
|
18
|
+
// 美化输出函数
|
|
19
|
+
function printBanner() {
|
|
20
|
+
console.log(
|
|
21
|
+
chalk.cyan(
|
|
22
|
+
figlet.textSync("YWKF CLI", {
|
|
23
|
+
font: "Standard",
|
|
24
|
+
horizontalLayout: "default",
|
|
25
|
+
verticalLayout: "default",
|
|
26
|
+
})
|
|
27
|
+
)
|
|
28
|
+
);
|
|
29
|
+
console.log(chalk.gray(`版本: ${package.version}\n`));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function printSuccess(message) {
|
|
33
|
+
console.log(chalk.green("✅ " + message));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function printError(message) {
|
|
37
|
+
console.log(chalk.red("❌ " + message));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function printInfo(message) {
|
|
41
|
+
console.log(chalk.blue("ℹ️ " + message));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function printWarning(message) {
|
|
45
|
+
console.log(chalk.yellow("⚠️ " + message));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function printFinalInstructions(projectName) {
|
|
49
|
+
const instructions = [
|
|
50
|
+
chalk.green("🎉 项目创建成功!"),
|
|
51
|
+
"",
|
|
52
|
+
chalk.cyan("接下来的步骤:"),
|
|
53
|
+
chalk.gray(" 1. 进入项目目录"),
|
|
54
|
+
chalk.white(` cd ${projectName}`),
|
|
55
|
+
chalk.gray(" 2. 安装依赖"),
|
|
56
|
+
chalk.white(" pnpm i"),
|
|
57
|
+
chalk.gray(" 3. 启动项目"),
|
|
58
|
+
chalk.white(" pnpm start"),
|
|
59
|
+
"",
|
|
60
|
+
chalk.magenta("🚀 开始你的开发之旅吧!"),
|
|
61
|
+
].join("\n");
|
|
62
|
+
|
|
63
|
+
console.log(
|
|
64
|
+
boxen(instructions, {
|
|
65
|
+
padding: 1,
|
|
66
|
+
margin: 1,
|
|
67
|
+
borderStyle: "round",
|
|
68
|
+
borderColor: "cyan",
|
|
69
|
+
backgroundColor: "black",
|
|
70
|
+
})
|
|
71
|
+
);
|
|
72
|
+
}
|
|
12
73
|
|
|
13
74
|
function cloneRepository(repoUrl, destination) {
|
|
14
75
|
return new Promise((resolve, reject) => {
|
|
@@ -26,119 +87,190 @@ function cloneRepository(repoUrl, destination) {
|
|
|
26
87
|
program
|
|
27
88
|
.command("create [projectName]")
|
|
28
89
|
.description("创建模版")
|
|
29
|
-
.option(
|
|
90
|
+
.option("-t, --template <template>", "模版名称")
|
|
30
91
|
.action(async (projectName, options) => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
92
|
+
// 显示Banner
|
|
93
|
+
printBanner();
|
|
94
|
+
|
|
95
|
+
const getRepoLoading = ora({
|
|
96
|
+
text: "正在获取模版列表...",
|
|
97
|
+
spinner: "dots",
|
|
98
|
+
});
|
|
99
|
+
getRepoLoading.start();
|
|
100
|
+
|
|
101
|
+
// 模拟异步获取模版数据
|
|
34
102
|
const templates = {
|
|
35
103
|
webpack: {
|
|
36
104
|
main: [
|
|
37
105
|
{
|
|
38
|
-
value:
|
|
39
|
-
|
|
40
|
-
|
|
106
|
+
value:
|
|
107
|
+
"https://ywgit.gz4399.com/ywkf/webpack-mainApplicate_demo.git",
|
|
108
|
+
name: "webpack-mainApplicate_demo",
|
|
109
|
+
},
|
|
41
110
|
],
|
|
42
111
|
sub: [
|
|
43
112
|
{
|
|
44
|
-
value:
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
113
|
+
value:
|
|
114
|
+
"https://ywgit.gz4399.com/ywkf/webpack-subApplicate_demo.git",
|
|
115
|
+
name: "webpack-subApplicate_demo",
|
|
116
|
+
},
|
|
117
|
+
],
|
|
48
118
|
},
|
|
49
119
|
vite: {
|
|
50
120
|
main: [
|
|
51
121
|
{
|
|
52
122
|
value: "https://ywgit.gz4399.com/ywkf/vite-mainApplicate_demo.git",
|
|
53
|
-
name: "vite-mainApplicate_demo"
|
|
54
|
-
}
|
|
123
|
+
name: "vite-mainApplicate_demo",
|
|
124
|
+
},
|
|
55
125
|
],
|
|
56
126
|
sub: [
|
|
57
127
|
{
|
|
58
128
|
value: "https://ywgit.gz4399.com/ywkf/vite-subApplicate_demo",
|
|
59
|
-
name: "vite-subApplicate_demo"
|
|
60
|
-
}
|
|
61
|
-
]
|
|
62
|
-
}
|
|
63
|
-
}
|
|
129
|
+
name: "vite-subApplicate_demo",
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
};
|
|
64
134
|
|
|
65
|
-
getRepoLoading.succeed(
|
|
135
|
+
getRepoLoading.succeed();
|
|
136
|
+
printSuccess("模版列表获取成功!");
|
|
137
|
+
console.log(); // 空行
|
|
66
138
|
|
|
67
139
|
// 1. 如果用户没有传入名称就交互式输入
|
|
68
140
|
if (!projectName) {
|
|
69
141
|
const { name } = await inquirer.prompt({
|
|
70
142
|
type: "input",
|
|
71
143
|
name: "name",
|
|
72
|
-
message: "请输入项目名称:",
|
|
73
|
-
|
|
74
|
-
|
|
144
|
+
message: chalk.cyan("📝 请输入项目名称:"),
|
|
145
|
+
validate: (input) => {
|
|
146
|
+
if (!input.trim()) {
|
|
147
|
+
return "项目名称不能为空!";
|
|
148
|
+
}
|
|
149
|
+
return true;
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
projectName = name;
|
|
75
153
|
}
|
|
76
|
-
|
|
154
|
+
printInfo(`项目名称:${chalk.bold(projectName)}`);
|
|
77
155
|
|
|
78
156
|
// 2. 选择工具类型
|
|
79
157
|
const { toolType } = await inquirer.prompt({
|
|
80
|
-
type:
|
|
81
|
-
name:
|
|
82
|
-
message:
|
|
83
|
-
choices: [
|
|
84
|
-
|
|
85
|
-
|
|
158
|
+
type: "list",
|
|
159
|
+
name: "toolType",
|
|
160
|
+
message: chalk.cyan("🔧 请选择工具类型:"),
|
|
161
|
+
choices: [
|
|
162
|
+
{
|
|
163
|
+
name: `${chalk.blue("📦 Webpack")} - 成熟稳定的打包工具`,
|
|
164
|
+
value: "webpack",
|
|
165
|
+
},
|
|
166
|
+
{ name: `${chalk.green("⚡ Vite")} - 快速的构建工具`, value: "vite" },
|
|
167
|
+
],
|
|
168
|
+
});
|
|
169
|
+
printInfo(`工具类型:${chalk.bold(toolType)}`);
|
|
86
170
|
|
|
87
171
|
// 3. 选择应用方向
|
|
88
172
|
const { appDirection } = await inquirer.prompt({
|
|
89
|
-
type:
|
|
90
|
-
name:
|
|
91
|
-
message:
|
|
92
|
-
choices: [
|
|
93
|
-
|
|
94
|
-
|
|
173
|
+
type: "list",
|
|
174
|
+
name: "appDirection",
|
|
175
|
+
message: chalk.cyan("🎯 请选择应用方向:"),
|
|
176
|
+
choices: [
|
|
177
|
+
{ name: `${chalk.magenta("🏠 主应用")} - 微前端主应用`, value: "main" },
|
|
178
|
+
{ name: `${chalk.yellow("🧩 子应用")} - 微前端子应用`, value: "sub" },
|
|
179
|
+
],
|
|
180
|
+
});
|
|
181
|
+
printInfo(
|
|
182
|
+
`应用方向:${chalk.bold(appDirection === "main" ? "主应用" : "子应用")}`
|
|
183
|
+
);
|
|
95
184
|
|
|
96
185
|
// 4. 选择模版
|
|
97
186
|
let projectTemplate;
|
|
98
187
|
if (options.template) {
|
|
99
|
-
projectTemplate = templates[toolType][appDirection].find(
|
|
188
|
+
projectTemplate = templates[toolType][appDirection].find(
|
|
189
|
+
(template) => template.name === options.template
|
|
190
|
+
)?.value;
|
|
191
|
+
if (projectTemplate) {
|
|
192
|
+
printSuccess(`使用指定模版:${chalk.bold(options.template)}`);
|
|
193
|
+
} else {
|
|
194
|
+
printWarning(`未找到指定模版 "${options.template}",请重新选择`);
|
|
195
|
+
}
|
|
100
196
|
}
|
|
101
197
|
|
|
102
198
|
if (!projectTemplate) {
|
|
103
199
|
const { template } = await inquirer.prompt({
|
|
104
|
-
type:
|
|
105
|
-
name:
|
|
106
|
-
message:
|
|
107
|
-
choices: templates[toolType][appDirection]
|
|
108
|
-
|
|
109
|
-
|
|
200
|
+
type: "list",
|
|
201
|
+
name: "template",
|
|
202
|
+
message: chalk.cyan("📋 请选择模版:"),
|
|
203
|
+
choices: templates[toolType][appDirection].map((t) => ({
|
|
204
|
+
name: `${chalk.white(t.name)}`,
|
|
205
|
+
value: t.value,
|
|
206
|
+
})),
|
|
207
|
+
});
|
|
208
|
+
projectTemplate = template;
|
|
110
209
|
}
|
|
111
|
-
|
|
210
|
+
|
|
211
|
+
console.log(); // 空行
|
|
112
212
|
|
|
113
213
|
// 获取目标文件夹路径
|
|
114
|
-
const dest = path.join(process.cwd(), projectName)
|
|
214
|
+
const dest = path.join(process.cwd(), projectName);
|
|
115
215
|
// 判断文件夹是否存在,存在就交互询问用户是否覆盖
|
|
116
216
|
if (fs.existsSync(dest)) {
|
|
217
|
+
printWarning(`目录 "${projectName}" 已存在!`);
|
|
117
218
|
const { force } = await inquirer.prompt({
|
|
118
|
-
type:
|
|
119
|
-
name:
|
|
120
|
-
message:
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
219
|
+
type: "confirm",
|
|
220
|
+
name: "force",
|
|
221
|
+
message: chalk.yellow("⚠️ 是否覆盖现有目录?"),
|
|
222
|
+
default: false,
|
|
223
|
+
});
|
|
224
|
+
if (force) {
|
|
225
|
+
fs.removeSync(dest);
|
|
226
|
+
printSuccess("已删除现有目录");
|
|
227
|
+
} else {
|
|
228
|
+
printInfo("操作已取消");
|
|
229
|
+
process.exit(1);
|
|
230
|
+
}
|
|
124
231
|
}
|
|
125
232
|
|
|
126
233
|
// 开始loading
|
|
127
|
-
const loading = ora(
|
|
128
|
-
|
|
234
|
+
const loading = ora({
|
|
235
|
+
text: "正在下载模版...",
|
|
236
|
+
spinner: "bouncingBar",
|
|
237
|
+
});
|
|
238
|
+
loading.start();
|
|
239
|
+
|
|
129
240
|
// 5. 开始下载模版
|
|
130
241
|
try {
|
|
131
242
|
const result = await cloneRepository(projectTemplate, dest);
|
|
132
|
-
loading.succeed(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
243
|
+
loading.succeed();
|
|
244
|
+
printSuccess("模版下载成功!");
|
|
245
|
+
|
|
246
|
+
// 删除.git文件夹
|
|
247
|
+
const gitDir = path.join(dest, ".git");
|
|
248
|
+
if (fs.existsSync(gitDir)) {
|
|
249
|
+
fs.removeSync(gitDir);
|
|
250
|
+
printSuccess("已清理 .git 文件夹");
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
console.log(); // 空行
|
|
254
|
+
printFinalInstructions(projectName);
|
|
136
255
|
} catch (error) {
|
|
137
|
-
loading.fail(
|
|
256
|
+
loading.fail();
|
|
257
|
+
printError("模版下载失败:" + error);
|
|
258
|
+
process.exit(1);
|
|
138
259
|
}
|
|
139
|
-
})
|
|
260
|
+
});
|
|
140
261
|
|
|
141
262
|
// 定义当前版本
|
|
142
|
-
program.version(`v${package.version}`)
|
|
143
|
-
program.on(
|
|
144
|
-
|
|
263
|
+
program.version(`v${package.version}`);
|
|
264
|
+
program.on("--help", () => {
|
|
265
|
+
printBanner();
|
|
266
|
+
console.log(chalk.gray("使用示例:"));
|
|
267
|
+
console.log(chalk.white(" @4399ywkf/cli create my-project"));
|
|
268
|
+
console.log(
|
|
269
|
+
chalk.white(
|
|
270
|
+
" @4399ywkf/cli create my-project -t webpack-mainApplicate_demo"
|
|
271
|
+
)
|
|
272
|
+
);
|
|
273
|
+
console.log();
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
program.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@4399ywkf/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "运维开发部脚手架",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -9,9 +9,6 @@
|
|
|
9
9
|
"publishConfig": {
|
|
10
10
|
"access": "public"
|
|
11
11
|
},
|
|
12
|
-
"scripts": {
|
|
13
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
14
|
-
},
|
|
15
12
|
"repository": {
|
|
16
13
|
"type": "git"
|
|
17
14
|
},
|
|
@@ -24,12 +21,25 @@
|
|
|
24
21
|
"download-git-repo": "^3.0.2",
|
|
25
22
|
"fs-extra": "^11.1.1",
|
|
26
23
|
"inquirer": "^8.2.5",
|
|
27
|
-
"ora": "^5.4.1"
|
|
24
|
+
"ora": "^5.4.1",
|
|
25
|
+
"chalk": "^4.1.2",
|
|
26
|
+
"boxen": "^5.1.2",
|
|
27
|
+
"figlet": "^1.5.2"
|
|
28
28
|
},
|
|
29
29
|
"files": [
|
|
30
30
|
"bin"
|
|
31
31
|
],
|
|
32
32
|
"authors": [
|
|
33
33
|
"ywjszx@4399.com"
|
|
34
|
-
]
|
|
35
|
-
|
|
34
|
+
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
37
|
+
"dev": "node bin/cli.js",
|
|
38
|
+
"debug": "node --inspect-brk bin/cli.js",
|
|
39
|
+
"debug:create": "node --inspect-brk bin/cli.js create test-project",
|
|
40
|
+
"debug:create-with-template": "node --inspect-brk bin/cli.js create test-project -t webpack-mainApplicate_demo",
|
|
41
|
+
"debug:help": "node --inspect-brk bin/cli.js --help",
|
|
42
|
+
"link": "npm link",
|
|
43
|
+
"unlink": "npm unlink -g"
|
|
44
|
+
}
|
|
45
|
+
}
|