generator-mico-cli 0.2.1 → 0.2.2-8.beta.1

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 (159) hide show
  1. package/README.md +199 -15
  2. package/bin/mico.js +232 -27
  3. package/generators/micro-react/index.js +200 -18
  4. package/generators/micro-react/meta.json +13 -0
  5. package/generators/micro-react/templates/.commitlintrc.js +1 -0
  6. package/generators/micro-react/templates/.cursor/rules/always-read-docs.mdc +14 -4
  7. package/generators/micro-react/templates/.cursor/rules/cicd-deploy.mdc +10 -8
  8. package/generators/micro-react/templates/.cursor/rules/coding-conventions.mdc +1 -1
  9. package/generators/micro-react/templates/.cursor/rules/development-guide.mdc +3 -4
  10. package/generators/micro-react/templates/.cursor/rules/layout-app.mdc +38 -31
  11. package/generators/micro-react/templates/.cursor/rules/project-overview.mdc +7 -4
  12. package/generators/micro-react/templates/.cursor/rules/theme-system.mdc +10 -12
  13. package/generators/micro-react/templates/.eslintrc.js +25 -1
  14. package/generators/micro-react/templates/AGENTS.md +5 -2
  15. package/generators/micro-react/templates/CICD/before_build.sh +76 -0
  16. package/generators/micro-react/templates/CICD/start_dev.sh +27 -3
  17. package/generators/micro-react/templates/CICD/start_prod.sh +26 -3
  18. package/generators/micro-react/templates/CICD/start_test.sh +28 -3
  19. package/generators/micro-react/templates/CICD/wangsu_fresh_dev.sh +4 -4
  20. package/generators/micro-react/templates/CICD/wangsu_fresh_prod.sh +4 -4
  21. package/generators/micro-react/templates/CICD/wangsu_fresh_test.sh +4 -4
  22. package/generators/micro-react/templates/CLAUDE.md +16 -9
  23. package/generators/micro-react/templates/README.md +42 -4
  24. package/generators/micro-react/templates/_gitignore +4 -0
  25. package/generators/micro-react/templates/_npmrc +4 -0
  26. package/generators/micro-react/templates/apps/layout/config/config.dev.ts +32 -16
  27. package/generators/micro-react/templates/apps/layout/config/config.prod.development.ts +24 -29
  28. package/generators/micro-react/templates/apps/layout/config/config.prod.testing.ts +25 -6
  29. package/generators/micro-react/templates/apps/layout/config/config.prod.ts +16 -7
  30. package/generators/micro-react/templates/apps/layout/config/config.ts +27 -4
  31. package/generators/micro-react/templates/apps/layout/config/routes.ts +5 -5
  32. package/generators/micro-react/templates/apps/layout/docs/arch-/346/227/245/345/277/227/344/270/216/345/270/270/351/207/217.md +2 -2
  33. package/generators/micro-react/templates/apps/layout/docs/common-intl.md +372 -0
  34. package/generators/micro-react/templates/apps/layout/docs/feat-/346/236/204/345/273/272define/344/270/216/345/205/215/350/256/244/350/257/201/345/210/235/345/247/213/346/200/201.md +44 -0
  35. package/generators/micro-react/templates/apps/layout/docs/feature-404/351/241/265/351/235/242.md +103 -0
  36. 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 +22 -26
  37. 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 +185 -28
  38. 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 +308 -63
  39. package/generators/micro-react/templates/apps/layout/docs/feature-/350/267/257/347/224/261/344/270/216/350/217/234/345/215/225/350/247/243/350/200/246.md +179 -0
  40. package/generators/micro-react/templates/apps/layout/docs/fix-SSO/346/227/240/351/231/220/351/207/215/345/256/232/345/220/221.md +88 -0
  41. package/generators/micro-react/templates/apps/layout/docs/utils-timezone.md +324 -0
  42. package/generators/micro-react/templates/apps/layout/mock/api.mock.ts +81 -61
  43. package/generators/micro-react/templates/apps/layout/mock/menus.ts +114 -4
  44. package/generators/micro-react/templates/apps/layout/mock/pages.ts +86 -0
  45. package/generators/micro-react/templates/apps/layout/package.json +7 -4
  46. package/generators/micro-react/templates/apps/layout/src/app.tsx +111 -76
  47. package/generators/micro-react/templates/apps/layout/src/common/auth/index.ts +3 -0
  48. package/generators/micro-react/templates/apps/layout/src/common/helpers.ts +177 -0
  49. package/generators/micro-react/templates/apps/layout/src/common/locale.ts +22 -17
  50. package/generators/micro-react/templates/apps/layout/src/common/menu/parser.ts +192 -42
  51. package/generators/micro-react/templates/apps/layout/src/common/menu/types.ts +69 -5
  52. package/generators/micro-react/templates/apps/layout/src/common/micro/index.ts +34 -0
  53. package/generators/micro-react/templates/apps/layout/src/common/micro-prefetch.ts +109 -0
  54. package/generators/micro-react/templates/apps/layout/src/common/portal-data.ts +45 -0
  55. package/generators/micro-react/templates/apps/layout/src/common/request/config.ts +72 -10
  56. package/generators/micro-react/templates/apps/layout/src/common/request/index.ts +2 -2
  57. package/generators/micro-react/templates/apps/layout/src/common/request/interceptors.ts +31 -3
  58. package/generators/micro-react/templates/apps/layout/src/common/request/sso.ts +29 -11
  59. package/generators/micro-react/templates/apps/layout/src/common/request/url-resolver.ts +1 -1
  60. package/generators/micro-react/templates/apps/layout/src/common/route-guard.ts +345 -0
  61. package/generators/micro-react/templates/apps/layout/src/common/theme.ts +2 -4
  62. package/generators/micro-react/templates/apps/layout/src/common/upload/oss.ts +3 -4
  63. package/generators/micro-react/templates/apps/layout/src/common/upload/types.ts +1 -1
  64. package/generators/micro-react/templates/apps/layout/src/common/uploadFiles.ts +1 -1
  65. package/generators/micro-react/templates/apps/layout/src/components/AppTabs/index.less +8 -3
  66. package/generators/micro-react/templates/apps/layout/src/components/AppTabs/index.tsx +25 -8
  67. package/generators/micro-react/templates/apps/layout/src/components/HeaderDropdown/index.tsx +20 -0
  68. package/generators/micro-react/templates/apps/layout/src/components/IconFont/index.tsx +5 -6
  69. package/generators/micro-react/templates/apps/layout/src/components/MicroAppLoader/index.less +21 -6
  70. package/generators/micro-react/templates/apps/layout/src/components/MicroAppLoader/index.tsx +83 -149
  71. package/generators/micro-react/templates/apps/layout/src/components/MicroAppLoader/micro-app-manager.ts +569 -0
  72. package/generators/micro-react/templates/apps/layout/src/components/RightContent/AvatarDropdown.tsx +383 -0
  73. package/generators/micro-react/templates/apps/layout/src/components/RightContent/avatar-dropdown.less +35 -0
  74. package/generators/micro-react/templates/apps/layout/src/components/RightContent/index.ts +2 -0
  75. package/generators/micro-react/templates/apps/layout/src/constants/index.ts +170 -6
  76. package/generators/micro-react/templates/apps/layout/src/global.less +18 -9
  77. package/generators/micro-react/templates/apps/layout/src/hooks/useMenu.ts +3 -2
  78. package/generators/micro-react/templates/apps/layout/src/hooks/useRoutePermissionRefresh.ts +72 -0
  79. package/generators/micro-react/templates/apps/layout/src/layouts/components/header/index.less +3 -1
  80. package/generators/micro-react/templates/apps/layout/src/layouts/components/header/index.tsx +10 -55
  81. package/generators/micro-react/templates/apps/layout/src/layouts/components/menu/index.less +34 -4
  82. package/generators/micro-react/templates/apps/layout/src/layouts/components/menu/index.tsx +24 -8
  83. package/generators/micro-react/templates/apps/layout/src/layouts/index.less +84 -13
  84. package/generators/micro-react/templates/apps/layout/src/layouts/index.tsx +156 -69
  85. package/generators/micro-react/templates/apps/layout/src/locales/en-US.ts +12 -0
  86. package/generators/micro-react/templates/apps/layout/src/locales/zh-CN.ts +12 -0
  87. package/generators/micro-react/templates/apps/layout/src/pages/403/index.tsx +8 -2
  88. package/generators/micro-react/templates/apps/layout/src/pages/404/index.tsx +78 -0
  89. package/generators/micro-react/templates/apps/layout/src/pages/Home/index.less +3 -0
  90. package/generators/micro-react/templates/apps/layout/src/pages/Home/index.tsx +7 -1
  91. package/generators/micro-react/templates/apps/layout/src/pages/User/Login/index.less +1 -1
  92. package/generators/micro-react/templates/apps/layout/src/pages/User/Login/index.tsx +3 -3
  93. package/generators/micro-react/templates/apps/layout/src/requestErrorConfig.ts +1 -1
  94. package/generators/micro-react/templates/apps/layout/src/services/config/index.ts +63 -0
  95. package/generators/micro-react/templates/apps/layout/src/services/config/type.ts +30 -0
  96. package/generators/micro-react/templates/apps/layout/src/services/user.ts +29 -2
  97. package/generators/micro-react/templates/apps/layout/tailwind.config.js +3 -0
  98. package/generators/micro-react/templates/deployDesc.md +3 -3
  99. package/generators/micro-react/templates/dev.preset.json +14 -0
  100. package/generators/micro-react/templates/docs/dev-preset.md +130 -0
  101. package/generators/micro-react/templates/package.json +21 -6
  102. package/generators/micro-react/templates/packages/common-intl/README.md +427 -0
  103. package/generators/micro-react/templates/packages/common-intl/package.json +34 -0
  104. package/generators/micro-react/templates/packages/common-intl/src/index.ts +7 -0
  105. package/generators/micro-react/templates/packages/common-intl/src/indexedDBUtils.ts +51 -0
  106. package/generators/micro-react/templates/packages/common-intl/src/intl.ts +50 -0
  107. package/generators/micro-react/templates/packages/common-intl/src/utils.ts +482 -0
  108. package/generators/micro-react/templates/packages/common-intl/tsconfig.json +22 -0
  109. package/generators/micro-react/templates/packages/common-intl/vite.config.ts +25 -0
  110. package/generators/micro-react/templates/scripts/apply-sentry-plugin.ts +45 -0
  111. package/generators/micro-react/templates/scripts/collect-dist.js +10 -0
  112. package/generators/micro-react/templates/scripts/dev-preset.js +265 -0
  113. package/generators/micro-react/templates/scripts/dev-preset.schema.json +39 -0
  114. package/generators/micro-react/templates/turbo.json +4 -1
  115. package/generators/subapp-react/index.js +326 -40
  116. package/generators/subapp-react/meta.json +10 -0
  117. package/generators/subapp-react/templates/homepage/.env +2 -1
  118. package/generators/subapp-react/templates/homepage/README.md +3 -3
  119. package/generators/subapp-react/templates/homepage/config/config.dev.ts +14 -7
  120. package/generators/subapp-react/templates/homepage/config/config.prod.development.ts +16 -5
  121. package/generators/subapp-react/templates/homepage/config/config.prod.testing.ts +16 -5
  122. package/generators/subapp-react/templates/homepage/config/config.prod.ts +14 -5
  123. package/generators/subapp-react/templates/homepage/config/config.ts +21 -0
  124. package/generators/subapp-react/templates/homepage/config/routes.ts +2 -2
  125. package/generators/subapp-react/templates/homepage/mock/api.mock.ts +2 -2
  126. package/generators/subapp-react/templates/homepage/package.json +7 -4
  127. package/generators/subapp-react/templates/homepage/src/app.tsx +18 -27
  128. package/generators/subapp-react/templates/homepage/src/common/request.ts +29 -2
  129. package/generators/subapp-react/templates/homepage/src/global.less +6 -5
  130. package/generators/subapp-react/templates/homepage/src/pages/index.less +3 -3
  131. package/generators/subapp-react/templates/homepage/src/pages/index.tsx +99 -60
  132. package/generators/subapp-react/templates/homepage/src/styles/theme.less +1 -1
  133. package/generators/subapp-umd/ignore-list.json +5 -0
  134. package/generators/subapp-umd/index.js +309 -0
  135. package/generators/subapp-umd/meta.json +11 -0
  136. package/generators/subapp-umd/templates/README.md +94 -0
  137. package/generators/subapp-umd/templates/package.json +35 -0
  138. package/generators/subapp-umd/templates/public/index.html +34 -0
  139. package/generators/subapp-umd/templates/src/App.less +15 -0
  140. package/generators/subapp-umd/templates/src/App.tsx +13 -0
  141. package/generators/subapp-umd/templates/src/index.ts +2 -0
  142. package/generators/subapp-umd/templates/tsconfig.json +27 -0
  143. package/generators/subapp-umd/templates/webpack.config.js +70 -0
  144. package/lib/utils.js +332 -2
  145. package/package.json +15 -2
  146. package/generators/micro-react/templates/apps/layout/mock/menus.json +0 -100
  147. package/generators/micro-react/templates/apps/layout/src/common/constants.ts +0 -38
  148. package/generators/micro-react/templates/apps/layout/src/components/MicroAppLoader/container-manager.ts +0 -202
  149. package/generators/micro-react/templates/packages/shared-styles/README.md +0 -124
  150. package/generators/micro-react/templates/packages/shared-styles/arco-design-mobile-override.less +0 -91
  151. package/generators/micro-react/templates/packages/shared-styles/arco-override.less +0 -119
  152. package/generators/micro-react/templates/packages/shared-styles/index.d.ts +0 -44
  153. package/generators/micro-react/templates/packages/shared-styles/index.less +0 -13
  154. package/generators/micro-react/templates/packages/shared-styles/package.json +0 -30
  155. package/generators/micro-react/templates/packages/shared-styles/theme-inject.less +0 -10
  156. package/generators/micro-react/templates/packages/shared-styles/themes/dark/custom-var.less +0 -290
  157. package/generators/micro-react/templates/packages/shared-styles/themes/normal/custom-var.less +0 -269
  158. package/generators/micro-react/templates/packages/shared-styles/variables-only.less +0 -433
  159. package/generators/micro-react/templates/packages/shared-styles/variables.less +0 -452
