generator-mico-cli 0.1.0

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 (24) hide show
  1. package/README.md +65 -0
  2. package/bin/mico.js +81 -0
  3. package/generators/subapp-react/ignore-list.json +7 -0
  4. package/generators/subapp-react/index.js +131 -0
  5. package/generators/subapp-react/templates/homepage/.env +4 -0
  6. package/generators/subapp-react/templates/homepage/config/config.dev.ts +50 -0
  7. package/generators/subapp-react/templates/homepage/config/config.prod.ts +41 -0
  8. package/generators/subapp-react/templates/homepage/config/config.testing.ts +8 -0
  9. package/generators/subapp-react/templates/homepage/config/config.ts +102 -0
  10. package/generators/subapp-react/templates/homepage/config/routes.ts +7 -0
  11. package/generators/subapp-react/templates/homepage/mock/api.mock.ts +59 -0
  12. package/generators/subapp-react/templates/homepage/package.json +30 -0
  13. package/generators/subapp-react/templates/homepage/src/app.tsx +80 -0
  14. package/generators/subapp-react/templates/homepage/src/assets/yay.jpg +0 -0
  15. package/generators/subapp-react/templates/homepage/src/common/logger.ts +42 -0
  16. package/generators/subapp-react/templates/homepage/src/common/mainApp.ts +53 -0
  17. package/generators/subapp-react/templates/homepage/src/common/request.ts +49 -0
  18. package/generators/subapp-react/templates/homepage/src/global.less +26 -0
  19. package/generators/subapp-react/templates/homepage/src/pages/index.less +139 -0
  20. package/generators/subapp-react/templates/homepage/src/pages/index.tsx +342 -0
  21. package/generators/subapp-react/templates/homepage/src/styles/theme.less +6 -0
  22. package/generators/subapp-react/templates/homepage/tsconfig.json +3 -0
  23. package/generators/subapp-react/templates/homepage/typings.d.ts +17 -0
  24. package/package.json +28 -0
