@4399ywkf/cli 0.0.4 → 0.0.5
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 +171 -13
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -84,6 +84,148 @@ function cloneRepository(repoUrl, destination) {
|
|
|
84
84
|
});
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
// 新添加:更新环境模板文件
|
|
88
|
+
async function updateEnvTemplate(filePath, config) {
|
|
89
|
+
try {
|
|
90
|
+
// 读取模板文件内容
|
|
91
|
+
let templateContent = await fs.readFile(filePath, "utf8");
|
|
92
|
+
|
|
93
|
+
// 替换模板变量
|
|
94
|
+
const replacements = {
|
|
95
|
+
"{{APP_CNAME}}": `"${config.appCname}"`,
|
|
96
|
+
"{{APP_NAME}}": `"${config.appName}"`,
|
|
97
|
+
"{{SENTRY_ENABLED}}": `"${config.sentryEnabled ? "true" : "false"}"`,
|
|
98
|
+
"{{SENTRY_DSN}}": `"${config.sentryDsn}"`,
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// 执行替换
|
|
102
|
+
for (const [placeholder, value] of Object.entries(replacements)) {
|
|
103
|
+
templateContent = templateContent.replace(
|
|
104
|
+
new RegExp(placeholder, "g"),
|
|
105
|
+
value
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 写回文件
|
|
110
|
+
await fs.writeFile(filePath, templateContent, "utf8");
|
|
111
|
+
} catch (error) {
|
|
112
|
+
throw new Error(`更新模板文件失败: ${error.message}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// 配置 webpack 子应用的环境变量(填充模板)
|
|
117
|
+
async function configureWebpackSubApp(projectPath, projectName) {
|
|
118
|
+
printInfo("正在配置 Webpack 子应用环境变量...");
|
|
119
|
+
|
|
120
|
+
const envFilePath = path.join(projectPath, "config", "env", ".env.public");
|
|
121
|
+
|
|
122
|
+
// 检查模板文件是否存在
|
|
123
|
+
if (!fs.existsSync(envFilePath)) {
|
|
124
|
+
printWarning("未找到 .env.public 模板文件,跳过配置");
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// 询问用户配置选项
|
|
129
|
+
const { configureEnv } = await inquirer.prompt({
|
|
130
|
+
type: "confirm",
|
|
131
|
+
name: "configureEnv",
|
|
132
|
+
message: chalk.cyan("🔧 是否要自定义应用配置?"),
|
|
133
|
+
default: true,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
if (!configureEnv) {
|
|
137
|
+
// 如果不配置,使用默认值填充模板
|
|
138
|
+
const defaultConfig = {
|
|
139
|
+
appCname: projectName.toLowerCase().replace(/[^a-z0-9-]/g, "-"),
|
|
140
|
+
appName: projectName
|
|
141
|
+
.toLowerCase()
|
|
142
|
+
.replace(/[^a-z0-9-]/g, "-")
|
|
143
|
+
.split("-")
|
|
144
|
+
.map((word, index) =>
|
|
145
|
+
index === 0 ? word : word.charAt(0).toUpperCase() + word.slice(1)
|
|
146
|
+
)
|
|
147
|
+
.join(""),
|
|
148
|
+
outputPath: "dist",
|
|
149
|
+
publicPath: "/",
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
await updateEnvTemplate(envFilePath, defaultConfig);
|
|
153
|
+
printInfo("已使用默认配置填充模板");
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// 获取用户输入的配置
|
|
158
|
+
const config = await inquirer.prompt([
|
|
159
|
+
{
|
|
160
|
+
type: "input",
|
|
161
|
+
name: "appName",
|
|
162
|
+
message: chalk.cyan("📝 请输入应用代码名称(APP_NAME):"),
|
|
163
|
+
default: projectName.toLowerCase().replace(/[^a-z0-9-_]/g, "-"),
|
|
164
|
+
validate: (input) => {
|
|
165
|
+
if (!input.trim()) {
|
|
166
|
+
return "应用代码名称不能为空!";
|
|
167
|
+
}
|
|
168
|
+
if (!/^[a-z0-9-_]+$/.test(input)) {
|
|
169
|
+
return "应用代码名称只能包含小写字母、数字、横线和下划线!";
|
|
170
|
+
}
|
|
171
|
+
return true;
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
type: "input",
|
|
176
|
+
name: "appCname",
|
|
177
|
+
message: chalk.cyan("📝 请输入应用名称 (APP_CNAME):"),
|
|
178
|
+
default: projectName.toLowerCase().replace(/[^a-z0-9-_]/g, "-"),
|
|
179
|
+
validate: (input) => {
|
|
180
|
+
if (!input.trim()) {
|
|
181
|
+
return "应用名称不能为空!";
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// 支持中文、英文、数字、横线、下划线,必须以字母或中文开头
|
|
185
|
+
if (
|
|
186
|
+
!/^[\u4e00-\u9fff\u3400-\u4dbfa-zA-Z][\u4e00-\u9fff\u3400-\u4dbfa-zA-Z0-9_-]*$/.test(
|
|
187
|
+
input
|
|
188
|
+
)
|
|
189
|
+
) {
|
|
190
|
+
return "应用名称必须以中文或字母开头,可包含中文、字母、数字、横线和下划线!";
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return true;
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
type: "confirm",
|
|
198
|
+
name: "sentryEnabled",
|
|
199
|
+
message: chalk.cyan("📝 是否开启 Sentry?"),
|
|
200
|
+
default: true,
|
|
201
|
+
},
|
|
202
|
+
// 如果开启 sentry 则需要输入 sentry 的 dsn
|
|
203
|
+
{
|
|
204
|
+
type: "input",
|
|
205
|
+
name: "sentryDsn",
|
|
206
|
+
message: chalk.cyan("📝 请输入 Sentry 的 DSN:"),
|
|
207
|
+
default: "https://207b65a59562963635abde2cfce82651@sentry.gz4399.com/28",
|
|
208
|
+
when: (answers) => answers.sentryEnabled,
|
|
209
|
+
},
|
|
210
|
+
]);
|
|
211
|
+
|
|
212
|
+
try {
|
|
213
|
+
// 更新模板文件
|
|
214
|
+
await updateEnvTemplate(envFilePath, config);
|
|
215
|
+
printSuccess(`已更新环境配置文件:${chalk.bold(".env.public")}`);
|
|
216
|
+
|
|
217
|
+
// 显示配置信息
|
|
218
|
+
console.log();
|
|
219
|
+
printInfo("应用配置信息:");
|
|
220
|
+
console.log(chalk.gray(` 应用代码名称: ${chalk.white(config.appCname)}`));
|
|
221
|
+
console.log(chalk.gray(` 应用名称: ${chalk.white(config.appName)}`));
|
|
222
|
+
console.log();
|
|
223
|
+
} catch (error) {
|
|
224
|
+
printError(`更新环境配置文件失败:${error.message}`);
|
|
225
|
+
throw error;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
87
229
|
program
|
|
88
230
|
.command("create [projectName]")
|
|
89
231
|
.description("创建模版")
|
|
@@ -184,11 +326,13 @@ program
|
|
|
184
326
|
|
|
185
327
|
// 4. 选择模版
|
|
186
328
|
let projectTemplate;
|
|
329
|
+
|
|
187
330
|
if (options.template) {
|
|
188
|
-
|
|
331
|
+
const foundTemplate = templates[toolType][appDirection].find(
|
|
189
332
|
(template) => template.name === options.template
|
|
190
|
-
)
|
|
191
|
-
if (
|
|
333
|
+
);
|
|
334
|
+
if (foundTemplate) {
|
|
335
|
+
projectTemplate = foundTemplate.value;
|
|
192
336
|
printSuccess(`使用指定模版:${chalk.bold(options.template)}`);
|
|
193
337
|
} else {
|
|
194
338
|
printWarning(`未找到指定模版 "${options.template}",请重新选择`);
|
|
@@ -196,16 +340,24 @@ program
|
|
|
196
340
|
}
|
|
197
341
|
|
|
198
342
|
if (!projectTemplate) {
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
|
|
343
|
+
const availableTemplates = templates[toolType][appDirection];
|
|
344
|
+
|
|
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;
|
|
360
|
+
}
|
|
209
361
|
}
|
|
210
362
|
|
|
211
363
|
console.log(); // 空行
|
|
@@ -250,6 +402,12 @@ program
|
|
|
250
402
|
printSuccess("已清理 .git 文件夹");
|
|
251
403
|
}
|
|
252
404
|
|
|
405
|
+
// 新添加:如果是 webpack 子应用,进行环境配置
|
|
406
|
+
if (toolType === "webpack" && appDirection === "sub") {
|
|
407
|
+
console.log(); // 空行
|
|
408
|
+
await configureWebpackSubApp(dest, projectName);
|
|
409
|
+
}
|
|
410
|
+
|
|
253
411
|
console.log(); // 空行
|
|
254
412
|
printFinalInstructions(projectName);
|
|
255
413
|
} catch (error) {
|