@@ -1,13 +1,19 @@
1
1
  // https://umijs.org/config/
2
2
 
3
3
  import { defineConfig } from '@umijs/max';
4
+ import { applySentryPlugin } from '../../../scripts/apply-sentry-plugin';
4
5
  const { CDN_PUBLIC_PATH } = process.env;
5
6
 
6
7
  const PUBLIC_PATH: string = CDN_PUBLIC_PATH
7
- ? `${CDN_PUBLIC_PATH.replace(/\/?$/, '/') }<%= appName %>/`
8
- : '/<%= appName %>/';
8
+ ? `${CDN_PUBLIC_PATH.replace(/\/?$/, '/')}<%= appName %>/`
9
+ : '/<%= appName %>/';
9
10
 
10
11
  const config: ReturnType<typeof defineConfig> = {
12
+ /**
13
+ * 启用 Source Map(用于 Sentry 错误追踪)
14
+ * hidden-source-map 会生成 .map 文件但不在 JS 中添加 sourcemap 注释
15
+ */
16
+ devtool: 'hidden-source-map',
11
17
  // 生产环境:将所有代码打包到一个文件
12
18
  extraBabelPlugins: ['babel-plugin-dynamic-import-node'],
13
19
 
@@ -17,10 +23,12 @@ const config: ReturnType<typeof defineConfig> = {
17
23
  memo.optimization.splitChunks(false);
18
24
  // 禁用 runtimeChunk
19
25
  memo.optimization.runtimeChunk(false);
26
+ applySentryPlugin({ memo, appName: '<%= appName %>' });
27
+ memo.plugins.delete('runtimePublicPath');
20
28
  return memo;
21
29
  },
22
30
  publicPath: PUBLIC_PATH,
23
-
31
+ cssPublicPath: PUBLIC_PATH,
24
32
 
25
33
  /**
26
34
  * @name 外部依赖配置
@@ -29,12 +37,13 @@ const config: ReturnType<typeof defineConfig> = {
29
37
  *
30
38
  * 作为 qiankun 子应用时,这些库由主应用提供:
31
39
  * - react / react-dom: 主应用已加载,避免多实例问题
32
- * - @arco-design/web-react: 主应用已加载,复用组件和样式
40
+ * - @mico-platform/ui: 主应用已加载,复用组件和样式
33
41
  */
34
42
  externals: {
35
43
  react: 'React',
36
44
  'react-dom': 'ReactDOM',
37
- '@arco-design/web-react': 'arco',
45
+ '@mico-platform/ui': 'micoUI',
46
+ '@common-web/sentry': 'CommonWebSentry',
38
47
  },
39
48
  };
