generator-mico-cli 0.2.20 → 0.2.21
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/README.md +29 -0
- package/bin/mico.js +124 -5
- package/generators/micro-react/index.js +76 -17
- package/generators/micro-react/templates/CLAUDE.md +11 -5
- package/generators/micro-react/templates/_gitignore +2 -0
- package/generators/micro-react/templates/apps/layout/config/config.ts +21 -0
- package/generators/micro-react/templates/apps/layout/docs/common-intl.md +8 -6
- package/generators/micro-react/templates/apps/layout/docs/feature-/345/276/256/345/211/215/347/253/257/346/250/241/345/274/217.md +60 -35
- package/generators/micro-react/templates/apps/layout/docs/feature-/350/217/234/345/215/225/346/235/203/351/231/220/346/216/247/345/210/266.md +7 -2
- package/generators/micro-react/templates/apps/layout/docs/utils-timezone.md +4 -2
- package/generators/micro-react/templates/apps/layout/mock/menus.ts +7 -2
- package/generators/micro-react/templates/apps/layout/package.json +3 -2
- package/generators/micro-react/templates/apps/layout/src/common/menu/parser.ts +3 -15
- package/generators/micro-react/templates/apps/layout/src/common/menu/types.ts +4 -0
- package/generators/micro-react/templates/apps/layout/src/global.less +1 -2
- package/generators/micro-react/templates/package.json +2 -1
- package/generators/subapp-react/index.js +81 -13
- package/generators/subapp-react/templates/homepage/config/config.dev.ts +8 -1
- package/generators/subapp-react/templates/homepage/config/config.ts +21 -0
- package/generators/subapp-react/templates/homepage/config/routes.ts +1 -1
- package/generators/subapp-react/templates/homepage/mock/api.mock.ts +2 -2
- package/generators/subapp-react/templates/homepage/package.json +3 -2
- package/generators/subapp-react/templates/homepage/src/app.tsx +1 -1
- package/generators/subapp-react/templates/homepage/src/common/request.ts +2 -2
- package/generators/subapp-react/templates/homepage/src/global.less +2 -1
- package/generators/subapp-react/templates/homepage/src/pages/index.less +1 -1
- package/generators/subapp-react/templates/homepage/src/pages/index.tsx +27 -27
- package/lib/utils.js +200 -2
- package/package.json +1 -1
package/lib/utils.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('node:fs');
|
|
4
4
|
const path = require('node:path');
|
|
5
|
-
const { execSync } = require('node:child_process');
|
|
5
|
+
const { execSync, exec } = require('node:child_process');
|
|
6
|
+
const os = require('node:os');
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* 转换为 kebab-case
|
|
@@ -135,7 +136,7 @@ function getRegistryForPackage(packageName) {
|
|
|
135
136
|
}
|
|
136
137
|
|
|
137
138
|
/**
|
|
138
|
-
* 从 npm registry
|
|
139
|
+
* 从 npm registry 获取包的最新版本号(同步版本)
|
|
139
140
|
* registry 根据 packageName 的 scope 自动选择:scope 包含 mico 时用 MICO_NPM_REGISTRY,否则用默认
|
|
140
141
|
* @param {string} packageName - 包名,如 '@mico-platform/ui'
|
|
141
142
|
* @param {string} [fallback='1.0.0'] - 网络或超时时的回退版本
|
|
@@ -161,6 +162,193 @@ function getLatestNpmVersion(packageName, fallback = '1.0.0', timeoutMs = 8000,
|
|
|
161
162
|
}
|
|
162
163
|
}
|
|
163
164
|
|
|
165
|
+
/**
|
|
166
|
+
* 从 npm registry 获取包的最新版本号(异步版本)
|
|
167
|
+
* @param {string} packageName - 包名,如 '@mico-platform/ui'
|
|
168
|
+
* @param {string} [fallback='1.0.0'] - 网络或超时时的回退版本
|
|
169
|
+
* @param {number} [timeoutMs=8000] - 超时毫秒
|
|
170
|
+
* @param {string} [cwd] - 执行 npm view 的 cwd
|
|
171
|
+
* @returns {Promise<string>} 版本号,如 '1.2.3'
|
|
172
|
+
*/
|
|
173
|
+
function getLatestNpmVersionAsync(packageName, fallback = '1.0.0', timeoutMs = 8000, cwd) {
|
|
174
|
+
return new Promise((resolve) => {
|
|
175
|
+
const registry = getRegistryForPackage(packageName);
|
|
176
|
+
const registryArg = registry ? `--registry=${registry}` : '';
|
|
177
|
+
const cmd = `npm view ${packageName} version ${registryArg}`.trim();
|
|
178
|
+
|
|
179
|
+
const child = exec(cmd, {
|
|
180
|
+
encoding: 'utf-8',
|
|
181
|
+
timeout: timeoutMs,
|
|
182
|
+
...(cwd && { cwd })
|
|
183
|
+
}, (error, stdout) => {
|
|
184
|
+
if (error) {
|
|
185
|
+
resolve(fallback);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const v = stdout.trim();
|
|
189
|
+
resolve(v && /^\d+\.\d+\.\d+/.test(v) ? v : fallback);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// 确保超时后也能 resolve
|
|
193
|
+
setTimeout(() => {
|
|
194
|
+
child.kill();
|
|
195
|
+
resolve(fallback);
|
|
196
|
+
}, timeoutMs + 100);
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* 并行获取多个包的版本号
|
|
202
|
+
* @param {Array<{name: string, fallback?: string}>} packages - 包列表
|
|
203
|
+
* @param {number} [timeoutMs=8000] - 超时毫秒
|
|
204
|
+
* @param {string} [cwd] - 执行 npm view 的 cwd
|
|
205
|
+
* @returns {Promise<Record<string, string>>} 包名到版本号的映射
|
|
206
|
+
*/
|
|
207
|
+
async function getPackageVersionsParallel(packages, timeoutMs = 8000, cwd) {
|
|
208
|
+
const results = await Promise.all(
|
|
209
|
+
packages.map(async (pkg) => {
|
|
210
|
+
const version = await getLatestNpmVersionAsync(
|
|
211
|
+
pkg.name,
|
|
212
|
+
pkg.fallback || '1.0.0',
|
|
213
|
+
timeoutMs,
|
|
214
|
+
cwd
|
|
215
|
+
);
|
|
216
|
+
return { name: pkg.name, version };
|
|
217
|
+
})
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
return results.reduce((acc, { name, version }) => {
|
|
221
|
+
acc[name] = version;
|
|
222
|
+
return acc;
|
|
223
|
+
}, {});
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// ============ 配置文件支持 ============
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* 查找并加载 .micorc 配置文件
|
|
230
|
+
* 按优先级从高到低查找:当前目录 -> 用户主目录
|
|
231
|
+
* @param {string} [startDir] - 开始查找的目录,默认为 process.cwd()
|
|
232
|
+
* @returns {object} 配置对象,找不到则返回空对象
|
|
233
|
+
*/
|
|
234
|
+
function loadMicorc(startDir = process.cwd()) {
|
|
235
|
+
const configNames = ['.micorc', '.micorc.json'];
|
|
236
|
+
const searchPaths = [
|
|
237
|
+
startDir,
|
|
238
|
+
os.homedir()
|
|
239
|
+
];
|
|
240
|
+
|
|
241
|
+
for (const dir of searchPaths) {
|
|
242
|
+
for (const name of configNames) {
|
|
243
|
+
const configPath = path.join(dir, name);
|
|
244
|
+
if (fs.existsSync(configPath)) {
|
|
245
|
+
try {
|
|
246
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
247
|
+
const config = JSON.parse(content);
|
|
248
|
+
return { config, configPath };
|
|
249
|
+
} catch (e) {
|
|
250
|
+
// 解析失败,继续查找
|
|
251
|
+
console.warn(`Warning: Failed to parse ${configPath}: ${e.message}`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return { config: {}, configPath: null };
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* 合并配置与用户输入
|
|
262
|
+
* @param {object} defaults - 默认值
|
|
263
|
+
* @param {object} rcConfig - .micorc 配置
|
|
264
|
+
* @returns {object} 合并后的默认值
|
|
265
|
+
*/
|
|
266
|
+
function mergeDefaults(defaults, rcConfig) {
|
|
267
|
+
return { ...defaults, ...rcConfig };
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// ============ 环境检查 ============
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* 检查命令是否可用
|
|
274
|
+
* @param {string} command - 命令名称
|
|
275
|
+
* @returns {{available: boolean, version?: string, error?: string}}
|
|
276
|
+
*/
|
|
277
|
+
function checkCommand(command) {
|
|
278
|
+
try {
|
|
279
|
+
const versionFlag = command === 'pnpm' ? '--version' : '--version';
|
|
280
|
+
const out = execSync(`${command} ${versionFlag}`, {
|
|
281
|
+
encoding: 'utf-8',
|
|
282
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
283
|
+
timeout: 5000
|
|
284
|
+
});
|
|
285
|
+
const version = out.trim().split('\n')[0];
|
|
286
|
+
return { available: true, version };
|
|
287
|
+
} catch (e) {
|
|
288
|
+
return { available: false, error: e.message };
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* 检查 Node.js 版本是否满足要求
|
|
294
|
+
* @param {string} required - 要求的最低版本,如 '18'
|
|
295
|
+
* @returns {{satisfied: boolean, current: string, required: string}}
|
|
296
|
+
*/
|
|
297
|
+
function checkNodeVersion(required = '18') {
|
|
298
|
+
const current = process.version.replace(/^v/, '');
|
|
299
|
+
const currentMajor = parseInt(current.split('.')[0], 10);
|
|
300
|
+
const requiredMajor = parseInt(required, 10);
|
|
301
|
+
return {
|
|
302
|
+
satisfied: currentMajor >= requiredMajor,
|
|
303
|
+
current,
|
|
304
|
+
required
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* 检查网络连接(npm registry)
|
|
310
|
+
* @param {number} [timeoutMs=5000] - 超时毫秒
|
|
311
|
+
* @returns {Promise<{reachable: boolean, registry: string, error?: string}>}
|
|
312
|
+
*/
|
|
313
|
+
async function checkNpmRegistry(timeoutMs = 5000) {
|
|
314
|
+
const registry = 'https://registry.npmjs.org';
|
|
315
|
+
return new Promise((resolve) => {
|
|
316
|
+
const child = exec(`npm ping --registry=${registry}`, {
|
|
317
|
+
timeout: timeoutMs
|
|
318
|
+
}, (error) => {
|
|
319
|
+
if (error) {
|
|
320
|
+
resolve({ reachable: false, registry, error: error.message });
|
|
321
|
+
} else {
|
|
322
|
+
resolve({ reachable: true, registry });
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
setTimeout(() => {
|
|
327
|
+
child.kill();
|
|
328
|
+
resolve({ reachable: false, registry, error: 'Timeout' });
|
|
329
|
+
}, timeoutMs + 100);
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* 运行完整的环境检查
|
|
335
|
+
* @returns {Promise<object>} 检查结果
|
|
336
|
+
*/
|
|
337
|
+
async function runDoctorChecks() {
|
|
338
|
+
const results = {
|
|
339
|
+
node: checkNodeVersion('18'),
|
|
340
|
+
pnpm: checkCommand('pnpm'),
|
|
341
|
+
yo: checkCommand('yo'),
|
|
342
|
+
git: checkCommand('git'),
|
|
343
|
+
npm: null
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
// 异步检查 npm registry
|
|
347
|
+
results.npm = await checkNpmRegistry();
|
|
348
|
+
|
|
349
|
+
return results;
|
|
350
|
+
}
|
|
351
|
+
|
|
164
352
|
/**
|
|
165
353
|
* 检查是否启用了 verbose 模式
|
|
166
354
|
* @returns {boolean}
|
|
@@ -247,8 +435,18 @@ module.exports = {
|
|
|
247
435
|
transformDestPath,
|
|
248
436
|
isTemplateFile,
|
|
249
437
|
getLatestNpmVersion,
|
|
438
|
+
getLatestNpmVersionAsync,
|
|
439
|
+
getPackageVersionsParallel,
|
|
250
440
|
setupErrorHandlers,
|
|
251
441
|
TEMPLATE_EXTENSIONS,
|
|
442
|
+
// 配置文件
|
|
443
|
+
loadMicorc,
|
|
444
|
+
mergeDefaults,
|
|
445
|
+
// 环境检查
|
|
446
|
+
checkCommand,
|
|
447
|
+
checkNodeVersion,
|
|
448
|
+
checkNpmRegistry,
|
|
449
|
+
runDoctorChecks,
|
|
252
450
|
// Verbose 日志
|
|
253
451
|
isVerbose,
|
|
254
452
|
verboseLog,
|