generator-mico-cli 0.2.19 → 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 +86 -17
- package/generators/micro-react/templates/.eslintrc.js +24 -1
- package/generators/micro-react/templates/CICD/start_dev.sh +1 -1
- 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 +23 -21
- package/generators/micro-react/templates/apps/layout/docs/feature-/344/270/273/351/242/230/350/211/262/345/210/207/346/215/242.md +1 -1
- 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 +61 -36
- 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/locale.ts +3 -3
- 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/components/MicroAppLoader/index.tsx +1 -1
- package/generators/micro-react/templates/apps/layout/src/global.less +2 -3
- package/generators/micro-react/templates/apps/layout/src/services/config/type.ts +2 -4
- package/generators/micro-react/templates/package.json +5 -2
- package/generators/micro-react/templates/packages/common-intl/README.md +8 -8
- package/generators/micro-react/templates/packages/common-intl/src/intl.ts +13 -5678
- package/generators/micro-react/templates/packages/common-intl/src/utils.ts +22 -21
- 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/generators/micro-react/templates/packages/common-intl/.turbo/turbo-build.log +0 -13
- package/generators/micro-react/templates/packages/common-intl/dist/index.d.ts +0 -3
- package/generators/micro-react/templates/packages/common-intl/dist/index.js +0 -4388
- package/generators/micro-react/templates/packages/common-intl/dist/indexedDBUtils.d.ts +0 -13
- package/generators/micro-react/templates/packages/common-intl/dist/intl.d.ts +0 -1022
- package/generators/micro-react/templates/packages/common-intl/dist/utils.d.ts +0 -122
package/README.md
CHANGED
|
@@ -48,12 +48,41 @@ mico list
|
|
|
48
48
|
mico create micro-react --verbose
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
预览模式(只显示将创建的文件,不实际创建):
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
mico create micro-react --dry-run
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
检查环境依赖:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
mico doctor
|
|
61
|
+
```
|
|
62
|
+
|
|
51
63
|
将额外参数传递给生成器:
|
|
52
64
|
|
|
53
65
|
```bash
|
|
54
66
|
mico create micro-react -- --help
|
|
55
67
|
```
|
|
56
68
|
|
|
69
|
+
## 配置文件
|
|
70
|
+
|
|
71
|
+
可以在项目目录或用户主目录创建 `.micorc` 或 `.micorc.json` 文件来预设默认值:
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"packageScope": "@my-company",
|
|
76
|
+
"cdnPrefix": "portal",
|
|
77
|
+
"author": "Team <team@example.com>",
|
|
78
|
+
"defaultSubappName": "subapp"
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
配置查找顺序:
|
|
83
|
+
1. 当前目录的 `.micorc` 或 `.micorc.json`
|
|
84
|
+
2. 用户主目录的 `.micorc` 或 `.micorc.json`
|
|
85
|
+
|
|
57
86
|
## Monorepo 项目生成器 (micro-react)
|
|
58
87
|
|
|
59
88
|
创建基于 qiankun 微前端架构的完整 Monorepo 项目:
|
package/bin/mico.js
CHANGED
|
@@ -22,18 +22,32 @@ Commands:
|
|
|
22
22
|
create <generator> Run a generator (e.g., mico create subapp-react)
|
|
23
23
|
list List all available generators
|
|
24
24
|
update Update mico-cli to the latest version
|
|
25
|
+
doctor Check environment dependencies
|
|
25
26
|
|
|
26
27
|
Options:
|
|
27
28
|
--help, -h Show this help message
|
|
28
29
|
--version, -v Show version number
|
|
29
30
|
--verbose Show detailed output during generation
|
|
31
|
+
--dry-run Preview files without creating them
|
|
30
32
|
--no-update-check Skip update check
|
|
31
33
|
|
|
32
34
|
Examples:
|
|
33
35
|
mico create subapp-react
|
|
34
36
|
mico create micro-react --verbose
|
|
37
|
+
mico create micro-react --dry-run
|
|
35
38
|
mico list
|
|
36
39
|
mico update
|
|
40
|
+
mico doctor
|
|
41
|
+
|
|
42
|
+
Configuration:
|
|
43
|
+
Create a .micorc or .micorc.json file in your project or home directory
|
|
44
|
+
to set default values for prompts:
|
|
45
|
+
|
|
46
|
+
{
|
|
47
|
+
"packageScope": "@my-company",
|
|
48
|
+
"cdnPrefix": "portal",
|
|
49
|
+
"author": "Team <team@example.com>"
|
|
50
|
+
}
|
|
37
51
|
|
|
38
52
|
Notes:
|
|
39
53
|
Requires Yeoman CLI (yo) installed globally.
|
|
@@ -118,6 +132,85 @@ function printVersion() {
|
|
|
118
132
|
console.log(`mico-cli v${pkg.version}`);
|
|
119
133
|
}
|
|
120
134
|
|
|
135
|
+
/**
|
|
136
|
+
* 运行 doctor 检查
|
|
137
|
+
*/
|
|
138
|
+
async function runDoctor() {
|
|
139
|
+
const { runDoctorChecks, loadMicorc } = require('../lib/utils');
|
|
140
|
+
|
|
141
|
+
console.log('');
|
|
142
|
+
console.log(` \x1b[1mMico CLI Environment Check\x1b[0m (v${pkg.version})`);
|
|
143
|
+
console.log('');
|
|
144
|
+
|
|
145
|
+
const results = await runDoctorChecks();
|
|
146
|
+
|
|
147
|
+
// Node.js
|
|
148
|
+
const nodeIcon = results.node.satisfied ? '\x1b[32m✓\x1b[0m' : '\x1b[31m✗\x1b[0m';
|
|
149
|
+
const nodeStatus = results.node.satisfied ? 'OK' : `Required: >= ${results.node.required}`;
|
|
150
|
+
console.log(` ${nodeIcon} Node.js ${results.node.current} (${nodeStatus})`);
|
|
151
|
+
|
|
152
|
+
// pnpm
|
|
153
|
+
const pnpmIcon = results.pnpm.available ? '\x1b[32m✓\x1b[0m' : '\x1b[31m✗\x1b[0m';
|
|
154
|
+
if (results.pnpm.available) {
|
|
155
|
+
console.log(` ${pnpmIcon} pnpm ${results.pnpm.version}`);
|
|
156
|
+
} else {
|
|
157
|
+
console.log(` ${pnpmIcon} pnpm not found`);
|
|
158
|
+
console.log(' Install: npm install -g pnpm');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Yeoman
|
|
162
|
+
const yoIcon = results.yo.available ? '\x1b[32m✓\x1b[0m' : '\x1b[31m✗\x1b[0m';
|
|
163
|
+
if (results.yo.available) {
|
|
164
|
+
console.log(` ${yoIcon} yo ${results.yo.version}`);
|
|
165
|
+
} else {
|
|
166
|
+
console.log(` ${yoIcon} yo not found`);
|
|
167
|
+
console.log(' Install: npm install -g yo');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Git
|
|
171
|
+
const gitIcon = results.git.available ? '\x1b[32m✓\x1b[0m' : '\x1b[33m⚠\x1b[0m';
|
|
172
|
+
if (results.git.available) {
|
|
173
|
+
console.log(` ${gitIcon} git ${results.git.version}`);
|
|
174
|
+
} else {
|
|
175
|
+
console.log(` ${gitIcon} git not found (optional)`);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// npm registry
|
|
179
|
+
const npmIcon = results.npm.reachable ? '\x1b[32m✓\x1b[0m' : '\x1b[33m⚠\x1b[0m';
|
|
180
|
+
if (results.npm.reachable) {
|
|
181
|
+
console.log(` ${npmIcon} npm registry reachable`);
|
|
182
|
+
} else {
|
|
183
|
+
console.log(` ${npmIcon} npm registry unreachable (${results.npm.error})`);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// .micorc 配置
|
|
187
|
+
console.log('');
|
|
188
|
+
const { config, configPath } = loadMicorc();
|
|
189
|
+
if (configPath) {
|
|
190
|
+
console.log(` \x1b[32m✓\x1b[0m Config loaded from: ${configPath}`);
|
|
191
|
+
const keys = Object.keys(config);
|
|
192
|
+
if (keys.length > 0) {
|
|
193
|
+
console.log(` Keys: ${keys.join(', ')}`);
|
|
194
|
+
}
|
|
195
|
+
} else {
|
|
196
|
+
console.log(' \x1b[2m○\x1b[0m No .micorc config found (optional)');
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
console.log('');
|
|
200
|
+
|
|
201
|
+
// 总结
|
|
202
|
+
const allGood = results.node.satisfied && results.pnpm.available && results.yo.available;
|
|
203
|
+
if (allGood) {
|
|
204
|
+
console.log(' \x1b[32m✅ All required dependencies are installed!\x1b[0m');
|
|
205
|
+
} else {
|
|
206
|
+
console.log(' \x1b[31m❌ Some required dependencies are missing.\x1b[0m');
|
|
207
|
+
console.log(' Please install them before using mico-cli.');
|
|
208
|
+
}
|
|
209
|
+
console.log('');
|
|
210
|
+
|
|
211
|
+
return allGood;
|
|
212
|
+
}
|
|
213
|
+
|
|
121
214
|
/**
|
|
122
215
|
* 检查是否有新版本
|
|
123
216
|
* @returns {Promise<{current: string, latest: string, hasUpdate: boolean} | null>}
|
|
@@ -256,6 +349,7 @@ function performUpdate(latestVersion) {
|
|
|
256
349
|
* @param {string[]} passthroughArgs - 透传参数
|
|
257
350
|
* @param {object} options - 选项
|
|
258
351
|
* @param {boolean} options.verbose - 是否启用详细输出
|
|
352
|
+
* @param {boolean} options.dryRun - 是否启用 dry-run 模式
|
|
259
353
|
*/
|
|
260
354
|
function runGenerator(generator, rest, passthroughArgs, options = {}) {
|
|
261
355
|
const localGeneratorEntry = path.join(
|
|
@@ -275,17 +369,31 @@ function runGenerator(generator, rest, passthroughArgs, options = {}) {
|
|
|
275
369
|
|
|
276
370
|
const yoArgs = [yoGenerator, ...rest];
|
|
277
371
|
|
|
372
|
+
// 添加 dry-run 参数给 yeoman
|
|
373
|
+
if (options.dryRun) {
|
|
374
|
+
yoArgs.push('--dry-run');
|
|
375
|
+
}
|
|
376
|
+
|
|
278
377
|
if (passthroughArgs.length > 0) {
|
|
279
378
|
yoArgs.push('--', ...passthroughArgs);
|
|
280
379
|
}
|
|
281
380
|
|
|
282
|
-
//
|
|
381
|
+
// 通过环境变量传递标志给生成器
|
|
283
382
|
const env = { ...process.env };
|
|
284
383
|
if (options.verbose) {
|
|
285
384
|
env.MICO_VERBOSE = '1';
|
|
385
|
+
}
|
|
386
|
+
if (options.dryRun) {
|
|
387
|
+
env.MICO_DRY_RUN = '1';
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
if (options.verbose) {
|
|
286
391
|
console.log('');
|
|
287
392
|
console.log(' \x1b[2m[verbose] Running generator:', yoGenerator, '\x1b[0m');
|
|
288
393
|
console.log(' \x1b[2m[verbose] Arguments:', yoArgs.join(' '), '\x1b[0m');
|
|
394
|
+
if (options.dryRun) {
|
|
395
|
+
console.log(' \x1b[2m[verbose] Dry-run mode enabled\x1b[0m');
|
|
396
|
+
}
|
|
289
397
|
console.log('');
|
|
290
398
|
}
|
|
291
399
|
|
|
@@ -323,6 +431,7 @@ async function main() {
|
|
|
323
431
|
const hasVersion = mainArgs.includes('--version') || mainArgs.includes('-v');
|
|
324
432
|
const skipUpdateCheck = mainArgs.includes('--no-update-check');
|
|
325
433
|
const isVerbose = mainArgs.includes('--verbose');
|
|
434
|
+
const isDryRun = mainArgs.includes('--dry-run');
|
|
326
435
|
|
|
327
436
|
// 过滤掉标志参数
|
|
328
437
|
const filteredArgs = mainArgs.filter(
|
|
@@ -332,7 +441,8 @@ async function main() {
|
|
|
332
441
|
arg !== '--version' &&
|
|
333
442
|
arg !== '-v' &&
|
|
334
443
|
arg !== '--no-update-check' &&
|
|
335
|
-
arg !== '--verbose'
|
|
444
|
+
arg !== '--verbose' &&
|
|
445
|
+
arg !== '--dry-run'
|
|
336
446
|
);
|
|
337
447
|
|
|
338
448
|
// 处理 --version
|
|
@@ -355,6 +465,12 @@ async function main() {
|
|
|
355
465
|
process.exit(0);
|
|
356
466
|
}
|
|
357
467
|
|
|
468
|
+
// 处理 doctor 命令
|
|
469
|
+
if (command === 'doctor') {
|
|
470
|
+
const success = await runDoctor();
|
|
471
|
+
process.exit(success ? 0 : 1);
|
|
472
|
+
}
|
|
473
|
+
|
|
358
474
|
// 处理 update 命令
|
|
359
475
|
if (command === 'update') {
|
|
360
476
|
const updateInfo = await checkForUpdate();
|
|
@@ -376,8 +492,8 @@ async function main() {
|
|
|
376
492
|
process.exit(1);
|
|
377
493
|
}
|
|
378
494
|
|
|
379
|
-
//
|
|
380
|
-
if (!skipUpdateCheck) {
|
|
495
|
+
// 检查更新(除非跳过或 dry-run)
|
|
496
|
+
if (!skipUpdateCheck && !isDryRun) {
|
|
381
497
|
const updateInfo = await checkForUpdate();
|
|
382
498
|
if (updateInfo && updateInfo.hasUpdate) {
|
|
383
499
|
const shouldUpdate = await askForUpdate(
|
|
@@ -396,7 +512,10 @@ async function main() {
|
|
|
396
512
|
}
|
|
397
513
|
|
|
398
514
|
// 运行生成器
|
|
399
|
-
runGenerator(generator, rest.slice(1), passthroughArgs, {
|
|
515
|
+
runGenerator(generator, rest.slice(1), passthroughArgs, {
|
|
516
|
+
verbose: isVerbose,
|
|
517
|
+
dryRun: isDryRun
|
|
518
|
+
});
|
|
400
519
|
return;
|
|
401
520
|
}
|
|
402
521
|
|
|
@@ -9,10 +9,10 @@ const {
|
|
|
9
9
|
collectFiles,
|
|
10
10
|
transformDestPath,
|
|
11
11
|
isTemplateFile,
|
|
12
|
-
|
|
12
|
+
getPackageVersionsParallel,
|
|
13
13
|
setupErrorHandlers,
|
|
14
14
|
createLogger,
|
|
15
|
-
|
|
15
|
+
loadMicorc,
|
|
16
16
|
} = require('../../lib/utils');
|
|
17
17
|
|
|
18
18
|
const IGNORE_LIST = require('./ignore-list.json');
|
|
@@ -25,6 +25,17 @@ module.exports = class extends Generator {
|
|
|
25
25
|
this.projectRoot = process.cwd();
|
|
26
26
|
this.logger = createLogger(this);
|
|
27
27
|
|
|
28
|
+
// 检查 dry-run 模式
|
|
29
|
+
this.isDryRun = this.options.dryRun || process.env.MICO_DRY_RUN === '1';
|
|
30
|
+
|
|
31
|
+
// 加载 .micorc 配置
|
|
32
|
+
const { config: rcConfig, configPath } = loadMicorc(this.projectRoot);
|
|
33
|
+
this.rcConfig = rcConfig;
|
|
34
|
+
if (configPath) {
|
|
35
|
+
this.logger.verbose('Loaded config from:', configPath);
|
|
36
|
+
this.logger.verbose('Config:', JSON.stringify(rcConfig, null, 2));
|
|
37
|
+
}
|
|
38
|
+
|
|
28
39
|
// 检查当前目录是否已是一个 monorepo
|
|
29
40
|
const workspaceFile = path.join(this.projectRoot, 'pnpm-workspace.yaml');
|
|
30
41
|
if (fs.existsSync(workspaceFile)) {
|
|
@@ -46,12 +57,15 @@ module.exports = class extends Generator {
|
|
|
46
57
|
|
|
47
58
|
async prompting() {
|
|
48
59
|
try {
|
|
60
|
+
// 使用 .micorc 中的值作为默认值
|
|
61
|
+
const rc = this.rcConfig || {};
|
|
62
|
+
|
|
49
63
|
this.answers = await this.prompt([
|
|
50
64
|
{
|
|
51
65
|
type: 'input',
|
|
52
66
|
name: 'projectName',
|
|
53
67
|
message: 'Project name',
|
|
54
|
-
default: path.basename(this.projectRoot),
|
|
68
|
+
default: rc.projectName || path.basename(this.projectRoot),
|
|
55
69
|
filter: (input) => toKebab(input),
|
|
56
70
|
validate: (input) => {
|
|
57
71
|
const value = toKebab(input);
|
|
@@ -63,7 +77,7 @@ module.exports = class extends Generator {
|
|
|
63
77
|
type: 'input',
|
|
64
78
|
name: 'packageScope',
|
|
65
79
|
message: 'Package scope (e.g., @my-project)',
|
|
66
|
-
default: (answers) => `@${toKebab(answers.projectName)}`,
|
|
80
|
+
default: (answers) => rc.packageScope || `@${toKebab(answers.projectName)}`,
|
|
67
81
|
validate: (input) => {
|
|
68
82
|
if (!input) return 'Package scope is required';
|
|
69
83
|
if (!input.startsWith('@'))
|
|
@@ -80,7 +94,7 @@ module.exports = class extends Generator {
|
|
|
80
94
|
- 输入 "portal": https://cdn.example.com/portal/my-project/1.0.0/
|
|
81
95
|
- 输入 "admin/v2": https://cdn.example.com/admin/v2/my-project/1.0.0/
|
|
82
96
|
Prefix`,
|
|
83
|
-
default: '',
|
|
97
|
+
default: rc.cdnPrefix || '',
|
|
84
98
|
filter: (input) => {
|
|
85
99
|
// 移除首尾斜杠,规范化路径
|
|
86
100
|
return input.trim().replace(/^\/+|\/+$/g, '');
|
|
@@ -90,7 +104,7 @@ module.exports = class extends Generator {
|
|
|
90
104
|
type: 'input',
|
|
91
105
|
name: 'author',
|
|
92
106
|
message: 'Author',
|
|
93
|
-
default: 'Your Name <email@example.com>',
|
|
107
|
+
default: rc.author || 'Your Name <email@example.com>',
|
|
94
108
|
},
|
|
95
109
|
]);
|
|
96
110
|
|
|
@@ -110,7 +124,7 @@ module.exports = class extends Generator {
|
|
|
110
124
|
}
|
|
111
125
|
}
|
|
112
126
|
|
|
113
|
-
writing() {
|
|
127
|
+
async writing() {
|
|
114
128
|
try {
|
|
115
129
|
if (!fs.existsSync(this.templateDir)) {
|
|
116
130
|
console.error('');
|
|
@@ -125,21 +139,21 @@ module.exports = class extends Generator {
|
|
|
125
139
|
|
|
126
140
|
// 在 mico_cli 根目录执行 npm view,以使用该目录 .npmrc 中的 Nexus 认证
|
|
127
141
|
const cliRoot = path.resolve(__dirname, '../..');
|
|
128
|
-
this.logger.verbose('Fetching latest package versions...');
|
|
142
|
+
this.logger.verbose('Fetching latest package versions (parallel)...');
|
|
129
143
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const themeVer = getLatestNpmVersion(
|
|
137
|
-
'@mico-platform/theme',
|
|
138
|
-
'1.0.0',
|
|
144
|
+
// 并行获取版本
|
|
145
|
+
const versions = await getPackageVersionsParallel(
|
|
146
|
+
[
|
|
147
|
+
{ name: '@mico-platform/ui', fallback: '1.0.0' },
|
|
148
|
+
{ name: '@mico-platform/theme', fallback: '1.0.0' },
|
|
149
|
+
],
|
|
139
150
|
8000,
|
|
140
151
|
cliRoot,
|
|
141
152
|
);
|
|
142
153
|
|
|
154
|
+
const micoUiVer = versions['@mico-platform/ui'];
|
|
155
|
+
const themeVer = versions['@mico-platform/theme'];
|
|
156
|
+
|
|
143
157
|
this.logger.verbose('@mico-platform/ui version:', micoUiVer);
|
|
144
158
|
this.logger.verbose('@mico-platform/theme version:', themeVer);
|
|
145
159
|
|
|
@@ -173,6 +187,45 @@ module.exports = class extends Generator {
|
|
|
173
187
|
process.exit(1);
|
|
174
188
|
}
|
|
175
189
|
|
|
190
|
+
// Dry-run 模式:只列出文件,不实际创建
|
|
191
|
+
if (this.isDryRun) {
|
|
192
|
+
this.log('');
|
|
193
|
+
this.log('\x1b[33m📋 Dry run mode - no files will be created\x1b[0m');
|
|
194
|
+
this.log('');
|
|
195
|
+
this.log(` Project: ${this.projectName}`);
|
|
196
|
+
this.log(` Scope: ${this.packageScope}`);
|
|
197
|
+
this.log(` Destination: ${this.destDir}`);
|
|
198
|
+
this.log('');
|
|
199
|
+
this.log(' Would create the following files:');
|
|
200
|
+
this.log('');
|
|
201
|
+
|
|
202
|
+
let templateCount = 0;
|
|
203
|
+
let copyCount = 0;
|
|
204
|
+
|
|
205
|
+
for (const relPath of files) {
|
|
206
|
+
const destRelPath = transformDestPath(relPath);
|
|
207
|
+
const isTemplate = isTemplateFile(relPath);
|
|
208
|
+
const tag = isTemplate ? '\x1b[32m[tpl]\x1b[0m' : '\x1b[36m[cpy]\x1b[0m';
|
|
209
|
+
this.log(` ${tag} ${destRelPath}`);
|
|
210
|
+
|
|
211
|
+
if (isTemplate) {
|
|
212
|
+
templateCount++;
|
|
213
|
+
} else {
|
|
214
|
+
copyCount++;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
this.log('');
|
|
219
|
+
this.log(` Total: ${files.length} files (${templateCount} templates, ${copyCount} static)`);
|
|
220
|
+
this.log('');
|
|
221
|
+
this.log(' Run without --dry-run to actually create these files.');
|
|
222
|
+
this.log('');
|
|
223
|
+
|
|
224
|
+
// 设置标记以跳过后续阶段
|
|
225
|
+
this._skipInstall = true;
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
|
|
176
229
|
this.log('');
|
|
177
230
|
this.log(`📦 Creating project: ${this.projectName}`);
|
|
178
231
|
this.log(` Scope: ${this.packageScope}`);
|
|
@@ -210,6 +263,19 @@ module.exports = class extends Generator {
|
|
|
210
263
|
}
|
|
211
264
|
|
|
212
265
|
install() {
|
|
266
|
+
// 跳过 dry-run 模式
|
|
267
|
+
if (this._skipInstall) return;
|
|
268
|
+
|
|
269
|
+
// 检查并初始化 git
|
|
270
|
+
const gitDir = path.join(this.destDir, '.git');
|
|
271
|
+
if (!fs.existsSync(gitDir)) {
|
|
272
|
+
this.log('');
|
|
273
|
+
this.log('🔧 初始化 Git 仓库...');
|
|
274
|
+
this.spawnCommandSync('git', ['init'], {
|
|
275
|
+
cwd: this.destDir,
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
213
279
|
this.log('');
|
|
214
280
|
this.log('📦 正在安装依赖...');
|
|
215
281
|
this.spawnCommandSync('pnpm', ['install'], {
|
|
@@ -218,6 +284,9 @@ module.exports = class extends Generator {
|
|
|
218
284
|
}
|
|
219
285
|
|
|
220
286
|
end() {
|
|
287
|
+
// 跳过 dry-run 模式
|
|
288
|
+
if (this._skipInstall) return;
|
|
289
|
+
|
|
221
290
|
this.log('');
|
|
222
291
|
this.log('✅ 项目创建成功!');
|
|
223
292
|
this.log('');
|
|
@@ -19,7 +19,30 @@ module.exports = {
|
|
|
19
19
|
},
|
|
20
20
|
],
|
|
21
21
|
},
|
|
22
|
-
|
|
22
|
+
// TypeScript 文件使用专门的 parser
|
|
23
|
+
overrides: [
|
|
24
|
+
{
|
|
25
|
+
files: ["*.ts", "*.tsx"],
|
|
26
|
+
parser: "@typescript-eslint/parser",
|
|
27
|
+
plugins: ["@typescript-eslint"],
|
|
28
|
+
extends: [
|
|
29
|
+
"eslint:recommended",
|
|
30
|
+
"plugin:@typescript-eslint/recommended",
|
|
31
|
+
],
|
|
32
|
+
rules: {
|
|
33
|
+
// 使用 TS 版本的 no-unused-vars
|
|
34
|
+
"no-unused-vars": "off",
|
|
35
|
+
"@typescript-eslint/no-unused-vars": [
|
|
36
|
+
"warn",
|
|
37
|
+
{
|
|
38
|
+
argsIgnorePattern: "^_",
|
|
39
|
+
varsIgnorePattern: "^_",
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
// 忽略 apps/ 子包和 scripts/,apps由内部的eslint规则处理
|
|
23
46
|
ignorePatterns: [
|
|
24
47
|
'node_modules/',
|
|
25
48
|
'dist/',
|
|
@@ -53,15 +53,21 @@ apps/ # Workspace 应用目录(微前端子应用)
|
|
|
53
53
|
│ │ ├── app.tsx # Umi 运行时配置
|
|
54
54
|
│ │ ├── layouts/ # 布局组件
|
|
55
55
|
│ │ ├── pages/ # 路由页面
|
|
56
|
-
│ │ ├── components/ #
|
|
56
|
+
│ │ ├── components/ # 公共组件(MicroAppLoader 等)
|
|
57
57
|
│ │ ├── common/ # 工具模块(auth、request、upload、menu)
|
|
58
|
+
│ │ ├── constants/ # 常量定义(路由、主题、时区等)
|
|
58
59
|
│ │ ├── hooks/ # 自定义 Hooks
|
|
59
60
|
│ │ ├── services/ # API 服务层
|
|
60
61
|
│ │ ├── models/ # Umi model(全局状态)
|
|
61
|
-
│ │
|
|
62
|
-
│ │ └── styles/ # 主题变量与样式覆盖
|
|
62
|
+
│ │ └── locales/ # 国际化文件(zh-CN、en-US)
|
|
63
63
|
│ └── config/ # Umi 配置
|
|
64
|
-
|
|
64
|
+
├── basis/ # 基础数据子应用(货币管理等)
|
|
65
|
+
│ ├── src/
|
|
66
|
+
│ │ ├── pages/ # 路由页面
|
|
67
|
+
│ │ ├── locales/ # 国际化文件
|
|
68
|
+
│ │ └── common/ # 工具模块
|
|
69
|
+
│ └── config/ # Umi 配置
|
|
70
|
+
packages/ # 共享包(common-intl 等)
|
|
65
71
|
scripts/ # 构建与开发脚本
|
|
66
72
|
CICD/ # 部署资源
|
|
67
73
|
```
|
|
@@ -97,7 +103,7 @@ refactor(auth): 重构认证服务
|
|
|
97
103
|
API 请求配置在 `src/common/request/`(模块化拆分为 6 个文件),错误处理在 `src/requestErrorConfig.ts`。详见 [请求模块架构](./apps/layout/docs/arch-请求模块.md)。
|
|
98
104
|
|
|
99
105
|
### 日志与常量
|
|
100
|
-
Logger 工具在 `src/common/logger.ts`,常量定义在 `src/
|
|
106
|
+
Logger 工具在 `src/common/logger.ts`,常量定义在 `src/constants/index.ts`。详见 [日志与常量](./apps/layout/docs/arch-日志与常量.md)。
|
|
101
107
|
|
|
102
108
|
### 认证模块
|
|
103
109
|
认证逻辑在 `src/common/auth/`,核心文件 `auth-manager.ts` 管理 Token 存储和用户信息。SSO 登录在 `getInitialState()` 中完成,确保 UI 渲染前认证已就绪。
|
|
@@ -118,6 +118,27 @@ const config: ReturnType<typeof defineConfig> = {
|
|
|
118
118
|
*/
|
|
119
119
|
tailwindcss: {},
|
|
120
120
|
|
|
121
|
+
/**
|
|
122
|
+
* @name 额外 Babel Presets
|
|
123
|
+
* @description 使用 @mico-platform/ui 的 babel preset,实现组件与图标的按需加载
|
|
124
|
+
*/
|
|
125
|
+
extraBabelPresets: ['@mico-platform/ui/babel-preset'],
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* @name MFSU 配置
|
|
129
|
+
* @description
|
|
130
|
+
* - exclude: theme 子路径解析;ui 尽量与主应用一起编译
|
|
131
|
+
* - shared: React 单例,确保 MFSU 预打包里的组件(如 Layout)与主应用共用同一份 React,否则 useContext 报 null
|
|
132
|
+
* @doc https://umijs.org/docs/guides/mfsu
|
|
133
|
+
*/
|
|
134
|
+
mfsu: {
|
|
135
|
+
exclude: ['@mico-platform/theme', '@mico-platform/ui'],
|
|
136
|
+
shared: {
|
|
137
|
+
react: { singleton: true },
|
|
138
|
+
'react-dom': { singleton: true },
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
|
|
121
142
|
/**
|
|
122
143
|
* @name qiankun 微前端配置
|
|
123
144
|
* @description 作为主应用,动态加载子应用
|