40
49
 
@@ -102,6 +102,27 @@ const config: ReturnType<typeof defineConfig> = {
102
102
  codeSplitting: {
103
103
  jsStrategy: 'granularChunks',
104
104
  },
105
+
106
+ /**
107
+ * @name 额外 Babel Presets
108
+ * @description 使用 @mico-platform/ui 的 babel preset,实现组件与图标的按需加载
109
+ */
110
+ extraBabelPresets: ['@mico-platform/ui/babel-preset'],
111
+
112
+ /**
113
+ * @name MFSU 配置
114
+ * @description
115
+ * - exclude: theme 子路径解析;ui 尽量与主应用一起编译
116
+ * - shared: React 单例,确保 MFSU 预打包里的组件(如 UI 库)与应用共用同一份 React,否则 useContext 报 null
117
+ * @doc https://umijs.org/docs/guides/mfsu
118
+ */
119
+ mfsu: {
120
+ exclude: ['@mico-platform/theme', '@mico-platform/ui'],
121
+ shared: {
122
+ react: { singleton: true },
123
+ 'react-dom': { singleton: true },
124
+ },
125
+ },
105
126
  };
106
127
 
107
128
  export default defineConfig(config);
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @name 路由配置
3
- * @description homepage 子应用的路由配置
3
+ * @description <%= appName %> 子应用的路由配置
4
4
  */
