generator-mico-cli 0.2.16 → 0.2.18

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 (39) hide show
  1. package/README.md +12 -0
  2. package/bin/mico.js +101 -5
  3. package/generators/micro-react/index.js +46 -0
  4. package/generators/micro-react/meta.json +12 -0
  5. package/generators/micro-react/templates/.cursor/rules/cicd-deploy.mdc +10 -8
  6. package/generators/micro-react/templates/.cursor/rules/development-guide.mdc +1 -1
  7. package/generators/micro-react/templates/AGENTS.md +3 -0
  8. package/generators/micro-react/templates/CICD/start_dev.sh +2 -1
  9. package/generators/micro-react/templates/CICD/start_prod.sh +2 -1
  10. package/generators/micro-react/templates/CICD/start_test.sh +2 -1
  11. package/generators/micro-react/templates/CICD/wangsu_fresh_dev.sh +4 -4
  12. package/generators/micro-react/templates/CICD/wangsu_fresh_prod.sh +4 -4
  13. package/generators/micro-react/templates/CICD/wangsu_fresh_test.sh +4 -4
  14. package/generators/micro-react/templates/README.md +39 -1
  15. package/generators/micro-react/templates/apps/layout/config/config.dev.ts +1 -1
  16. package/generators/micro-react/templates/apps/layout/config/config.prod.testing.ts +1 -1
  17. package/generators/micro-react/templates/apps/layout/config/config.prod.ts +3 -3
  18. package/generators/micro-react/templates/apps/layout/config/config.ts +1 -1
  19. 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
  20. 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 +4 -4
  21. package/generators/micro-react/templates/apps/layout/src/app.tsx +2 -2
  22. package/generators/micro-react/templates/apps/layout/src/components/HeaderDropdown/index.tsx +0 -2
  23. package/generators/micro-react/templates/apps/layout/src/components/MicroAppLoader/index.tsx +3 -0
  24. package/generators/micro-react/templates/apps/layout/src/layouts/index.less +2 -1
  25. package/generators/micro-react/templates/deployDesc.md +3 -3
  26. package/generators/micro-react/templates/dev.preset.json +14 -0
  27. package/generators/micro-react/templates/docs/dev-preset.md +130 -0
  28. package/generators/micro-react/templates/package.json +2 -0
  29. package/generators/micro-react/templates/scripts/dev-preset.js +265 -0
  30. package/generators/micro-react/templates/scripts/dev-preset.schema.json +39 -0
  31. package/generators/subapp-react/index.js +31 -1
  32. package/generators/subapp-react/meta.json +10 -0
  33. package/generators/subapp-react/templates/homepage/config/config.dev.ts +2 -3
  34. package/generators/subapp-react/templates/homepage/config/config.prod.development.ts +1 -1
  35. package/generators/subapp-react/templates/homepage/config/config.prod.testing.ts +1 -1
  36. package/generators/subapp-react/templates/homepage/config/config.prod.ts +1 -1
  37. package/generators/subapp-react/templates/homepage/src/pages/index.tsx +1 -1
  38. package/lib/utils.js +49 -1
  39. package/package.json +3 -2
package/README.md CHANGED
@@ -36,6 +36,18 @@ mico create subapp-react
36
36
  yo subapp-react
37
37
  ```
38
38
 
39
+ 列出所有可用的生成器:
40
+
41
+ ```bash
42
+ mico list
43
+ ```
44
+
45
+ 使用详细输出模式(显示文件处理过程):
46
+
47
+ ```bash
48
+ mico create micro-react --verbose
49
+ ```
50
+
39
51
  将额外参数传递给生成器:
40
52
 
41
53
  ```bash
package/bin/mico.js CHANGED
@@ -20,16 +20,19 @@ Usage: mico <command> [options]
20
20
 
21
21
  Commands:
22
22
  create <generator> Run a generator (e.g., mico create subapp-react)
23
+ list List all available generators
23
24
  update Update mico-cli to the latest version
24
25
 
25
26
  Options:
26
27
  --help, -h Show this help message
27
28
  --version, -v Show version number
29
+ --verbose Show detailed output during generation
28
30
  --no-update-check Skip update check
29
31
 
30
32
  Examples:
31
33
  mico create subapp-react
32
- mico create app
34
+ mico create micro-react --verbose
35
+ mico list
33
36
  mico update
34
37
 
35
38
  Notes:
@@ -38,6 +41,76 @@ Notes:
38
41
  `);
39
42
  }
40
43
 
44
+ /**
45
+ * 列出所有可用的生成器
46
+ */
47
+ function listGenerators() {
48
+ const generatorsDir = path.join(rootDir, 'generators');
49
+
50
+ if (!fs.existsSync(generatorsDir)) {
51
+ console.error('❌ Error: generators directory not found.');
52
+ process.exit(1);
53
+ }
54
+
55
+ const entries = fs.readdirSync(generatorsDir, { withFileTypes: true });
56
+ const generators = [];
57
+
58
+ for (const entry of entries) {
59
+ if (!entry.isDirectory()) continue;
60
+
61
+ const generatorPath = path.join(generatorsDir, entry.name);
62
+ const indexPath = path.join(generatorPath, 'index.js');
63
+ const metaPath = path.join(generatorPath, 'meta.json');
64
+
65
+ // 必须有 index.js 才算有效生成器
66
+ if (!fs.existsSync(indexPath)) continue;
67
+
68
+ let meta = { name: entry.name, description: '(No description)' };
69
+ if (fs.existsSync(metaPath)) {
70
+ try {
71
+ meta = { ...meta, ...JSON.parse(fs.readFileSync(metaPath, 'utf8')) };
72
+ } catch {
73
+ // 忽略解析错误
74
+ }
75
+ }
76
+
77
+ generators.push(meta);
78
+ }
79
+
80
+ if (generators.length === 0) {
81
+ console.log('');
82
+ console.log(' No generators found.');
83
+ console.log('');
84
+ return;
85
+ }
86
+
87
+ console.log('');
88
+ console.log(` \x1b[1mAvailable Generators\x1b[0m (mico-cli v${pkg.version})`);
89
+ console.log('');
90
+
91
+ // 计算最长名称用于对齐
92
+ const maxNameLen = Math.max(...generators.map((g) => g.name.length));
93
+
94
+ for (const gen of generators) {
95
+ const name = gen.name.padEnd(maxNameLen + 2);
96
+ console.log(` \x1b[36m${name}\x1b[0m ${gen.description}`);
97
+
98
+ // 如果有 features,显示特性列表
99
+ if (gen.features && gen.features.length > 0) {
100
+ for (const feature of gen.features) {
101
+ console.log(` ${' '.repeat(maxNameLen + 2)} • ${feature}`);
102
+ }
103
+ }
104
+
105
+ // 如果有 usage,显示用法
106
+ if (gen.usage) {
107
+ console.log(` ${' '.repeat(maxNameLen + 2)} \x1b[2m$ ${gen.usage}\x1b[0m`);
108
+ }
109
+
110
+ console.log('');
111
+ }
112
+ }
113
+
41
114
  /**
42
115
  * 打印版本信息
43
116
  */
@@ -178,8 +251,13 @@ function performUpdate(latestVersion) {
178
251
 
179
252
  /**
180
253
  * 运行 Yeoman 生成器
254
+ * @param {string} generator - 生成器名称
255
+ * @param {string[]} rest - 剩余参数
256
+ * @param {string[]} passthroughArgs - 透传参数
257
+ * @param {object} options - 选项
258
+ * @param {boolean} options.verbose - 是否启用详细输出
181
259
  */
182
- function runGenerator(generator, rest, passthroughArgs) {
260
+ function runGenerator(generator, rest, passthroughArgs, options = {}) {
183
261
  const localGeneratorEntry = path.join(
184
262
  rootDir,
185
263
  'generators',
@@ -201,7 +279,17 @@ function runGenerator(generator, rest, passthroughArgs) {
201
279
  yoArgs.push('--', ...passthroughArgs);
202
280
  }
203
281
 
204
- const child = spawn('yo', yoArgs, { stdio: 'inherit' });
282
+ // 通过环境变量传递 verbose 标志给生成器
283
+ const env = { ...process.env };
284
+ if (options.verbose) {
285
+ env.MICO_VERBOSE = '1';
286
+ console.log('');
287
+ console.log(' \x1b[2m[verbose] Running generator:', yoGenerator, '\x1b[0m');
288
+ console.log(' \x1b[2m[verbose] Arguments:', yoArgs.join(' '), '\x1b[0m');
289
+ console.log('');
290
+ }
291
+
292
+ const child = spawn('yo', yoArgs, { stdio: 'inherit', env });
205
293
 
206
294
  child.on('error', (error) => {
207
295
  if (error && error.code === 'ENOENT') {
@@ -234,6 +322,7 @@ async function main() {
234
322
  const hasHelp = mainArgs.includes('--help') || mainArgs.includes('-h');
235
323
  const hasVersion = mainArgs.includes('--version') || mainArgs.includes('-v');
236
324
  const skipUpdateCheck = mainArgs.includes('--no-update-check');
325
+ const isVerbose = mainArgs.includes('--verbose');
237
326
 
238
327
  // 过滤掉标志参数
239
328
  const filteredArgs = mainArgs.filter(
@@ -242,7 +331,8 @@ async function main() {
242
331
  arg !== '-h' &&
243
332
  arg !== '--version' &&
244
333
  arg !== '-v' &&
245
- arg !== '--no-update-check'
334
+ arg !== '--no-update-check' &&
335
+ arg !== '--verbose'
246
336
  );
247
337
 
248
338
  // 处理 --version
@@ -259,6 +349,12 @@ async function main() {
259
349
 
260
350
  const [command, ...rest] = filteredArgs;
261
351
 
352
+ // 处理 list 命令
353
+ if (command === 'list' || command === 'ls') {
354
+ listGenerators();
355
+ process.exit(0);
356
+ }
357
+
262
358
  // 处理 update 命令
263
359
  if (command === 'update') {
264
360
  const updateInfo = await checkForUpdate();
@@ -300,7 +396,7 @@ async function main() {
300
396
  }
301
397
 
302
398
  // 运行生成器
303
- runGenerator(generator, rest.slice(1), passthroughArgs);
399
+ runGenerator(generator, rest.slice(1), passthroughArgs, { verbose: isVerbose });
304
400
  return;
305
401
  }
306
402
 
@@ -11,6 +11,8 @@ const {
11
11
  isTemplateFile,
12
12
  getLatestNpmVersion,
13
13
  setupErrorHandlers,
14
+ createLogger,
15
+ // isVerbose,
14
16
  } = require('../../lib/utils');
15
17
 
16
18
  const IGNORE_LIST = require('./ignore-list.json');
@@ -21,6 +23,7 @@ setupErrorHandlers();
21
23
  module.exports = class extends Generator {
22
24
  initializing() {
23
25
  this.projectRoot = process.cwd();
26
+ this.logger = createLogger(this);
24
27
 
25
28
  // 检查当前目录是否已是一个 monorepo
26
29
  const workspaceFile = path.join(this.projectRoot, 'pnpm-workspace.yaml');
@@ -68,6 +71,21 @@ module.exports = class extends Generator {
68
71
  return true;
69
72
  },
70
73
  },
74
+ {
75
+ type: 'input',
76
+ name: 'cdnPrefix',
77
+ message: `CDN path prefix (用于区分不同业务线的 CDN 目录)
78
+ 示例:CDN 完整路径 = https://cdn.example.com/<prefix>/<projectName>/<version>/
79
+ - 留空: https://cdn.example.com/my-project/1.0.0/
80
+ - 输入 "portal": https://cdn.example.com/portal/my-project/1.0.0/
81
+ - 输入 "admin/v2": https://cdn.example.com/admin/v2/my-project/1.0.0/
82
+ Prefix`,
83
+ default: '',
84
+ filter: (input) => {
85
+ // 移除首尾斜杠,规范化路径
86
+ return input.trim().replace(/^\/+|\/+$/g, '');
87
+ },
88
+ },
71
89
  {
72
90
  type: 'input',
73
91
  name: 'author',
@@ -79,6 +97,7 @@ module.exports = class extends Generator {
79
97
  this.projectName = toKebab(this.answers.projectName);
80
98
  this.ProjectName = toPascal(this.projectName);
81
99
  this.packageScope = this.answers.packageScope;
100
+ this.cdnPrefix = this.answers.cdnPrefix;
82
101
  this.author = this.answers.author;
83
102
  this.templateDir = this.templatePath();
84
103
  this.destDir = this.projectRoot;
@@ -101,8 +120,13 @@ module.exports = class extends Generator {
101
120
  process.exit(1);
102
121
  }
103
122
 
123
+ this.logger.verbose('Template directory:', this.templateDir);
124
+ this.logger.verbose('Destination directory:', this.destDir);
125
+
104
126
  // 在 mico_cli 根目录执行 npm view,以使用该目录 .npmrc 中的 Nexus 认证
105
127
  const cliRoot = path.resolve(__dirname, '../..');
128
+ this.logger.verbose('Fetching latest package versions...');
129
+
106
130
  const micoUiVer = getLatestNpmVersion(
107
131
  '@mico-platform/ui',
108
132
  '1.0.0',
@@ -115,6 +139,13 @@ module.exports = class extends Generator {
115
139
  8000,
116
140
  cliRoot,
117
141
  );
142
+
143
+ this.logger.verbose('@mico-platform/ui version:', micoUiVer);
144
+ this.logger.verbose('@mico-platform/theme version:', themeVer);
145
+
146
+ // 构建 CDN 路径片段:如果有 prefix 则加上斜杠前缀,否则为空
147
+ const cdnPrefixPath = this.cdnPrefix ? `${this.cdnPrefix}/` : '';
148
+
118
149
  const templateData = {
119
150
  projectName: this.projectName,
120
151
  ProjectName: this.ProjectName,
@@ -122,8 +153,12 @@ module.exports = class extends Generator {
122
153
  author: this.author,
123
154
  micoUiVersion: `^${micoUiVer}`,
124
155
  themeVersion: `^${themeVer}`,
156
+ cdnPrefix: this.cdnPrefix,
157
+ cdnPrefixPath, // 用于拼接路径,已包含尾部斜杠
125
158
  };
126
159
 
160
+ this.logger.verbose('Template data:', JSON.stringify(templateData, null, 2));
161
+
127
162
  const files = collectFiles(
128
163
  this.templateDir,
129
164
  this.templateDir,
@@ -143,17 +178,28 @@ module.exports = class extends Generator {
143
178
  this.log(` Scope: ${this.packageScope}`);
144
179
  this.log('');
145
180
 
181
+ this.logger.verbose(`Processing ${files.length} files...`);
182
+
183
+ let templateCount = 0;
184
+ let copyCount = 0;
185
+
146
186
  for (const relPath of files) {
147
187
  const srcPath = path.join(this.templateDir, relPath);
148
188
  const destRelPath = transformDestPath(relPath);
149
189
  const destPath = path.join(this.destDir, destRelPath);
150
190
 
151
191
  if (isTemplateFile(relPath)) {
192
+ this.logger.file('template', destRelPath);
152
193
  this.fs.copyTpl(srcPath, destPath, templateData);
194
+ templateCount++;
153
195
  } else {
196
+ this.logger.file('copy', destRelPath);
154
197
  this.fs.copy(srcPath, destPath);
198
+ copyCount++;
155
199
  }
156
200
  }
201
+
202
+ this.logger.verbose(`Processed: ${templateCount} templates, ${copyCount} copied`);
157
203
  } catch (error) {
158
204
  console.error('');
159
205
  console.error('❌ Error during file generation:');
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "micro-react",
3
+ "description": "创建基于 qiankun 的微前端 Monorepo 项目",
4
+ "usage": "mkdir my-project && cd my-project && mico create micro-react",
5
+ "features": [
6
+ "Turborepo + pnpm Workspace",
7
+ "qiankun 微前端架构",
8
+ "Arco Design + Tailwind CSS",
9
+ "主题切换、国际化、认证模块",
10
+ "可配置 CDN 路径前缀(支持多业务线隔离)"
11
+ ]
12
+ }
@@ -21,7 +21,7 @@ globs: ["CICD/**", "deployDesc.md"]
21
21
  │ ↓ │
22
22
  │ ┌─────────────────────────────────────────────────────────────┐│
23
23
  │ │ 构建产物:dist/{app}/ ││
24
- │ │ 上传 CDN:cdn-portal[-env].micoplatform.com/<%= projectName %>/ ││
24
+ │ │ 上传 CDN:cdn-portal[-env].micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/ ││
25
25
  │ └─────────────────────────────────────────────────────────────┘│
26
26
  └─────────────────────────────────────────────────────────────────┘
27
27
  ```
@@ -51,7 +51,7 @@ pnpm install
51
51
  VERSION=$(node -p "require('./package.json').version")
52
52
 
53
53
  # 3. 设置 CDN 路径
54
- export CDN_PUBLIC_PATH="https://cdn-portal[-env].micoplatform.com/<%= projectName %>/${VERSION}/"
54
+ export CDN_PUBLIC_PATH="https://cdn-portal[-env].micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/${VERSION}/"
55
55
 
56
56
  # 4. 执行构建
57
57
  pnpm run build:[environment]
@@ -78,12 +78,14 @@ echo "VERSION=$VERSION" > .env_x_<%= projectName %>
78
78
  ### CDN 路径结构
79
79
  ```
80
80
  cdn-portal.micoplatform.com/
81
- └── <%= projectName %>/
82
- └── {version}/
83
- └── dist/
84
- ├── layout/ # 主应用
85
- ├── homepage/ # 子应用
86
- └── ...
81
+ <% if (cdnPrefix) { %>└── <%= cdnPrefix %>/
82
+ └── <%= projectName %>/
83
+ <% } else { %>└── <%= projectName %>/
84
+ <% } %> └── {version}/
85
+ └── dist/
86
+ ├── layout/ # 主应用
87
+ ├── homepage/ # 子应用
88
+ └── ...
87
89
  ```
88
90
 
89
91
  ## 环境变量
@@ -273,7 +273,7 @@ sh CICD/start_prod.sh
273
273
 
274
274
  构建产物上传到 CDN:
275
275
  ```
276
- cdn-portal[-env].micoplatform.com/<%= projectName %>/{version}/dist/{app}/
276
+ cdn-portal[-env].micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/{version}/dist/{app}/
277
277
  ```
278
278
 
279
279
  - `version`:`package.json` 的 version 字段
@@ -22,6 +22,9 @@
22
22
 
23
23
  - `pnpm install` 安装 workspace 依赖。
24
24
  - `pnpm dev` 运行交互式开发启动器(选择应用)。
25
+ - `pnpm dev:preset` 根据 `dev.preset.json` 配置,一次性并行启动多个应用。
26
+ - `pnpm dev:preset <preset>` 使用指定预设启动多应用。
27
+ - `pnpm list:preset` 列出所有可用的启动预设。
25
28
  - `pnpm -C apps/<app> dev` 直接运行指定应用。
26
29
  - `pnpm build` 构建所有应用用于生产环境;`pnpm build:development|testing|production|local` 设置不同环境模式。
27
30
  - `pnpm lint` 运行 ESLint + Turbo lint 检查;`pnpm lint:fix` 自动修复。
@@ -30,7 +30,8 @@ if [ -f "$PROJECT_ROOT/CICD/before_build.sh" ]; then
30
30
  fi
31
31
 
32
32
  # 设置子应用的 CDN 公共路径(开发环境)
33
- export CDN_PUBLIC_PATH="https://cdn-portal-dev.micoplatform.com/<%= projectName %>/${VERSION}/"
33
+ # 路径格式: https://cdn-xxx.com/<prefix>/<projectName>/<version>/
34
+ export CDN_PUBLIC_PATH="https://cdn-portal-dev.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/${VERSION}/"
34
35
  echo "CDN_PUBLIC_PATH: $CDN_PUBLIC_PATH"
35
36
 
36
37
  pnpm run build:development
@@ -30,7 +30,8 @@ if [ -f "$PROJECT_ROOT/CICD/before_build.sh" ]; then
30
30
  fi
31
31
 
32
32
  # 设置子应用的 CDN 公共路径(生产环境)
33
- export CDN_PUBLIC_PATH="https://cdn-portal.micoplatform.com/<%= projectName %>/${VERSION}/"
33
+ # 路径格式: https://cdn-xxx.com/<prefix>/<projectName>/<version>/
34
+ export CDN_PUBLIC_PATH="https://cdn-portal.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/${VERSION}/"
34
35
  echo "CDN_PUBLIC_PATH: $CDN_PUBLIC_PATH"
35
36
 
36
37
  pnpm run build:production
@@ -31,7 +31,8 @@ fi
31
31
 
32
32
 
33
33
  # 设置子应用的 CDN 公共路径(测试环境)
34
- export CDN_PUBLIC_PATH="https://cdn-portal-test.micoplatform.com/<%= projectName %>/${VERSION}/"
34
+ # 路径格式: https://cdn-xxx.com/<prefix>/<projectName>/<version>/
35
+ export CDN_PUBLIC_PATH="https://cdn-portal-test.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/${VERSION}/"
35
36
  echo "CDN_PUBLIC_PATH: $CDN_PUBLIC_PATH"
36
37
 
37
38
  pnpm run build:testing
@@ -5,13 +5,13 @@ apiKey=$(cat ~/.wangsu_key)
5
5
  date=`env LANG="en_US.UTF-8" date -u "+%a, %d %b %Y %H:%M:%S GMT"`
6
6
  password=`echo -en "$date" | openssl dgst -sha1 -hmac $apiKey -binary | openssl enc -base64`
7
7
  echo "打印刷新地址"
8
- echo "dir1:http://cdn-portal-dev.micoplatform.com/<%= projectName %>/$version/"
9
- echo "dir2:https://cdn-portal-dev.micoplatform.com/<%= projectName %>/$version/"
8
+ echo "dir1:http://cdn-portal-dev.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version/"
9
+ echo "dir2:https://cdn-portal-dev.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version/"
10
10
  curl -i --url "https://open.chinanetcenter.com/ccm/purge/ItemIdReceiver" -X "POST" -u "$username:$password" -H "Date:$date" -H "Content-Type: application/json" --data-binary @- <<EOF
11
11
  {
12
12
  "dirs": [
13
- "http://cdn-portal-dev.micoplatform.com/<%= projectName %>/$version",
14
- "https://cdn-portal-dev.micoplatform.com/<%= projectName %>/$version"
13
+ "http://cdn-portal-dev.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version",
14
+ "https://cdn-portal-dev.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version"
15
15
  ],
16
16
  "dirAction":"expire"
17
17
  }
@@ -5,13 +5,13 @@ apiKey=$(cat ~/.wangsu_key)
5
5
  date=`env LANG="en_US.UTF-8" date -u "+%a, %d %b %Y %H:%M:%S GMT"`
6
6
  password=`echo -en "$date" | openssl dgst -sha1 -hmac $apiKey -binary | openssl enc -base64`
7
7
  echo "打印刷新地址"
8
- echo "dir1:http://cdn-portal.micoplatform.com/<%= projectName %>/$version/"
9
- echo "dir2:https://cdn-portal.micoplatform.com/<%= projectName %>/$version/"
8
+ echo "dir1:http://cdn-portal.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version/"
9
+ echo "dir2:https://cdn-portal.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version/"
10
10
  curl -i --url "https://open.chinanetcenter.com/ccm/purge/ItemIdReceiver" -X "POST" -u "$username:$password" -H "Date:$date" -H "Content-Type: application/json" --data-binary @- <<EOF
11
11
  {
12
12
  "dirs": [
13
- "http://cdn-portal.micoplatform.com/<%= projectName %>/$version",
14
- "https://cdn-portal.micoplatform.com/<%= projectName %>/$version"
13
+ "http://cdn-portal.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version",
14
+ "https://cdn-portal.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version"
15
15
  ],
16
16
  "dirAction":"expire"
17
17
  }
@@ -5,13 +5,13 @@ apiKey=$(cat ~/.wangsu_key)
5
5
  date=`env LANG="en_US.UTF-8" date -u "+%a, %d %b %Y %H:%M:%S GMT"`
6
6
  password=`echo -en "$date" | openssl dgst -sha1 -hmac $apiKey -binary | openssl enc -base64`
7
7
  echo "打印刷新地址"
8
- echo "dir1:http://cdn-portal-test.micoplatform.com/<%= projectName %>/$version/"
9
- echo "dir2:https://cdn-portal-test.micoplatform.com/<%= projectName %>/$version/"
8
+ echo "dir1:http://cdn-portal-test.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version/"
9
+ echo "dir2:https://cdn-portal-test.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version/"
10
10
  curl -i --url "https://open.chinanetcenter.com/ccm/purge/ItemIdReceiver" -X "POST" -u "$username:$password" -H "Date:$date" -H "Content-Type: application/json" --data-binary @- <<EOF
11
11
  {
12
12
  "dirs": [
13
- "http://cdn-portal-test.micoplatform.com/<%= projectName %>/$version",
14
- "https://cdn-portal-test.micoplatform.com/<%= projectName %>/$version"
13
+ "http://cdn-portal-test.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version",
14
+ "https://cdn-portal-test.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version"
15
15
  ],
16
16
  "dirAction":"expire"
17
17
  }
@@ -27,6 +27,9 @@ pnpm install
27
27
  | 命令 | 说明 |
28
28
  |------|------|
29
29
  | `pnpm dev` | 交互式选择并启动应用开发服务器 |
30
+ | `pnpm dev:preset` | 根据配置文件并行启动多个应用 |
31
+ | `pnpm dev:preset <preset>` | 使用指定预设启动(如 `pnpm dev:preset full`) |
32
+ | `pnpm list:preset` | 列出所有可用的启动预设 |
30
33
  | `pnpm build` | 构建所有应用(生产环境) |
31
34
  | `pnpm build:development` | 构建所有应用(开发环境) |
32
35
  | `pnpm build:testing` | 构建所有应用(测试环境) |
@@ -37,6 +40,39 @@ pnpm install
37
40
 
38
41
  > **提示**:也可以使用 `pnpm -C apps/<app-name> dev` 直接启动指定应用,例如 `pnpm -C apps/layout dev`。
39
42
 
43
+ ### 多应用并行启动
44
+
45
+ 通过 `dev.preset.json` 配置预设,一条命令并行启动多个应用:
46
+
47
+ ```bash
48
+ # 使用默认预设启动
49
+ pnpm dev:preset
50
+
51
+ # 使用指定预设
52
+ pnpm dev:preset full
53
+
54
+ # 查看所有预设
55
+ pnpm list:preset
56
+ ```
57
+
58
+ 预设配置文件 `dev.preset.json` 示例:
59
+
60
+ ```json
61
+ {
62
+ "presets": {
63
+ "full": {
64
+ "description": "启动所有应用",
65
+ "apps": ["layout", "subapp"]
66
+ }
67
+ },
68
+ "default": "full"
69
+ }
70
+ ```
71
+
72
+ 每个应用的日志会以不同颜色的前缀区分,按 `Ctrl+C` 同时停止所有应用。
73
+
74
+ 详细说明请参考 [多应用并行启动文档](./docs/dev-preset.md)。
75
+
40
76
  ## 新建子应用
41
77
 
42
78
  使用 Mico CLI 快速创建新的 React 子应用:
@@ -57,9 +93,11 @@ mico create subapp-react
57
93
  │ └── layout/ # 主应用(qiankun master)
58
94
  ├── packages/ # 共享包目录
59
95
  ├── scripts/ # 构建与开发脚本
60
- │ ├── dev.js # 交互式启动脚本
96
+ │ ├── dev.js # 交互式启动脚本(单应用)
97
+ │ ├── dev-preset.js # 多应用并行启动脚本
61
98
  │ ├── collect-dist.js # 构建产物收集
62
99
  │ └── create-umi-app.sh # 创建新应用
100
+ ├── dev.preset.json # 多应用启动预设配置
63
101
  ├── turbo.json # Turborepo 任务管道
64
102
  ├── pnpm-workspace.yaml # Workspace 包含范围
65
103
  └── .editorconfig # 编辑器统一约束
@@ -59,7 +59,7 @@ const config: ReturnType<typeof defineConfig> = {
59
59
  define: {
60
60
  'process.env.NODE_ENV': 'development',
61
61
  'process.env.APP_ID': '<%= projectName %>',
62
- 'process.env.API_BASE_URL': '',
62
+ 'process.env.API_BASE_URL': 'https://dashboard-api-test.micoplatform.com',
63
63
  'process.env.PROXY_SUFFIX': '/proxy/audit_svr',
64
64
  'process.env.LOGIN_ENDPOINT':
65
65
  'https://dashboard-api-test.micoplatform.com/api/yufu_login/',
@@ -6,7 +6,7 @@ const config: ReturnType<typeof defineConfig> = {
6
6
  define: {
7
7
  'process.env.NODE_ENV': 'testing',
8
8
  'process.env.APP_ID': '<%= projectName %>',
9
- 'process.env.API_BASE_URL': '',
9
+ 'process.env.API_BASE_URL': 'https://dashboard-api-test.micoplatform.com',
10
10
  'process.env.PROXY_SUFFIX': '/proxy/audit_svr',
11
11
  'process.env.LOGIN_ENDPOINT':
12
12
  'https://dashboard-api-test.micoplatform.com/api/yufu_login/',
@@ -11,12 +11,12 @@ const config: ReturnType<typeof defineConfig> = {
11
11
  define: {
12
12
  'process.env.NODE_ENV': 'production',
13
13
  'process.env.APP_ID': '<%= projectName %>',
14
- 'process.env.API_BASE_URL': '',
14
+ 'process.env.API_BASE_URL': 'https://dashboard-api.micoplatform.com',
15
15
  'process.env.PROXY_SUFFIX': '/proxy/audit_svr',
16
16
  'process.env.LOGIN_ENDPOINT':
17
- 'https://dashboard-api-test.micoplatform.com/api/yufu_login/',
17
+ 'https://dashboard-api.micoplatform.com/api/yufu_login/',
18
18
  'process.env.REFRESH_ENDPOINT':
19
- 'https://dashboard-api-test.micoplatform.com/api/yufu_login/refresh/',
19
+ 'https://dashboard-api.micoplatform.com/api/yufu_login/refresh/',
20
20
  'process.env.EXTERNAL_LOGIN_PATH':
21
21
  'https://micous-idp.cig.tencentcs.com/sso/xxxxxxx/cas',
22
22
  },
@@ -16,7 +16,7 @@ const config: ReturnType<typeof defineConfig> = {
16
16
  * @description React 应用挂载的 DOM 元素 id
17
17
  * @doc https://umijs.org/docs/api/config#mountelementid
18
18
  */
19
- mountElementId: '<%= projectName %>',
19
+ mountElementId: 'root',
20
20
 
21
21
  /**
22
22
  * @name 开启 hash 模式
@@ -198,7 +198,7 @@ wc -c apps/[子应用]/dist/umi.css
198
198
 
199
199
  #### 原理
200
200
 
201
- 1. 主应用加载 @mico-platform/ui 并暴露到 `window.micoUi`
201
+ 1. 主应用加载 @mico-platform/ui 并暴露到 `window.micoUI`
202
202
  2. 主应用的样式包含 `arco-theme` 属性选择器(基于 Arco)
203
203
  3. 主应用切换主题时设置 `body[arco-theme="dark"]`
204
204
  4. 子应用的 UI 组件(来自 window.micoUi)自动应用暗色样式
@@ -271,7 +271,7 @@ export const getRequest = () => mainAppProps?.request;
271
271
  │ 主应用 (layout) │
272
272
  │ ┌─────────────────────────────────────────────────────────┐│
273
273
  │ │ 1. 打包并加载 React、ReactDOM、@mico-platform/ui ││
274
- │ │ 2. 暴露到 window.React / window.ReactDOM / window.micoUi ││
274
+ │ │ 2. 暴露到 window.React / window.ReactDOM / window.micoUI ││
275
275
  │ └─────────────────────────────────────────────────────────┘│
276
276
  │ ↓ 共享 │
277
277
  │ ┌─────────────────────────────────────────────────────────┐│
@@ -289,7 +289,7 @@ export const getRequest = () => mainAppProps?.request;
289
289
 
290
290
  ```typescript
291
291
  // apps/layout/src/app.tsx
292
- import * as micoUi from '@mico-platform/ui';
292
+ import * as micoUI from '@mico-platform/ui';
293
293
  import React from 'react';
294
294
  import ReactDOM from 'react-dom';
295
295
 
@@ -297,7 +297,7 @@ import ReactDOM from 'react-dom';
297
297
  if (typeof window !== 'undefined') {
298
298
  (window as any).React = React;
299
299
  (window as any).ReactDOM = ReactDOM;
300
- (window as any).micoUi = micoUi;
300
+ (window as any).micoUI = micoUI;
301
301
  }
302
302
  ```
303
303
 
@@ -334,7 +334,7 @@ const config: ReturnType<typeof defineConfig> = {
334
334
  externals: {
335
335
  react: 'window.React',
336
336
  'react-dom': 'window.ReactDOM',
337
- '@mico-platform/ui': 'window.micoUi',
337
+ '@mico-platform/ui': 'window.micoUI',
338
338
  },
339
339
  };
340
340
 
@@ -2,7 +2,7 @@ import { history, type RequestConfig } from '@umijs/max';
2
2
  import { addGlobalUncaughtErrorHandler } from 'qiankun';
3
3
  import { errorConfig } from './requestErrorConfig';
4
4
  // 将 @mico-platform/ui 暴露到 window,供子应用 externals 使用
5
- import * as micoUi from '@mico-platform/ui';
5
+ import * as micoUI from '@mico-platform/ui';
6
6
  import React from 'react';
7
7
  import ReactDOM from 'react-dom/client';
8
8
 
@@ -86,7 +86,7 @@ if (typeof window !== 'undefined') {
86
86
  const win = window as unknown as Record<string, unknown>;
87
87
  win.React = React;
88
88
  win.ReactDOM = ReactDOM;
89
- win.micoUi = micoUi;
89
+ win.micoUI = micoUI;
90
90
  }
91
91
 
92
92
  // 初始化主题(在页面加载时立即执行,避免闪烁)