package/README.md ADDED
@@ -0,0 +1,65 @@
1
+ # Mico CLI Generator
2
+
3
+ 用于搭建基于 TypeScript 的 Node.js CLI 项目的 Yeoman 生成器。
4
+
5
+ ## 文档索引
6
+
7
+ - `docs/subapp-react-generator.md` React 子应用生成器说明
8
+
9
+ ## 要求
10
+
11
+ - Node >= 18
12
+ - Yeoman CLI: `npm install -g yo`
13
+
14
+ ## 安装和使用
15
+
16
+ ```bash
17
+ npm install -g yo generator-mico-cli
18
+ ```
19
+
20
+ ## 包装器 CLI
21
+
22
+ 全局安装后,`mico` 命令可用于委托给 Yeoman 生成器。
23
+ 如果 `generators/<name>` 下存在本地生成器,它将作为 `yo mico-cli:<name>` 运行。
24
+
25
+ ```bash
26
+ mico create subapp-react
27
+ ```
28
+
29
+ 等同于:
30
+
31
+ ```bash
32
+ yo subapp-react
33
+ ```
34
+
35
+ 将额外参数传递给生成器:
36
+
37
+ ```bash
38
+ mico create mirco-react -- --help
39
+ ```
40
+
41
+ ## React 子应用生成器(audit-center)
42
+
43
+ 该生成器会复制 `apps/homepage` 为新的子应用,并替换标识字符串。
44
+ `config/` 目录下的多环境配置会完整保留。
45
+
46
+ ```bash
47
+ cd <monorepo-root>
48
+ mico create subapp-react
49
+ ```
50
+
51
+ ## 同步子应用模板
52
+
53
+ 将 `audit-center/apps/homepage` 同步到生成器模板目录:
54
+
55
+ ```bash
56
+ AUDIT_CENTER_ROOT=<audit-center-root> npm run sync:subapp-react-template
57
+ ```
58
+
59
+ 也可以直接传入路径:
60
+
61
+ ```bash
62
+ npm run sync:subapp-react-template -- <audit-center-root>
63
+ ```
64
+
65
+ 忽略清单位于 `generators/subapp-react/ignore-list.json`。
package/bin/mico.js ADDED
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const { spawn } = require('node:child_process');
5
+ const fs = require('node:fs');
6
+ const path = require('node:path');
7
+
8
+ function printHelp() {
9
+ console.log('Usage: mico create <generator> [args]');
10
+ console.log(' mico create <generator> -- [args]');
11
+ console.log('');
12
+ console.log('Examples:');
13
+ console.log(' mico create mirco-react');
14
+ console.log(' mico create mico-cli -- --help');
15
+ console.log('');
16
+ console.log('Notes:');
17
+ console.log(' Requires Yeoman CLI (yo) installed globally.');
18
+ console.log(' If a local generator exists at generators/<name>, it will be used.');
19
+ }
20
+
21
+ const args = process.argv.slice(2);
22
+ const doubleDashIndex = args.indexOf('--');
23
+ const passthroughArgs =
24
+ doubleDashIndex === -1 ? [] : args.slice(doubleDashIndex + 1);
25
+ const mainArgs = doubleDashIndex === -1 ? args : args.slice(0, doubleDashIndex);
26
+ const hasHelp = mainArgs.includes('--help') || mainArgs.includes('-h');
27
+
28
+ if (mainArgs.length === 0 || hasHelp) {
29
+ printHelp();
30
+ process.exit(0);
31
+ }
32
+
33
+ const [command, generator, ...rest] = mainArgs;
34
+
35
+ if (command !== 'create' || !generator) {
36
+ printHelp();
37
+ process.exit(1);
38
+ }
39
+
40
+ const rootDir = path.resolve(__dirname, '..');
41
+ const localGeneratorEntry = path.join(
42
+ rootDir,
43
+ 'generators',
44
+ generator,
45
+ 'index.js'
46
+ );
47
+
48
+ let localNamespace = 'generator';
49
+ try {
50
+ const pkg = JSON.parse(
51
+ fs.readFileSync(path.join(rootDir, 'package.json'), 'utf8')
52
+ );
53
+ const pkgName = typeof pkg.name === 'string' ? pkg.name : '';
54
+ localNamespace = pkgName.replace(/^generator-/, '') || pkgName || localNamespace;
55
+ } catch {
56
+ // Fall back to a generic namespace
57
+ }
58
+
59
+ const yoGenerator = fs.existsSync(localGeneratorEntry)
60
+ ? `${localNamespace}:${generator}`
61
+ : generator;
62
+ const yoArgs = [yoGenerator, ...rest];
63
+
64
+ if (passthroughArgs.length > 0) {
65
+ yoArgs.push('--', ...passthroughArgs);
66
+ }
67
+
68
+ const child = spawn('yo', yoArgs, { stdio: 'inherit' });
69
+
70
+ child.on('error', (error) => {
71
+ if (error && error.code === 'ENOENT') {
72
+ console.error('Cannot find "yo". Install it with: npm install -g yo');
73
+ } else {
74
+ console.error(error);
75
+ }
76
+ process.exit(1);
77
+ });
78
+
79
+ child.on('exit', (code) => {
80
+ process.exit(typeof code === 'number' ? code : 1);
81
+ });
@@ -0,0 +1,7 @@
1
+ [
2
+ "node_modules",
3
+ "dist",
4
+ ".umi",
5
+ ".umi-production",
6
+ ".turbo"
7
+ ]
@@ -0,0 +1,131 @@
1
+ 'use strict';
2
+
3
+ const Generator = require('yeoman-generator');
4
+ const fs = require('node:fs');
5
+ const path = require('node:path');
6
+ const { toKebab, toPascal } = require('../../lib/utils');
7
+
8
+ const IGNORE_LIST = require('./ignore-list.json');
9
+
10
+ /**
11
+ * 检查路径是否应该被忽略
12
+ */
13
+ function shouldIgnorePath(sourceRoot, currentPath) {
14
+ const rel = path.relative(sourceRoot, currentPath);
15
+ if (!rel || rel.startsWith('..')) return false;
16
+ const parts = rel.split(path.sep);
17
+ return parts.some((part) => IGNORE_LIST.includes(part));
18
+ }
19
+
20
+ /**
21
+ * 递归遍历目录,收集所有文件的相对路径
22
+ */
23
+ function collectFiles(dir, sourceRoot, files = []) {
24
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
25
+ const fullPath = path.join(dir, entry.name);
26
+ if (shouldIgnorePath(sourceRoot, fullPath)) continue;
27
+
28
+ if (entry.isDirectory()) {
29
+ collectFiles(fullPath, sourceRoot, files);
30
+ } else if (entry.isFile()) {
31
+ files.push(path.relative(sourceRoot, fullPath));
32
+ }
33
+ }
34
+ return files;
35
+ }
36
+
37
+ /**
38
+ * 需要使用 EJS 模板处理的文件扩展名
39
+ */
40
+ const TEMPLATE_EXTENSIONS = new Set([
41
+ '.ts',
42
+ '.tsx',
43
+ '.js',
44
+ '.jsx',
45
+ '.json',
46
+ '.less',
47
+ '.md'
48
+ ]);
49
+
50
+ module.exports = class extends Generator {
51
+ async prompting() {
52
+ this.answers = await this.prompt([
53
+ {
54
+ type: 'input',
55
+ name: 'appName',
56
+ message: 'Sub app name',
57
+ default: 'subapp',
58
+ filter: (input) => toKebab(input),
59
+ validate: (input) => {
60
+ const value = toKebab(input);
61
+ if (!value) return 'App name is required';
62
+ return true;
63
+ }
64
+ }
65
+ ]);
66
+
67
+ this.monorepoRoot = this.destinationRoot();
68
+ this.appName = toKebab(this.answers.appName);
69
+ this.appNamePascal = toPascal(this.appName);
70
+ this.templateDir = this.templatePath('homepage');
71
+ this.destDir = path.join(this.monorepoRoot, 'apps', this.appName);
72
+ }
73
+
74
+ writing() {
75
+ const appsDir = path.join(this.monorepoRoot, 'apps');
76
+ const workspaceFile = path.join(this.monorepoRoot, 'pnpm-workspace.yaml');
77
+
78
+ // 检查是否在 monorepo 中
79
+ if (!fs.existsSync(appsDir)) {
80
+ this.env.error(
81
+ `apps directory not found in ${this.monorepoRoot}. Run this generator from the monorepo root.`
82
+ );
83
+ return;
84
+ }
85
+
86
+ // 警告:检查是否是 pnpm workspace
87
+ if (!fs.existsSync(workspaceFile)) {
88
+ this.log.warning(
89
+ 'pnpm-workspace.yaml not found. Make sure you are in the correct monorepo.'
90
+ );
91
+ }
92
+
93
+ if (fs.existsSync(this.destDir)) {
94
+ this.env.error(`Target already exists: ${this.destDir}`);
95
+ return;
96
+ }
97
+
98
+ // 模板数据
99
+ const templateData = {
100
+ appName: this.appName,
101
+ AppName: this.appNamePascal
102
+ };
103
+
104
+ // 收集所有文件
105
+ const files = collectFiles(this.templateDir, this.templateDir);
106
+
107
+ for (const relPath of files) {
108
+ const srcPath = path.join(this.templateDir, relPath);
109
+ const destPath = path.join(this.destDir, relPath);
110
+ const ext = path.extname(relPath);
111
+
112
+ if (TEMPLATE_EXTENSIONS.has(ext)) {
113
+ // 使用 EJS 模板处理
114
+ this.fs.copyTpl(srcPath, destPath, templateData);
115
+ } else {
116
+ // 直接复制(图片等二进制文件)
117
+ this.fs.copy(srcPath, destPath);
118
+ }
119
+ }
120
+ }
121
+
122
+ end() {
123
+ this.log('');
124
+ this.log('✅ 子应用创建成功!');
125
+ this.log('');
126
+ this.log(` cd apps/${this.appName}`);
127
+ this.log(' pnpm install');
128
+ this.log(' pnpm dev');
129
+ this.log('');
130
+ }
131
+ };
@@ -0,0 +1,4 @@
1
+ # Default: 5
2
+ CHECK_TIMEOUT=10
3
+ DID_YOU_KNOW=none
4
+ PORT=8010
@@ -0,0 +1,50 @@
1
+ // https://umijs.org/config/
2
+
3
+ import { defineConfig } from '@umijs/max';
4
+
5
+ /**
6
+ * 开发环境配置
7
+ * - 不配置 externals,直接打包依赖,方便独立运行调试
8
+ * - 生产环境通过 config.prod.ts 配置 externals 复用主应用依赖
9
+ */
10
+ const config: ReturnType<typeof defineConfig> = {
11
+ publicPath: '/',
12
+ base: '/',
13
+
14
+ define: {
15
+ 'process.env.NODE_ENV': 'development',
16
+ },
17
+ // /**
18
+ // * @name 脚本加载配置
19
+ // * @description 开发环境独立运行时,通过 CDN 加载公共依赖
20
+ // * 作为微前端子应用运行时,这些库由主应用提供
21
+ // */
22
+ // headScripts: [
23
+ // 'https://unpkg.com/react@18/umd/react.development.js',
24
+ // 'https://unpkg.com/react-dom@18/umd/react-dom.development.js',
25
+ // 'https://unpkg.com/@arco-design/web-react@latest/dist/arco.min.js',
26
+ // ],
27
+
28
+ // /**
29
+ // * @name 样式加载配置
30
+ // * @description 开发环境独立运行时加载 Arco Design CSS
31
+ // */
32
+ // links: [
33
+ // {
34
+ // rel: 'stylesheet',
35
+ // href: 'https://unpkg.com/@arco-design/web-react@latest/dist/css/arco.min.css',
36
+ // },
37
+ // ],
38
+
39
+ // /**
40
+ // * @name 外部依赖配置
41
+ // * @description 开发环境也需要 externals,配合 CDN 使用
42
+ // */
43
+ // externals: {
44
+ // react: 'window.React',
45
+ // 'react-dom': 'window.ReactDOM',
46
+ // '@arco-design/web-react': 'window.arco',
47
+ // },
48
+ };
49
+
50
+ export default defineConfig(config);
@@ -0,0 +1,41 @@
1
+ // https://umijs.org/config/
2
+
3
+ import { defineConfig } from '@umijs/max';
4
+ const { CDN_PUBLIC_PATH } = process.env;
5
+
6
+ const PUBLIC_PATH: string = CDN_PUBLIC_PATH
7
+ ? `${CDN_PUBLIC_PATH.replace(/\/?$/, '/') }homepage/`
8
+ : '/homepage/';
9
+
10
+ const config: ReturnType<typeof defineConfig> = {
11
+ // 生产环境:将所有代码打包到一个文件
12
+ extraBabelPlugins: ['babel-plugin-dynamic-import-node'],
13
+
14
+ // 禁用代码分割,只输出一个 JS 和一个 CSS
15
+ chainWebpack(memo) {
16
+ // 禁用 splitChunks
17
+ memo.optimization.splitChunks(false);
18
+ // 禁用 runtimeChunk
19
+ memo.optimization.runtimeChunk(false);
20
+ return memo;
21
+ },
22
+ publicPath: PUBLIC_PATH,
23
+
24
+
25
+ /**
26
+ * @name 外部依赖配置
27
+ * @description 将大型公共库排除打包,运行时从主应用获取
28
+ * @doc https://umijs.org/docs/api/config#externals
29
+ *
30
+ * 作为 qiankun 子应用时,这些库由主应用提供:
31
+ * - react / react-dom: 主应用已加载,避免多实例问题
32
+ * - @arco-design/web-react: 主应用已加载,复用组件和样式
33
+ */
34
+ externals: {
35
+ react: 'window.React',
36
+ 'react-dom': 'window.ReactDOM',
37
+ '@arco-design/web-react': 'window.arco',
38
+ },
39
+ };
40
+
41
+ export default defineConfig(config);
@@ -0,0 +1,8 @@
1
+ // https://umijs.org/config/
2
+
3
+ import { defineConfig } from '@umijs/max';
4
+
5
+ const config: ReturnType<typeof defineConfig> = {
6
+ };
7
+
8
+ export default defineConfig(config);
@@ -0,0 +1,102 @@
1
+ // https://umijs.org/config/
2
+
3
+ import { defineConfig } from '@umijs/max';
4
+ import routes from './routes';
5
+
6
+ /**
7
+ * @name 使用公共路径
8
+ * @description 部署时的路径
9
+ */
10
+ const PUBLIC_PATH = '/dist/<%= appName %>/';
11
+
12
+ const config: ReturnType<typeof defineConfig> = {
13
+ /**
14
+ * @name 挂载元素 ID
15
+ * @description React 应用挂载的 DOM 元素 id
16
+ */
17
+ mountElementId: '<%= appName %>-root',
18
+
19
+ /**
20
+ * @name 基础路径
21
+ * @description 子应用的路由前缀
22
+ */
23
+ base: '/',
24
+
25
+ /**
26
+ * @name 开启 hash 模式
27
+ * @description 让 build 之后的产物包含 hash 后缀
28
+ */
29
+ hash: false,
30
+
31
+ publicPath: PUBLIC_PATH,
32
+
33
+ /**
34
+ * @name 路由配置
35
+ */
36
+ routes,
37
+
38
+ /**
39
+ * @name moment 的国际化配置
40
+ */
41
+ ignoreMomentLocale: true,
42
+
43
+ /**
44
+ * @name 快速热更新配置
45
+ */
46
+ fastRefresh: true,
47
+
48
+ //============== 以下都是 max 的插件配置 ===============
49
+
50
+ /**
51
+ * @name 网络请求配置
52
+ * @doc https://umijs.org/docs/max/request
53
+ */
54
+ request: {},
55
+
56
+ /**
57
+ * @name 数据流插件
58
+ * @doc https://umijs.org/docs/max/data-flow
59
+ */
60
+ model: {},
61
+
62
+ /**
63
+ * @name 全局初始状态
64
+ */
65
+ initialState: {},
66
+
67
+ /**
68
+ * @name layout 插件
69
+ * @description 禁用内置 layout,子应用使用自定义布局
70
+ */
71
+ layout: false,
72
+
73
+ /**
74
+ * @name 其他配置
75
+ */
76
+ esbuildMinifyIIFE: true,
77
+
78
+ define: {
79
+ 'process.env.NODE_ENV': process.env.NODE_ENV,
80
+ },
81
+
82
+ /**
83
+ * @name qiankun 微前端配置
84
+ * @description 作为子应用
85
+ * @doc https://umijs.org/docs/max/micro-frontend
86
+ */
87
+ qiankun: {
88
+ slave: {},
89
+ },
90
+
91
+ /**
92
+ * @name 代码拆分配置
93
+ * @description 确保动态 import 的模块打包为独立 chunk
94
+ * @doc https://umijs.org/docs/api/config#codeSplitting
95
+ */
96
+ codeSplitting: {
97
+ jsStrategy: 'granularChunks',
98
+ },
99
+ };
100
+
101
+ export default defineConfig(config);
102
+
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @name 路由配置
3
+ * @description homepage 子应用的路由配置
4
+ */
5
+ export default [
6
+ { path: '/<%= appName %>', component: '@/pages/index' },
7
+ ];
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @name Mock API
3
+ * @description homepage 子应用的 Mock 数据
4
+ * @doc https://umijs.org/docs/guides/mock
5
+ */
6
+
7
+ export default {
8
+ // 获取用户信息
9
+ 'GET /api/user/info': {
10
+ success: true,
11
+ data: {
12
+ id: 1001,
13
+ name: '张三',
14
+ email: 'zhangsan@example.com',
15
+ avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=homepage',
16
+ role: 'admin',
17
+ department: '技术部',
18
+ },
19
+ },
20
+
21
+ // 获取统计数据
22
+ 'GET /api/dashboard/stats': {
23
+ success: true,
24
+ data: {
25
+ totalUsers: 12580,
26
+ activeUsers: 3420,
27
+ pendingTasks: 156,
28
+ completedTasks: 8934,
29
+ lastUpdated: new Date().toISOString(),
30
+ },
31
+ },
32
+
33
+ // 获取列表数据
34
+ 'GET /api/items': {
35
+ success: true,
36
+ data: {
37
+ list: [
38
+ { id: 1, title: '待审核内容 A', status: 'pending', createdAt: '2025-12-27 10:00:00' },
39
+ { id: 2, title: '待审核内容 B', status: 'pending', createdAt: '2025-12-27 09:30:00' },
40
+ { id: 3, title: '已通过内容 C', status: 'approved', createdAt: '2025-12-26 15:00:00' },
41
+ { id: 4, title: '已拒绝内容 D', status: 'rejected', createdAt: '2025-12-26 14:00:00' },
42
+ ],
43
+ total: 4,
44
+ page: 1,
45
+ pageSize: 10,
46
+ },
47
+ },
48
+
49
+ // POST 请求示例
50
+ 'POST /api/items/approve': (req: any, res: any) => {
51
+ const { id } = req.body || {};
52
+ res.json({
53
+ success: true,
54
+ message: `Item ${id} approved successfully`,
55
+ data: { id, status: 'approved' },
56
+ });
57
+ },
58
+ };
59
+
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "<%= appName %>",
3
+ "version": "0.0.1",
4
+ "private": true,
5
+ "author": "Easton <easton@micous.com>",
6
+ "scripts": {
7
+ "dev": "max dev",
8
+ "build": "npm run build:production",
9
+ "build:development": "cross-env UMI_ENV=dev max build",
10
+ "build:production": "cross-env UMI_ENV=prod max build",
11
+ "build:testing": "cross-env UMI_ENV=testing max build",
12
+ "postinstall": "max setup",
13
+ "setup": "max setup",
14
+ "start": "npm run dev"
15
+ },
16
+ "dependencies": {
17
+ "@audit-center/shared-styles": "workspace:*",
18
+ "@umijs/max": "^4.4.8",
19
+ "babel-plugin-dynamic-import-node": "^2.3.3",
20
+ "cross-env": "^10.1.0",
21
+ "react": "^18.2.0",
22
+ "react-dom": "^18.2.0"
23
+ },
24
+ "devDependencies": {
25
+ "@arco-design/web-react": "^2.66.6",
26
+ "@types/react": "^18.0.33",
27
+ "@types/react-dom": "^18.0.11",
28
+ "typescript": "^5.0.3"
29
+ }
30
+ }
@@ -0,0 +1,80 @@
1
+ /**
2
+ * @name 应用入口配置
3
+ * @description homepage 子应用的运行时配置
4
+ * @doc https://umijs.org/docs/max/micro-frontend#子应用配置
5
+ *
6
+ * 注意:app.tsx 只能导出 Umi 规定的 API(qiankun、getInitialState 等)
7
+ * 自定义函数请放在 @/common/mainApp.ts 中
8
+ */
9
+
10
+ import { appLogger } from './common/logger';
11
+ import { type IMicroAppProps, setMainAppProps } from './common/mainApp';
12
+
13
+ /**
14
+ * @name 独立运行时加载主题
15
+ * @description 仅在开发环境且非 qiankun 环境中加载主题样式
16
+ *
17
+ * 实现原理:
18
+ * - 生产构建时 process.env.NODE_ENV !== 'development',整个 if 块被 tree-shake
19
+ * - 开发环境独立运行时加载主题,支持本地预览
20
+ * - 作为微应用运行时(无论开发还是生产),使用主应用的主题
21
+ */
22
+ if (process.env.NODE_ENV === 'development') {
23
+ // 开发环境:运行时检测是否独立运行
24
+ if (typeof window !== 'undefined' && !window.__POWERED_BY_QIANKUN__) {
25
+ // 直接导入主题样式(开发环境下会被打包)
26
+ import('./styles/theme.less');
27
+ appLogger.log('Running standalone in dev mode, theme loaded');
28
+ }
29
+ }
30
+ // 生产环境:作为微应用时,主题由主应用注入,无需加载
31
+
32
+ /**
33
+ * @name qiankun 生命周期钩子
34
+ * @description 子应用生命周期配置,用于与主应用通信
35
+ */
36
+ export const qiankun = {
37
+ /**
38
+ * 在应用 bootstrap 时调用
39
+ */
40
+ async bootstrap(props: IMicroAppProps) {
41
+ appLogger.log('bootstrap', props);
42
+ },
43
+
44
+ /**
45
+ * 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
46
+ */
47
+ async mount(props: IMicroAppProps) {
48
+ appLogger.log('mount', props);
49
+ // 保存主应用传递的 props,包括 request 实例
50
+ setMainAppProps(props);
51
+ },
52
+
53
+ /**
54
+ * 应用每次切出/卸载会调用的方法,通常在这里我们会卸载微应用的应用实例
55
+ */
56
+ async unmount(props: IMicroAppProps) {
57
+ appLogger.log('unmount', props);
58
+ // 清理引用
59
+ setMainAppProps(null);
60
+ },
61
+
62
+ /**
63
+ * 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
64
+ */
65
+ async update(props: IMicroAppProps) {
66
+ appLogger.log('update', props);
67
+ // 更新 props
68
+ setMainAppProps(props);
69
+ },
70
+ };
71
+
72
+ /**
73
+ * @name 全局初始状态
74
+ * @description 可以从主应用获取共享的状态
75
+ */
76
+ export async function getInitialState() {
77
+ return {
78
+ name: '<%= appName %>',
79
+ };
80
+ }