5
5
  export default [
6
- { path: '/<%= appName %>', component: '@/pages/index' },
6
+ { path: '/', component: '@/pages/index' },
7
7
  ];
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @name Mock API
3
- * @description homepage 子应用的 Mock 数据
3
+ * @description <%= appName %> 子应用的 Mock 数据
4
4
  * @doc https://umijs.org/docs/guides/mock
5
5
  */
6
6
 
@@ -12,7 +12,7 @@ export default {
12
12
  // id: 1001,
13
13
  // name: '张三',
14
14
  // email: 'zhangsan@example.com',
15
- // avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=homepage',
15
+ // avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=<%= appName %>',
16
16
  // role: 'admin',
17
17
  // department: '技术部',
18
18
  // },
@@ -4,6 +4,7 @@
4
4
  "private": true,
5
5
  "author": "Easton <easton@micous.com>",
6
6
  "scripts": {
7
+ "check-types": "tsc --noEmit",
7
8
  "dev": "max dev",
8
9
  "build": "npm run build:production",
9
10
  "build:development": "cross-env UMI_ENV=development max build",
@@ -14,17 +15,19 @@
14
15
  "start": "npm run dev"
15
16
  },
16
17
  "dependencies": {
17
- "<%= packageScope %>/shared-styles": "workspace:*",
18
+ "@mico-platform/ui": "<%= micoUiVersion %>",
19
+ "@mico-platform/theme": "<%= themeVersion %>",
18
20
  "@umijs/max": "^4.4.8",
19
- "babel-plugin-dynamic-import-node": "^2.3.3",
20
- "cross-env": "^10.1.0",
21
21
  "react": "^18.2.0",
22
22
  "react-dom": "^18.2.0"
23
23
  },
24
24
  "devDependencies": {
25
- "@arco-design/web-react": "^2.66.6",
25
+ "@mico-platform/ui": "<%= micoUiVersion %>",
26
26
  "@types/react": "^18.0.33",
27
27
  "@types/react-dom": "^18.0.11",
28
+ "babel-plugin-dynamic-import-node": "^2.3.3",
29
+ "babel-plugin-import": "^1.13.8",
30
+ "cross-env": "^10.1.0",
28
31
  "typescript": "^5.0.3"
29
32
  }
30
33
  }
@@ -1,34 +1,22 @@
1
1
  /**
2
2
  * @name 应用入口配置
3
- * @description homepage 子应用的运行时配置
3
+ * @description <%= appName %> 子应用的运行时配置
4
4
  * @doc https://umijs.org/docs/max/micro-frontend#子应用配置
5
5
  *
6
6
  * 注意:app.tsx 只能导出 Umi 规定的 API(qiankun、getInitialState 等)
7
7
  * 自定义函数请放在 @/common/mainApp.ts 中
8
8
  */
9
9
 
10
+ import React from 'react';
10
11
  import { history } from '@umijs/max';
12
+ import { SentryErrorBoundary } from '@common-web/sentry';
11
13
  import { appLogger } from './common/logger';
12
14
  import { type IMicroAppProps, setMainAppProps } from './common/mainApp';
13
15
 
14
- /**
15
- * @name 独立运行时加载主题
16
- * @description 仅在开发环境且非 qiankun 环境中加载主题样式
17
- *
18
- * 实现原理:
19
- * - 生产构建时 process.env.NODE_ENV !== 'development',整个 if 块被 tree-shake
20
- * - 开发环境独立运行时加载主题,支持本地预览
21
- * - 作为微应用运行时(无论开发还是生产),使用主应用的主题
22
- */
23
- if (process.env.NODE_ENV === 'development') {
24
- // 开发环境:运行时检测是否独立运行
25
- if (typeof window !== 'undefined' && !window.__POWERED_BY_QIANKUN__) {
26
- // 直接导入主题样式(开发环境下会被打包)
27
- import('./styles/theme.less');
28
- appLogger.log('Running standalone in dev mode, theme loaded');
29
- }
16
+ /** 与 layout parser.findRouteByPath 一致:根路径 "/" 保持不变 */
17
+ function stripTrailingSlash(path: string): string {
18
+ return path.length > 1 && path.endsWith('/') ? path.slice(0, -1) : path;
30
19
  }
31
- // 生产环境:作为微应用时,主题由主应用注入,无需加载
32
20
 
33
21
  /**
34
22
  * @name 路由同步工具
@@ -37,12 +25,12 @@ if (process.env.NODE_ENV === 'development') {
37
25
  function syncRoute(routePath: string, logPrefix = 'route sync') {
38
26
  if (!history) return;
39
27
 
40
- const currentPath = history.location.pathname;
28
+ const currentPath = stripTrailingSlash(history.location.pathname);
41
29
  const isWildcard = routePath.endsWith('/*');
42
- // 通配符模式取基础路径,否则使用原路径
43
- const targetPath = isWildcard ? routePath.slice(0, -2) : routePath;
30
+ const targetPath = stripTrailingSlash(
31
+ isWildcard ? routePath.slice(0, -2) : routePath,
32
+ );
44
33
 
45
- // 判断当前路径是否已匹配目标
46
34
  const isMatched = isWildcard
47
35
  ? currentPath === targetPath || currentPath.startsWith(`${targetPath}/`)
48
36
  : currentPath === targetPath;
@@ -73,11 +61,10 @@ export const qiankun = {
73
61
  // 保存主应用传递的 props,包括 request 实例
74
62
  setMainAppProps(props);
75
63
 
76
- // 初始路由同步:延迟到下一帧确保 React 组件已初始化
77
- if (props.routePath) {
78
- const routePath = props.routePath;
79
- requestAnimationFrame(() => syncRoute(routePath, 'initial route sync'));
80
- }
64
+ // 注意:不在 mount 中调用 syncRoute
65
+ // 原因:当子应用从缓存复用时,mount 时的 props 可能是旧的(包含过期的 routePath
66
+ // 主应用的 MicroAppManager 会在 mount 完成后立即调用 update() 传递正确的 props
67
+ // 路由同步完全由 update 生命周期处理,避免 mount 中的旧 routePath 覆盖正确的路由
81
68
  },
82
69
 
83
70
  /**
@@ -115,3 +102,7 @@ export async function getInitialState() {
115
102
  name: '<%= appName %>',
116
103
  };
117
104
  }
105
+
106
+ export function rootContainer(container: React.ReactNode) {
107
+ return <SentryErrorBoundary>{container}</SentryErrorBoundary>;
108
+ }
@@ -26,12 +26,12 @@ export async function request<T = any>(
26
26
 
27
27
  if (mainAppRequest) {
28
28
  // 微前端模式:使用主应用的 request
29
- console.log('[homepage] Using main app request:', url);
29
+ console.log('[<%= appName %>] Using main app request:', url);
30
30
  return mainAppRequest<T>(url, options);
31
31
  }
32
32
 
33
33
  // 独立运行模式:使用 umi request
34
- console.log('[homepage] Using umi request:', url);
34
+ console.log('[<%= appName %>] Using umi request:', url);
35
35
  // umi request 默认返回 data,skipErrorHandler 可选
36
36
  return umiRequest<T>(url, {
37
37
  skipErrorHandler: true,
@@ -46,4 +46,31 @@ export function getRequestSource(): 'main-app' | 'umi' {
46
46
  return getMainAppRequest() ? 'main-app' : 'umi';
47
47
  }
48
48
 
49
+ /**
50
+ * 从错误对象中提取错误消息
51
+ * 优先使用后端返回的 msg,否则使用默认消息
52
+ */
53
+ export function getErrorMessage(error: unknown, defaultMsg: string): string {
54
+ if (error && typeof error === 'object') {
55
+ // 尝试从 error.data.msg 获取(umi-request 格式)
56
+ const err = error as Record<string, any>;
57
+ if (err.data?.msg) {
58
+ return err.data.msg;
59
+ }
60
+ // 尝试从 error.response.data.msg 获取(axios 格式)
61
+ if (err.response?.data?.msg) {
62
+ return err.response.data.msg;
63
+ }
64
+ // 尝试从 error.msg 获取
65
+ if (err.msg) {
66
+ return err.msg;
67
+ }
68
+ // 尝试从 error.message 获取
69
+ if (err.message) {
70
+ return err.message;
71
+ }
72
+ }
73
+ return defaultMsg;
74
+ }
75
+
49
76
 
@@ -3,10 +3,10 @@
3
3
  * @description homepage 子应用的全局样式
4
4
  */
5
5
 
6
- // 仅导入 Less 变量(不包含 CSS 变量定义,避免重复打包)
7
- // CSS 变量由主应用(layout)注入到 body 上
8
- // Less 变量通过 var(--xxx) 引用 CSS 变量,自动适配主题
9
- @import '<%= packageScope %>/shared-styles/variables-only';
6
+ // 导入 @mico-platform/theme 主题入口(包含 CSS 变量 + Less 变量)
7
+ // 注意:作为微前端子应用运行时,主应用会先加载这些样式
8
+ // 独立运行时,需要自己加载完整样式(包括 UI 组件覆盖)
9
+ @import '@mico-platform/theme';
10
10
 
11
11
  * {
12
12
  box-sizing: border-box;
@@ -20,7 +20,8 @@ body {
20
20
  'Noto Sans', sans-serif;
21
21
  }
22
22
 
23
- #homepage-root {
23
+ #<%= appName %>-root {
24
24
  width: 100%;
25
25
  height: 100%;
26
+ background-color: var(--color-fill-1);
26
27
  }
@@ -3,10 +3,10 @@
3
3
  * @description 使用主题色变量的示例
4
4
  */
5
5
 
6
- // 导入共享样式变量
7
- @import '<%= packageScope %>/shared-styles/variables-only';
6
+ // 导入主题变量(仅 Less 变量,子应用用)
7
+ @import '@mico-platform/theme/variables';
8
8
 
9
- .homepage {
9
+ .<%= appName %> {
10
10
  padding: @spacing-lg;
11
11
  min-height: 100vh;
12
12
  // 使用主题色变量 - 背景色会随主题切换自动变化
@@ -12,8 +12,8 @@ import {
12
12
  Table,
13
13
  Tag,
14
14
  Typography,
15
- } from '@arco-design/web-react';
16
- import { IconMoon, IconRefresh, IconSun } from '@arco-design/web-react/icon';
15
+ } from '@mico-platform/ui';
16
+ import { IconMoon, IconRefresh, IconSun } from '@mico-platform/ui/icon';
17
17
  import { useState } from 'react';
18
18
  import './index.less';
19
19
 
@@ -45,12 +45,12 @@ interface IListItem {
45
45
  }
46
46
 
47
47
  /**
48
- * 主题色变量 & Arco Design 组件使用示例
48
+ * 主题色变量 & @mico-platform/ui 组件使用示例
49
49
  *
50
- * 子应用使用主题色变量和 Arco Design 的方式:
51
- * 1. 在 config.ts 中配置 externals,将 react/react-dom/@arco-design/web-react 排除打包
52
- * 2. 运行时从主应用的 window.React / window.arco 获取
53
- * 3. 在 global.less 中导入 @import '<%= packageScope %>/shared-styles/variables-only';
50
+ * 子应用使用主题色变量和 UI 组件的方式:
51
+ * 1. 在 config 中配置 externals,将 react/react-dom/@mico-platform/ui 排除打包
52
+ * 2. 运行时从主应用的 window.React / window.micoUI 获取
53
+ * 3. 在 global.less 中导入 @import '@mico-platform/theme';在 Less 中用 @import '@mico-platform/theme/variables'
54
54
  * 4. Less 变量自动适配主应用的主题切换
55
55
  */
56
56
  export default function HomePage() {
@@ -63,7 +63,9 @@ export default function HomePage() {
63
63
  const fetchUserInfo = async () => {
64
64
  setLoading(true);
65
65
  try {
66
- const res = await request<{ success: boolean; data: IUserInfo }>('/api/user/info');
66
+ const res = await request<{ success: boolean; data: IUserInfo }>(
67
+ '/api/user/info',
68
+ );
67
69
  if (res.success) {
68
70
  setUserInfo(res.data);
69
71
  Message.success('获取用户信息成功');
@@ -80,7 +82,9 @@ export default function HomePage() {
80
82
  const fetchStats = async () => {
81
83
  setLoading(true);
82
84
  try {
83
- const res = await request<{ success: boolean; data: IStatsData }>('/api/dashboard/stats');
85
+ const res = await request<{ success: boolean; data: IStatsData }>(
86
+ '/api/dashboard/stats',
87
+ );
84
88
  if (res.success) {
85
89
  setStats(res.data);
86
90
  Message.success('获取统计数据成功');
@@ -97,7 +101,10 @@ export default function HomePage() {
97
101
  const fetchList = async () => {
98
102
  setLoading(true);
99
103
  try {
100
- const res = await request<{ success: boolean; data: { list: IListItem[] } }>('/api/items');
104
+ const res = await request<{
105
+ success: boolean;
106
+ data: { list: IListItem[] };
107
+ }>('/api/items');
101
108
  if (res.success) {
102
109
  setListData(res.data.list);
103
110
  Message.success('获取列表数据成功');
@@ -124,14 +131,14 @@ export default function HomePage() {
124
131
  };
125
132
 
126
133
  const showMessage = () => {
127
- Message.success('Arco Design Message 组件正常工作!');
134
+ Message.success('@mico-platform/ui Message 组件正常工作!');
128
135
  };
129
136
 
130
137
  return (
131
- <div className="homepage">
138
+ <div className="<%= appName %>">
132
139
  <Title heading={2}>🎨 子应用主题 & 组件示例</Title>
133
140
  <Paragraph type="secondary">
134
- 子应用复用主应用的 React 和 Arco Design,无重复打包,主题自动同步
141
+ 子应用复用主应用的 React 和 @mico-platform/ui,无重复打包,主题自动同步
135
142
  </Paragraph>
136
143
 
137
144
  <Divider />
@@ -143,20 +150,30 @@ export default function HomePage() {
143
150
  style={{ marginBottom: 16 }}
144
151
  extra={
145
152
  <Tag color={getRequestSource() === 'main-app' ? 'green' : 'blue'}>
146
- {getRequestSource() === 'main-app' ? '使用主应用 Request' : '使用 Umi Request'}
153
+ {getRequestSource() === 'main-app'
154
+ ? '使用主应用 Request'
155
+ : '使用 Umi Request'}
147
156
  </Tag>
148
157
  }
149
158
  >
150
159
  <Paragraph>
151
- 子应用优先使用主应用传递的 <Text code>request</Text> 实例,独立运行时使用 Umi
152
- 内置的 request。两种模式都支持 Mock。
160
+ 子应用优先使用主应用传递的 <Text code>request</Text>{' '}
161
+ 实例,独立运行时使用 Umi 内置的 request。两种模式都支持 Mock。
153
162
  </Paragraph>
154
163
 
155
164
  <Space size="medium" style={{ marginTop: 16 }}>
156
- <Button type="primary" icon={<IconRefresh />} onClick={fetchUserInfo}>
165
+ <Button
166
+ type="primary"
167
+ icon={<IconRefresh />}
168
+ onClick={fetchUserInfo}
169
+ >
157
170
  获取用户信息
158
171
  </Button>
159
- <Button type="secondary" icon={<IconRefresh />} onClick={fetchStats}>
172
+ <Button
173
+ type="secondary"
174
+ icon={<IconRefresh />}
175
+ onClick={fetchStats}
176
+ >
160
177
  获取统计数据
161
178
  </Button>
162
179
  <Button type="outline" icon={<IconRefresh />} onClick={fetchList}>
@@ -175,7 +192,10 @@ export default function HomePage() {
175
192
  { label: 'ID', value: userInfo.id },
176
193
  { label: '姓名', value: userInfo.name },
177
194
  { label: '邮箱', value: userInfo.email },
178
- { label: '角色', value: <Tag color="arcoblue">{userInfo.role}</Tag> },
195
+ {
196
+ label: '角色',
197
+ value: <Tag color="arcoblue">{userInfo.role}</Tag>,
198
+ },
179
199
  { label: '部门', value: userInfo.department },
180
200
  ]}
181
201
  />
@@ -190,11 +210,26 @@ export default function HomePage() {
190
210
  <Descriptions
191
211
  column={2}
192
212
  data={[
193
- { label: '总用户数', value: stats.totalUsers.toLocaleString() },
194
- { label: '活跃用户', value: stats.activeUsers.toLocaleString() },
195
- { label: '待处理任务', value: <Tag color="orange">{stats.pendingTasks}</Tag> },
196
- { label: '已完成任务', value: <Tag color="green">{stats.completedTasks}</Tag> },
197
- { label: '更新时间', value: new Date(stats.lastUpdated).toLocaleString() },
213
+ {
214
+ label: '总用户数',
215
+ value: stats.totalUsers.toLocaleString(),
216
+ },
217
+ {
218
+ label: '活跃用户',
219
+ value: stats.activeUsers.toLocaleString(),
220
+ },
221
+ {
222
+ label: '待处理任务',
223
+ value: <Tag color="orange">{stats.pendingTasks}</Tag>,
224
+ },
225
+ {
226
+ label: '已完成任务',
227
+ value: <Tag color="green">{stats.completedTasks}</Tag>,
228
+ },
229
+ {
230
+ label: '更新时间',
231
+ value: new Date(stats.lastUpdated).toLocaleString(),
232
+ },
198
233
  ]}
199
234
  />
200
235
  </>
@@ -216,7 +251,9 @@ export default function HomePage() {
216
251
  dataIndex: 'status',
217
252
  width: 100,
218
253
  render: (status: keyof typeof statusColorMap) => (
219
- <Tag color={statusColorMap[status]}>{statusTextMap[status]}</Tag>
254
+ <Tag color={statusColorMap[status]}>
255
+ {statusTextMap[status]}
256
+ </Tag>
220
257
  ),
221
258
  },
222
259
  { title: '创建时间', dataIndex: 'createdAt', width: 180 },
@@ -228,11 +265,11 @@ export default function HomePage() {
228
265
  </Card>
229
266
  </Spin>
230
267
 
231
- {/* Arco Design 组件示例 */}
232
- <Card title="📦 Arco Design 组件" style={{ marginBottom: 16 }}>
268
+ {/* @mico-platform/ui 组件示例 */}
269
+ <Card title="📦 @mico-platform/ui 组件" style={{ marginBottom: 16 }}>
233
270
  <Paragraph>
234
- 子应用通过 <Text code>externals</Text> 配置复用主应用的 Arco Design,
235
- 避免重复打包(节省 ~800KB)。
271
+ 子应用通过 <Text code>externals</Text> 配置复用主应用的
272
+ @mico-platform/ui, 避免重复打包(节省 ~800KB)。
236
273
  </Paragraph>
237
274
 
238
275
  <Space size="medium" style={{ marginTop: 16 }}>
@@ -262,7 +299,9 @@ export default function HomePage() {
262
299
  checkedIcon={<IconMoon />}
263
300
  uncheckedIcon={<IconSun />}
264
301
  onChange={(checked: boolean) => {
265
- Message.info(`切换到 ${checked ? '暗色' : '亮色'} 模式(需在主应用操作)`);
302
+ Message.info(
303
+ `切换到 ${checked ? '暗色' : '亮色'} 模式(需在主应用操作)`,
304
+ );
266
305
  }}
267
306
  />
268
307
  <Text type="secondary">(实际切换请在主应用 Header 操作)</Text>
@@ -272,49 +311,49 @@ export default function HomePage() {
272
311
  {/* 自定义主题色示例 */}
273
312
  <Card title="🎨 自定义主题色变量" style={{ marginBottom: 16 }}>
274
313
  <Paragraph>
275
- 在 Less 中使用 <Text code><%= packageScope %>/shared-styles/variables-only</Text>{' '}
314
+ 在 Less 中使用 <Text code>@mico-platform/theme/variables</Text>{' '}
276
315
  导入主题变量,自动适配亮色/暗色主题。
277
316
  </Paragraph>
278
317
 
279
318
  <Title heading={6}>品牌色 & 功能色</Title>
280
- <div className="homepage-colors">
281
- <div className="homepage-color-item">
282
- <div className="homepage-color-box brand-1" />
283
- <span className="homepage-color-label">@Brand1-6</span>
319
+ <div className="<%= appName %>-colors">
320
+ <div className="<%= appName %>-color-item">
321
+ <div className="<%= appName %>-color-box brand-1" />
322
+ <span className="<%= appName %>-color-label">@Brand1-6</span>
284
323
  </div>
285
- <div className="homepage-color-item">
286
- <div className="homepage-color-box brand-2" />
287
- <span className="homepage-color-label">@Brand2-6</span>
324
+ <div className="<%= appName %>-color-item">
325
+ <div className="<%= appName %>-color-box brand-2" />
326
+ <span className="<%= appName %>-color-label">@Brand2-6</span>
288
327
  </div>
289
- <div className="homepage-color-item">
290
- <div className="homepage-color-box success" />
291
- <span className="homepage-color-label">@Success-6</span>
328
+ <div className="<%= appName %>-color-item">
329
+ <div className="<%= appName %>-color-box success" />
330
+ <span className="<%= appName %>-color-label">@Success-6</span>
292
331
  </div>
293
- <div className="homepage-color-item">
294
- <div className="homepage-color-box warning" />
295
- <span className="homepage-color-label">@Warning-6</span>
332
+ <div className="<%= appName %>-color-item">
333
+ <div className="<%= appName %>-color-box warning" />
334
+ <span className="<%= appName %>-color-label">@Warning-6</span>
296
335
  </div>
297
- <div className="homepage-color-item">
298
- <div className="homepage-color-box danger" />
299
- <span className="homepage-color-label">@Danger-6</span>
336
+ <div className="<%= appName %>-color-item">
337
+ <div className="<%= appName %>-color-box danger" />
338
+ <span className="<%= appName %>-color-label">@Danger-6</span>
300
339
  </div>
301
340
  </div>
302
341
 
303
342
  <Title heading={6} style={{ marginTop: 16 }}>
304
343
  中性色(随主题自动切换)
305
344
  </Title>
306
- <div className="homepage-colors">
307
- <div className="homepage-color-item">
308
- <div className="homepage-color-box fill-1" />
309
- <span className="homepage-color-label">@color-fill-1</span>
345
+ <div className="<%= appName %>-colors">
346
+ <div className="<%= appName %>-color-item">
347
+ <div className="<%= appName %>-color-box fill-1" />
348
+ <span className="<%= appName %>-color-label">@color-fill-1</span>
310
349
  </div>
311
- <div className="homepage-color-item">
312
- <div className="homepage-color-box fill-2" />
313
- <span className="homepage-color-label">@color-fill-2</span>
350
+ <div className="<%= appName %>-color-item">
351
+ <div className="<%= appName %>-color-box fill-2" />
352
+ <span className="<%= appName %>-color-label">@color-fill-2</span>
314
353
  </div>
315
- <div className="homepage-color-item">
316
- <div className="homepage-color-box fill-3" />
317
- <span className="homepage-color-label">@color-fill-3</span>
354
+ <div className="<%= appName %>-color-item">
355
+ <div className="<%= appName %>-color-box fill-3" />
356
+ <span className="<%= appName %>-color-label">@color-fill-3</span>
318
357
  </div>
319
358
  </div>
320
359
  </Card>
@@ -324,17 +363,17 @@ export default function HomePage() {
324
363
  <Alert
325
364
  type="info"
326
365
  title="依赖共享"
327
- content="通过 externals 配置,子应用复用主应用的 React 和 Arco Design,打包体积减少 ~1MB"
366
+ content="通过 externals 配置,子应用复用主应用的 React 和 @mico-platform/ui,打包体积减少 ~1MB"
328
367
  />
329
368
  <Alert
330
369
  type="success"
331
370
  title="主题同步"
332
- content="子应用的 Arco 组件和自定义样式自动跟随主应用主题切换"
371
+ content="子应用的 UI 组件和自定义样式自动跟随主应用主题切换"
333
372
  />
334
373
  <Alert
335
374
  type="warning"
336
375
  title="注意事项"
337
- content="使用 variables-only 导入,避免重复打包 CSS 变量定义"
376
+ content="使用 variables 导入,避免重复打包 CSS 变量定义"
338
377
  />
339
378
  </Space>
340
379
  </div>
@@ -2,5 +2,5 @@
2
2
  // 此文件仅在独立运行时被动态导入
3
3
  // 作为微前端子应用时不会被导入(使用主应用的主题)
4
4
 
5
- @import '<%= packageScope %>/shared-styles/theme-inject';
5
+ @import '@mico-platform/theme/theme-inject';
6
6
 
@@ -0,0 +1,5 @@
1
+ [
2
+ "node_modules",
3
+ "dist",
4
+ ".turbo"
5
+ ]