generator-mico-cli 0.1.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.
- package/README.md +84 -0
- package/bin/mico.js +316 -0
- package/generators/micro-react/ignore-list.json +8 -0
- package/generators/micro-react/index.js +158 -0
- package/generators/micro-react/templates/.commitlintrc.js +6 -0
- package/generators/micro-react/templates/.cursor/rules/always-read-docs.mdc +129 -0
- package/generators/micro-react/templates/.cursor/rules/cicd-deploy.mdc +143 -0
- package/generators/micro-react/templates/.cursor/rules/coding-conventions.mdc +206 -0
- package/generators/micro-react/templates/.cursor/rules/commit-conventions.mdc +111 -0
- package/generators/micro-react/templates/.cursor/rules/development-guide.mdc +295 -0
- package/generators/micro-react/templates/.cursor/rules/layout-app.mdc +275 -0
- package/generators/micro-react/templates/.cursor/rules/micro-frontend.mdc +196 -0
- package/generators/micro-react/templates/.cursor/rules/project-overview.mdc +128 -0
- package/generators/micro-react/templates/.cursor/rules/request-auth.mdc +220 -0
- package/generators/micro-react/templates/.cursor/rules/theme-system.mdc +206 -0
- package/generators/micro-react/templates/.editorconfig +16 -0
- package/generators/micro-react/templates/.env +3 -0
- package/generators/micro-react/templates/.eslintrc.js +30 -0
- package/generators/micro-react/templates/.husky/commit-msg +2 -0
- package/generators/micro-react/templates/.husky/pre-commit +2 -0
- package/generators/micro-react/templates/.lintstagedrc +5 -0
- package/generators/micro-react/templates/.stylelintrc.js +25 -0
- package/generators/micro-react/templates/AGENTS.md +39 -0
- package/generators/micro-react/templates/CICD/start_dev.sh +30 -0
- package/generators/micro-react/templates/CICD/start_local.sh +30 -0
- package/generators/micro-react/templates/CICD/start_prod.sh +30 -0
- package/generators/micro-react/templates/CICD/start_test.sh +30 -0
- package/generators/micro-react/templates/CICD/wangsu_fresh_dev.sh +19 -0
- package/generators/micro-react/templates/CICD/wangsu_fresh_prod.sh +19 -0
- package/generators/micro-react/templates/CICD/wangsu_fresh_test.sh +19 -0
- package/generators/micro-react/templates/CLAUDE.md +106 -0
- package/generators/micro-react/templates/README.md +84 -0
- package/generators/micro-react/templates/_gitignore +57 -0
- package/generators/micro-react/templates/_npmrc +2 -0
- package/generators/micro-react/templates/apps/layout/.env +4 -0
- package/generators/micro-react/templates/apps/layout/.eslintrc.js +10 -0
- package/generators/micro-react/templates/apps/layout/.lintstagedrc +17 -0
- package/generators/micro-react/templates/apps/layout/.prettierignore +3 -0
- package/generators/micro-react/templates/apps/layout/.prettierrc +8 -0
- package/generators/micro-react/templates/apps/layout/.stylelintrc.js +20 -0
- package/generators/micro-react/templates/apps/layout/README.md +37 -0
- package/generators/micro-react/templates/apps/layout/config/config.dev.ts +54 -0
- package/generators/micro-react/templates/apps/layout/config/config.prod.ts +37 -0
- package/generators/micro-react/templates/apps/layout/config/config.testing.ts +27 -0
- package/generators/micro-react/templates/apps/layout/config/config.ts +132 -0
- package/generators/micro-react/templates/apps/layout/config/routes.ts +13 -0
- package/generators/micro-react/templates/apps/layout/mock/api.mock.ts +78 -0
- package/generators/micro-react/templates/apps/layout/mock/menus.json +100 -0
- package/generators/micro-react/templates/apps/layout/mock/menus.ts +11 -0
- package/generators/micro-react/templates/apps/layout/mock/user.mock.ts +20 -0
- package/generators/micro-react/templates/apps/layout/package.json +45 -0
- package/generators/micro-react/templates/apps/layout/public/font/ar-SA.js +54 -0
- package/generators/micro-react/templates/apps/layout/public/font/default.js +54 -0
- package/generators/micro-react/templates/apps/layout/src/app.tsx +123 -0
- package/generators/micro-react/templates/apps/layout/src/assets/.gitkeep +0 -0
- package/generators/micro-react/templates/apps/layout/src/common/auth/cs-auth-manager.ts +220 -0
- package/generators/micro-react/templates/apps/layout/src/common/auth/index.ts +41 -0
- package/generators/micro-react/templates/apps/layout/src/common/auth/tool.ts +3 -0
- package/generators/micro-react/templates/apps/layout/src/common/auth/type.ts +6 -0
- package/generators/micro-react/templates/apps/layout/src/common/constants.ts +38 -0
- package/generators/micro-react/templates/apps/layout/src/common/env.ts +73 -0
- package/generators/micro-react/templates/apps/layout/src/common/helpers.ts +69 -0
- package/generators/micro-react/templates/apps/layout/src/common/locale.ts +123 -0
- package/generators/micro-react/templates/apps/layout/src/common/logger.ts +45 -0
- package/generators/micro-react/templates/apps/layout/src/common/menu/index.ts +2 -0
- package/generators/micro-react/templates/apps/layout/src/common/menu/parser.ts +143 -0
- package/generators/micro-react/templates/apps/layout/src/common/menu/types.ts +92 -0
- package/generators/micro-react/templates/apps/layout/src/common/request/config.ts +73 -0
- package/generators/micro-react/templates/apps/layout/src/common/request/index.ts +188 -0
- package/generators/micro-react/templates/apps/layout/src/common/request/interceptors.ts +186 -0
- package/generators/micro-react/templates/apps/layout/src/common/request/sso.ts +132 -0
- package/generators/micro-react/templates/apps/layout/src/common/request/token-refresh.ts +136 -0
- package/generators/micro-react/templates/apps/layout/src/common/request/types.ts +44 -0
- package/generators/micro-react/templates/apps/layout/src/common/request/url-resolver.ts +75 -0
- package/generators/micro-react/templates/apps/layout/src/common/theme.ts +107 -0
- package/generators/micro-react/templates/apps/layout/src/common/types.ts +7 -0
- package/generators/micro-react/templates/apps/layout/src/common/upload/index.ts +2 -0
- package/generators/micro-react/templates/apps/layout/src/common/upload/oss.ts +401 -0
- package/generators/micro-react/templates/apps/layout/src/common/upload/types.ts +47 -0
- package/generators/micro-react/templates/apps/layout/src/common/uploadFiles.ts +35 -0
- package/generators/micro-react/templates/apps/layout/src/components/IconFont/index.tsx +25 -0
- package/generators/micro-react/templates/apps/layout/src/components/MicroAppLoader/index.less +44 -0
- package/generators/micro-react/templates/apps/layout/src/components/MicroAppLoader/index.tsx +121 -0
- package/generators/micro-react/templates/apps/layout/src/constants/index.ts +15 -0
- package/generators/micro-react/templates/apps/layout/src/global.less +13 -0
- package/generators/micro-react/templates/apps/layout/src/hooks/index.ts +3 -0
- package/generators/micro-react/templates/apps/layout/src/hooks/useAuth.ts +75 -0
- package/generators/micro-react/templates/apps/layout/src/hooks/useMenu.ts +35 -0
- package/generators/micro-react/templates/apps/layout/src/hooks/useMenuState.ts +112 -0
- package/generators/micro-react/templates/apps/layout/src/hooks/useTheme.ts +124 -0
- package/generators/micro-react/templates/apps/layout/src/layouts/components/header/index.less +109 -0
- package/generators/micro-react/templates/apps/layout/src/layouts/components/header/index.tsx +97 -0
- package/generators/micro-react/templates/apps/layout/src/layouts/components/menu/index.less +164 -0
- package/generators/micro-react/templates/apps/layout/src/layouts/components/menu/index.tsx +165 -0
- package/generators/micro-react/templates/apps/layout/src/layouts/index.less +71 -0
- package/generators/micro-react/templates/apps/layout/src/layouts/index.tsx +91 -0
- package/generators/micro-react/templates/apps/layout/src/locales/en-US.ts +20 -0
- package/generators/micro-react/templates/apps/layout/src/locales/zh-CN.ts +19 -0
- package/generators/micro-react/templates/apps/layout/src/models/global.ts +13 -0
- package/generators/micro-react/templates/apps/layout/src/pages/Home/index.less +3 -0
- package/generators/micro-react/templates/apps/layout/src/pages/Home/index.tsx +7 -0
- package/generators/micro-react/templates/apps/layout/src/requestErrorConfig.ts +171 -0
- package/generators/micro-react/templates/apps/layout/src/services/auth.ts +37 -0
- package/generators/micro-react/templates/apps/layout/src/services/oss.ts +40 -0
- package/generators/micro-react/templates/apps/layout/src/styles/arco-override.less +78 -0
- package/generators/micro-react/templates/apps/layout/src/styles/themes/dark/custom-var.less +244 -0
- package/generators/micro-react/templates/apps/layout/src/styles/themes/normal/custom-var.less +195 -0
- package/generators/micro-react/templates/apps/layout/src/styles/variables.less +5 -0
- package/generators/micro-react/templates/apps/layout/src/utils/format.ts +4 -0
- package/generators/micro-react/templates/apps/layout/tailwind.config.js +7 -0
- package/generators/micro-react/templates/apps/layout/tailwind.css +3 -0
- package/generators/micro-react/templates/apps/layout/tsconfig.json +3 -0
- package/generators/micro-react/templates/apps/layout/typings.d.ts +1 -0
- package/generators/micro-react/templates/deployDesc.md +60 -0
- package/generators/micro-react/templates/docs/commit-message.md +98 -0
- package/generators/micro-react/templates/package.json +35 -0
- package/generators/micro-react/templates/packages/shared-styles/README.md +125 -0
- package/generators/micro-react/templates/packages/shared-styles/arco-override.less +78 -0
- package/generators/micro-react/templates/packages/shared-styles/index.less +14 -0
- package/generators/micro-react/templates/packages/shared-styles/package.json +27 -0
- package/generators/micro-react/templates/packages/shared-styles/theme-inject.less +10 -0
- package/generators/micro-react/templates/packages/shared-styles/themes/dark/custom-var.less +246 -0
- package/generators/micro-react/templates/packages/shared-styles/themes/normal/custom-var.less +195 -0
- package/generators/micro-react/templates/packages/shared-styles/variables-only.less +301 -0
- package/generators/micro-react/templates/packages/shared-styles/variables.less +363 -0
- package/generators/micro-react/templates/pnpm-workspace.yaml +9 -0
- package/generators/micro-react/templates/scripts/collect-dist.js +68 -0
- package/generators/micro-react/templates/scripts/create-umi-app.sh +61 -0
- package/generators/micro-react/templates/scripts/dev.js +133 -0
- package/generators/micro-react/templates/turbo.json +68 -0
- package/generators/subapp-react/ignore-list.json +7 -0
- package/generators/subapp-react/index.js +189 -0
- package/generators/subapp-react/templates/homepage/.env +4 -0
- package/generators/subapp-react/templates/homepage/README.md +116 -0
- package/generators/subapp-react/templates/homepage/_gitignore +9 -0
- package/generators/subapp-react/templates/homepage/config/config.dev.ts +59 -0
- package/generators/subapp-react/templates/homepage/config/config.prod.ts +41 -0
- package/generators/subapp-react/templates/homepage/config/config.testing.ts +40 -0
- package/generators/subapp-react/templates/homepage/config/config.ts +102 -0
- package/generators/subapp-react/templates/homepage/config/routes.ts +7 -0
- package/generators/subapp-react/templates/homepage/mock/api.mock.ts +59 -0
- package/generators/subapp-react/templates/homepage/package.json +30 -0
- package/generators/subapp-react/templates/homepage/src/app.tsx +80 -0
- package/generators/subapp-react/templates/homepage/src/assets/yay.jpg +0 -0
- package/generators/subapp-react/templates/homepage/src/common/logger.ts +42 -0
- package/generators/subapp-react/templates/homepage/src/common/mainApp.ts +53 -0
- package/generators/subapp-react/templates/homepage/src/common/request.ts +49 -0
- package/generators/subapp-react/templates/homepage/src/global.less +26 -0
- package/generators/subapp-react/templates/homepage/src/pages/index.less +139 -0
- package/generators/subapp-react/templates/homepage/src/pages/index.tsx +342 -0
- package/generators/subapp-react/templates/homepage/src/styles/theme.less +6 -0
- package/generators/subapp-react/templates/homepage/tsconfig.json +3 -0
- package/generators/subapp-react/templates/homepage/typings.d.ts +17 -0
- package/lib/utils.js +165 -0
- package/package.json +31 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 微前端架构指南 - qiankun 子应用加载与通信
|
|
3
|
+
globs: ["**/MicroAppLoader/**", "**/menu/**", "**/qiankun/**"]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 微前端架构
|
|
7
|
+
|
|
8
|
+
## 架构概览
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
12
|
+
│ Layout (主应用) │
|
|
13
|
+
│ ┌─────────────────────────────────────────────────────────┐│
|
|
14
|
+
│ │ Header ││
|
|
15
|
+
│ ├─────────┬───────────────────────────────────────────────┤│
|
|
16
|
+
│ │ │ ││
|
|
17
|
+
│ │ Menu │ ┌─────────────────────────────────────────┐ ││
|
|
18
|
+
│ │ │ │ MicroAppLoader / Outlet │ ││
|
|
19
|
+
│ │ │ │ (根据 loadType 选择渲染方式) │ ││
|
|
20
|
+
│ │ │ │ │ ││
|
|
21
|
+
│ │ │ │ loadType: 'microapp' → qiankun 加载 │ ││
|
|
22
|
+
│ │ │ │ loadType: 'internal' → React Router │ ││
|
|
23
|
+
│ │ │ └─────────────────────────────────────────┘ ││
|
|
24
|
+
│ └─────────┴───────────────────────────────────────────────┘│
|
|
25
|
+
└─────────────────────────────────────────────────────────────┘
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 核心文件
|
|
29
|
+
|
|
30
|
+
| 文件 | 说明 |
|
|
31
|
+
|------|------|
|
|
32
|
+
| `src/components/MicroAppLoader/index.tsx` | qiankun 微应用加载器 |
|
|
33
|
+
| `src/common/menu/parser.ts` | 菜单解析,包含加载类型判断 |
|
|
34
|
+
| `src/common/menu/types.ts` | 类型定义 |
|
|
35
|
+
| `src/layouts/index.tsx` | 主布局,集成微应用渲染 |
|
|
36
|
+
| `config/config.ts` | qiankun master 配置 |
|
|
37
|
+
|
|
38
|
+
## 加载类型判断
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
/**
|
|
42
|
+
* 判断页面的加载类型
|
|
43
|
+
* 有 htmlUrl 或 jsUrls 时使用 qiankun 微应用加载
|
|
44
|
+
*/
|
|
45
|
+
const getLoadType = (page: MenuItem['page']): 'internal' | 'microapp' => {
|
|
46
|
+
if (!page) return 'internal';
|
|
47
|
+
|
|
48
|
+
// 有 htmlUrl 或 jsUrls 使用 qiankun 微应用加载
|
|
49
|
+
if (page.htmlUrl || (page.jsUrls && page.jsUrls.length > 0)) {
|
|
50
|
+
return 'microapp';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return 'internal';
|
|
54
|
+
};
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## MicroAppLoader 组件
|
|
58
|
+
|
|
59
|
+
### Props 接口
|
|
60
|
+
```typescript
|
|
61
|
+
interface MicroAppLoaderProps {
|
|
62
|
+
/** 微应用入口 URL */
|
|
63
|
+
entry: string;
|
|
64
|
+
/** 微应用唯一标识(用于生成容器 ID) */
|
|
65
|
+
name: string;
|
|
66
|
+
/** 微应用显示名称(用于 loading 提示) */
|
|
67
|
+
displayName?: string;
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 使用示例
|
|
72
|
+
```tsx
|
|
73
|
+
<MicroAppLoader
|
|
74
|
+
entry="http://localhost:8001"
|
|
75
|
+
name="/homepage"
|
|
76
|
+
displayName="首页"
|
|
77
|
+
/>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## 传递给子应用的 Props
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
interface MicroAppProps {
|
|
84
|
+
/** 主应用标识 */
|
|
85
|
+
mainApp: '<%= projectName %>';
|
|
86
|
+
/** 共享的 request 实例 */
|
|
87
|
+
request: <T = any>(url: string, options?: any) => Promise<T>;
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
子应用可以使用主应用的 `request` 实例,确保认证 token 和拦截器一致。
|
|
92
|
+
|
|
93
|
+
## 菜单数据结构
|
|
94
|
+
|
|
95
|
+
### MenuItem
|
|
96
|
+
```typescript
|
|
97
|
+
interface MenuItem {
|
|
98
|
+
id: number;
|
|
99
|
+
name: string;
|
|
100
|
+
icon: string;
|
|
101
|
+
type: 'page' | 'folder' | 'link';
|
|
102
|
+
enabled: boolean;
|
|
103
|
+
sortOrder: number;
|
|
104
|
+
path?: string; // type === 'link' 时的外链地址
|
|
105
|
+
page?: PageConfig; // type === 'page' 时的页面配置
|
|
106
|
+
children?: MenuItem[];
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### PageConfig
|
|
111
|
+
```typescript
|
|
112
|
+
interface PageConfig {
|
|
113
|
+
id: number;
|
|
114
|
+
name: string;
|
|
115
|
+
route: string;
|
|
116
|
+
enabled: boolean;
|
|
117
|
+
htmlUrl: string | null; // 微应用 HTML 入口(优先使用)
|
|
118
|
+
jsUrls: string[]; // 微应用 JS 入口(备选)
|
|
119
|
+
cssUrls: string[]; // 微应用 CSS
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## 子应用接入指南
|
|
124
|
+
|
|
125
|
+
### 1. 导出 qiankun 生命周期
|
|
126
|
+
```typescript
|
|
127
|
+
// 子应用入口
|
|
128
|
+
let mainAppProps: MicroAppProps | null = null;
|
|
129
|
+
|
|
130
|
+
export async function bootstrap() {
|
|
131
|
+
console.log('micro app bootstrapped');
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export async function mount(props: MicroAppProps) {
|
|
135
|
+
mainAppProps = props;
|
|
136
|
+
// 渲染应用
|
|
137
|
+
ReactDOM.render(<App />, props.container);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export async function unmount(props: MicroAppProps) {
|
|
141
|
+
mainAppProps = null;
|
|
142
|
+
// 卸载应用
|
|
143
|
+
ReactDOM.unmountComponentAtNode(props.container);
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### 2. 使用主应用的 request
|
|
148
|
+
```typescript
|
|
149
|
+
// 获取主应用传递的 request 实例
|
|
150
|
+
const request = mainAppProps?.request;
|
|
151
|
+
|
|
152
|
+
// 发起请求
|
|
153
|
+
const data = await request('/api/users');
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### 3. Webpack 配置
|
|
157
|
+
```javascript
|
|
158
|
+
// 子应用需要配置 umd 输出
|
|
159
|
+
output: {
|
|
160
|
+
library: `${name}-[name]`,
|
|
161
|
+
libraryTarget: 'umd',
|
|
162
|
+
jsonpFunction: `webpackJsonp_${name}`,
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## 路由匹配
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
/**
|
|
170
|
+
* 根据路径查找对应的路由配置
|
|
171
|
+
* 支持通配符路由 /test/*
|
|
172
|
+
*/
|
|
173
|
+
export const findRouteByPath = (
|
|
174
|
+
routes: ParsedRoute[],
|
|
175
|
+
pathname: string,
|
|
176
|
+
): ParsedRoute | undefined => {
|
|
177
|
+
return routes.find((route) => {
|
|
178
|
+
// 处理通配符路由
|
|
179
|
+
if (route.path.endsWith('/*')) {
|
|
180
|
+
const basePath = route.path.slice(0, -2);
|
|
181
|
+
return pathname.startsWith(basePath);
|
|
182
|
+
}
|
|
183
|
+
return route.path === pathname;
|
|
184
|
+
});
|
|
185
|
+
};
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## 注意事项
|
|
189
|
+
|
|
190
|
+
1. **路由通配符**: 微应用路由建议使用 `/path/*` 以支持子路由
|
|
191
|
+
2. **入口优先级**: `htmlUrl` 优先级高于 `jsUrls[0]`
|
|
192
|
+
3. **CORS 配置**: 子应用需要配置允许主应用域名访问
|
|
193
|
+
4. **生命周期**: 子应用必须导出 `bootstrap`、`mount`、`unmount`
|
|
194
|
+
5. **重载触发**: `entry` 或 `name` 变化时会重新加载微应用
|
|
195
|
+
6. **错误处理**: 加载失败会显示错误信息,便于调试
|
|
196
|
+
7. **认证共享**: 子应用应使用主应用传递的 `request` 实例
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: <%= ProjectName %> 项目总览 - 基于 qiankun 微前端架构的管理平台
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# <%= ProjectName %>
|
|
7
|
+
|
|
8
|
+
## 项目简介
|
|
9
|
+
|
|
10
|
+
<%= ProjectName %> 是一个基于 qiankun 微前端架构的管理平台 Monorepo,采用 Turborepo + pnpm Workspace 管理多个子应用。
|
|
11
|
+
|
|
12
|
+
## 技术栈
|
|
13
|
+
|
|
14
|
+
| 分类 | 技术 |
|
|
15
|
+
|------|------|
|
|
16
|
+
| **Monorepo** | Turborepo + pnpm Workspace |
|
|
17
|
+
| **前端框架** | UmiJS 4 (@umijs/max)、React 18、TypeScript |
|
|
18
|
+
| **微前端** | qiankun |
|
|
19
|
+
| **UI 组件** | Arco Design Web |
|
|
20
|
+
| **样式方案** | Tailwind CSS + Less + CSS Variables |
|
|
21
|
+
| **代码规范** | ESLint、Stylelint、Husky、Commitlint |
|
|
22
|
+
|
|
23
|
+
## 项目结构
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
<%= projectName %>/
|
|
27
|
+
├── apps/ # Workspace 应用目录
|
|
28
|
+
│ ├── layout/ # 🏠 主布局应用(qiankun 主应用)
|
|
29
|
+
│ │ ├── config/ # Umi 配置
|
|
30
|
+
│ │ ├── docs/ # 功能文档
|
|
31
|
+
│ │ ├── mock/ # Mock 数据
|
|
32
|
+
│ │ └── src/
|
|
33
|
+
│ │ ├── app.tsx # Umi 运行时配置
|
|
34
|
+
│ │ ├── layouts/ # 布局组件
|
|
35
|
+
│ │ ├── pages/ # 路由页面
|
|
36
|
+
│ │ ├── components/ # 公共组件
|
|
37
|
+
│ │ ├── common/ # 工具模块
|
|
38
|
+
│ │ │ ├── auth/ # 认证模块
|
|
39
|
+
│ │ │ ├── request/ # 请求层
|
|
40
|
+
│ │ │ ├── menu/ # 菜单系统
|
|
41
|
+
│ │ │ └── upload/ # 上传模块
|
|
42
|
+
│ │ ├── hooks/ # 自定义 Hooks
|
|
43
|
+
│ │ ├── services/ # API 服务层
|
|
44
|
+
│ │ ├── models/ # Umi model(全局状态)
|
|
45
|
+
│ │ ├── locales/ # 国际化(zh-CN、en-US)
|
|
46
|
+
│ │ └── styles/ # 主题变量与样式
|
|
47
|
+
│ └── [subapp]/ # 📄 子应用
|
|
48
|
+
├── scripts/ # 构建与开发脚本
|
|
49
|
+
├── CICD/ # CI/CD 部署脚本
|
|
50
|
+
├── docs/ # 项目文档
|
|
51
|
+
├── turbo.json # Turborepo 配置
|
|
52
|
+
├── pnpm-workspace.yaml # Workspace 配置
|
|
53
|
+
└── package.json # 根包配置
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 核心模块说明
|
|
57
|
+
|
|
58
|
+
### 1. Layout 主应用 (apps/layout)
|
|
59
|
+
- **角色**: qiankun 主应用容器
|
|
60
|
+
- **职责**: 提供布局框架、菜单导航、主题切换、认证管理
|
|
61
|
+
- **关键文件**:
|
|
62
|
+
- `src/layouts/index.tsx` - 主布局组件
|
|
63
|
+
- `src/components/MicroAppLoader/` - 微应用加载器
|
|
64
|
+
- `src/common/menu/parser.ts` - 菜单解析与路由提取
|
|
65
|
+
- `src/common/request/index.ts` - 统一请求封装
|
|
66
|
+
- `src/hooks/useTheme.ts` - 主题管理 Hook
|
|
67
|
+
|
|
68
|
+
### 2. 微前端架构
|
|
69
|
+
- 菜单数据通过 `window.__MICO_MENUS__` 注入
|
|
70
|
+
- 根据 `htmlUrl` 或 `jsUrls` 判断是否为微应用
|
|
71
|
+
- 使用 `loadMicroApp` API 动态挂载子应用
|
|
72
|
+
- 子应用共享主应用的 `request` 实例
|
|
73
|
+
|
|
74
|
+
### 3. 主题系统
|
|
75
|
+
- 支持亮色/暗黑主题切换
|
|
76
|
+
- 使用 CSS Variables 实现运行时动态切换
|
|
77
|
+
- `arco-theme` 控制 Arco Design 组件
|
|
78
|
+
- `data-theme` 控制自定义样式
|
|
79
|
+
|
|
80
|
+
## 常用命令
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# 安装依赖
|
|
84
|
+
pnpm install
|
|
85
|
+
|
|
86
|
+
# 开发(交互式选择应用)
|
|
87
|
+
pnpm dev
|
|
88
|
+
|
|
89
|
+
# 直接启动指定应用
|
|
90
|
+
pnpm -C apps/layout dev
|
|
91
|
+
|
|
92
|
+
# 构建
|
|
93
|
+
pnpm build # 生产环境
|
|
94
|
+
pnpm build:development # 开发环境
|
|
95
|
+
pnpm build:testing # 测试环境
|
|
96
|
+
|
|
97
|
+
# 代码检查
|
|
98
|
+
pnpm lint
|
|
99
|
+
pnpm lint:fix
|
|
100
|
+
|
|
101
|
+
# 创建新应用
|
|
102
|
+
mico create subapp-react
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## 环境变量
|
|
106
|
+
|
|
107
|
+
- 根目录 `.env` 文件通过 `dotenv-cli` 注入所有应用
|
|
108
|
+
- 应用专属变量放在 `apps/<app>/.env.local`
|
|
109
|
+
- 影响缓存的变量需在 `turbo.json` 的 `globalEnv` 中登记
|
|
110
|
+
|
|
111
|
+
## CI/CD 构建
|
|
112
|
+
|
|
113
|
+
Jenkins 根据环境执行 `CICD/` 下的构建脚本:
|
|
114
|
+
|
|
115
|
+
| 环境 | 脚本 | CDN 域名 |
|
|
116
|
+
|------|------|---------|
|
|
117
|
+
| 开发 | `start_dev.sh` | `cdn-dev.example.com` |
|
|
118
|
+
| 测试 | `start_test.sh` | `cdn-test.example.com` |
|
|
119
|
+
| 生产 | `start_prod.sh` | `cdn.example.com` |
|
|
120
|
+
|
|
121
|
+
分支策略:`test` → 测试环境,`main` → 生产环境
|
|
122
|
+
|
|
123
|
+
## 相关文档
|
|
124
|
+
|
|
125
|
+
- [微前端模式](mdc:apps/layout/docs/feature-微前端模式.md)
|
|
126
|
+
- [主题色切换](mdc:apps/layout/docs/feature-主题色切换.md)
|
|
127
|
+
- [提交规范](mdc:docs/commit-message.md)
|
|
128
|
+
- [部署说明](mdc:deployDesc.md)
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 请求与认证模块 - API 请求封装与 SSO 认证流程
|
|
3
|
+
globs: ["**/request/**", "**/auth/**", "**/services/**"]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 请求与认证模块
|
|
7
|
+
|
|
8
|
+
## 请求层架构
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
12
|
+
│ request() 函数 │
|
|
13
|
+
├─────────────────────────────────────────────────────────────┤
|
|
14
|
+
│ 1. ensureSsoSession() - 处理 SSO ticket 换 token │
|
|
15
|
+
│ 2. runRequestInterceptors() - 执行请求拦截器 │
|
|
16
|
+
│ 3. baseRequest() - 发起实际请求 │
|
|
17
|
+
│ 4. runResponseInterceptors() - 执行响应拦截器 │
|
|
18
|
+
│ 5. 错误处理 - 401/403 时刷新 token │
|
|
19
|
+
└─────────────────────────────────────────────────────────────┘
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## 核心文件
|
|
23
|
+
|
|
24
|
+
| 文件 | 说明 |
|
|
25
|
+
|------|------|
|
|
26
|
+
| `src/common/request/index.ts` | 统一请求封装 |
|
|
27
|
+
| `src/common/auth/cs-auth-manager.ts` | Token 存储管理 |
|
|
28
|
+
| `src/common/auth/index.ts` | 认证入口 |
|
|
29
|
+
| `src/common/auth/tool.ts` | 认证工具函数 |
|
|
30
|
+
| `src/requestErrorConfig.ts` | 错误处理配置 |
|
|
31
|
+
|
|
32
|
+
## 请求函数使用
|
|
33
|
+
|
|
34
|
+
### 基本用法
|
|
35
|
+
```typescript
|
|
36
|
+
import { request } from '@/common/request';
|
|
37
|
+
|
|
38
|
+
// GET 请求
|
|
39
|
+
const users = await request<IUserList>('/api/users');
|
|
40
|
+
|
|
41
|
+
// POST 请求
|
|
42
|
+
const result = await request('/api/users', {
|
|
43
|
+
method: 'POST',
|
|
44
|
+
data: { name: 'John' },
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// 带自定义 headers
|
|
48
|
+
const data = await request('/api/data', {
|
|
49
|
+
headers: { 'X-Custom': 'value' },
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 请求选项
|
|
54
|
+
```typescript
|
|
55
|
+
interface UnifiedRequestOptions {
|
|
56
|
+
method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
57
|
+
data?: any;
|
|
58
|
+
headers?: Record<string, string>;
|
|
59
|
+
proxySuffix?: string; // 自定义代理路径
|
|
60
|
+
useCache?: boolean; // 使用缓存
|
|
61
|
+
[key: string]: any;
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 请求拦截器
|
|
66
|
+
|
|
67
|
+
### 内置拦截器
|
|
68
|
+
1. **等待队列拦截器**: 在获取 token 期间拦截请求
|
|
69
|
+
2. **默认 Headers 拦截器**: 添加认证信息
|
|
70
|
+
|
|
71
|
+
### 注册自定义拦截器
|
|
72
|
+
```typescript
|
|
73
|
+
import { registerRequestInterceptor, registerResponseInterceptor } from '@/common/request';
|
|
74
|
+
|
|
75
|
+
// 请求拦截器
|
|
76
|
+
const removeInterceptor = registerRequestInterceptor(async (ctx) => {
|
|
77
|
+
console.log('Request:', ctx.url);
|
|
78
|
+
return ctx;
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// 响应拦截器
|
|
82
|
+
registerResponseInterceptor(async (data, ctx) => {
|
|
83
|
+
console.log('Response:', data);
|
|
84
|
+
return data;
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// 移除拦截器
|
|
88
|
+
removeInterceptor();
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## 认证流程
|
|
92
|
+
|
|
93
|
+
### SSO 登录流程
|
|
94
|
+
```
|
|
95
|
+
┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
96
|
+
│ 用户 │ │ 主应用 │ │ SSO 服务 │
|
|
97
|
+
└────┬─────┘ └────┬─────┘ └────┬─────┘
|
|
98
|
+
│ │ │
|
|
99
|
+
│ 访问页面 │ │
|
|
100
|
+
│───────────────>│ │
|
|
101
|
+
│ │ │
|
|
102
|
+
│ │ 无 token,重定向 │
|
|
103
|
+
│<───────────────│ │
|
|
104
|
+
│ │ │
|
|
105
|
+
│ SSO 登录 │ │
|
|
106
|
+
│──────────────────────────────────>
|
|
107
|
+
│ │ │
|
|
108
|
+
│ 带 ticket 回调 │ │
|
|
109
|
+
│<──────────────────────────────────
|
|
110
|
+
│ │ │
|
|
111
|
+
│ ticket 换 token │
|
|
112
|
+
│ │───────────────>│
|
|
113
|
+
│ │<───────────────│
|
|
114
|
+
│ │ │
|
|
115
|
+
│ 返回页面内容 │ │
|
|
116
|
+
│<───────────────│ │
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Token 刷新流程
|
|
120
|
+
```typescript
|
|
121
|
+
// 401/403 时自动刷新 token
|
|
122
|
+
try {
|
|
123
|
+
const response = await baseRequest(url, options);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
if (shouldAttemptRefresh(error)) {
|
|
126
|
+
const newToken = await getRefreshPromise();
|
|
127
|
+
if (newToken) {
|
|
128
|
+
// 使用新 token 重试请求
|
|
129
|
+
return baseRequest(url, { ...options, headers: { authtoken: newToken } });
|
|
130
|
+
}
|
|
131
|
+
// 刷新失败,重定向登录
|
|
132
|
+
handleAuthFailureRedirect();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Token 存储
|
|
138
|
+
|
|
139
|
+
### 存储 Key
|
|
140
|
+
```typescript
|
|
141
|
+
const AUTH_TOKEN_KEY = 'auth_token';
|
|
142
|
+
const REFRESH_TOKEN_KEY = 'refresh_token';
|
|
143
|
+
const UID_KEY = 'uid';
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### 获取/设置 Token
|
|
147
|
+
```typescript
|
|
148
|
+
import {
|
|
149
|
+
getStoredAuthToken,
|
|
150
|
+
setStoredAuthToken,
|
|
151
|
+
getStoredRefreshToken,
|
|
152
|
+
setStoredRefreshToken,
|
|
153
|
+
clearStoredTokens,
|
|
154
|
+
} from '@/common/auth/cs-auth-manager';
|
|
155
|
+
|
|
156
|
+
// 获取 token
|
|
157
|
+
const token = getStoredAuthToken();
|
|
158
|
+
|
|
159
|
+
// 设置 token
|
|
160
|
+
setStoredAuthToken(newToken);
|
|
161
|
+
|
|
162
|
+
// 清除所有 token(登出)
|
|
163
|
+
clearStoredTokens();
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## 环境变量
|
|
167
|
+
|
|
168
|
+
在 `.env` 文件中配置:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
# API 基础地址
|
|
172
|
+
API_BASE_URL=https://api.example.com
|
|
173
|
+
|
|
174
|
+
# 代理路径后缀
|
|
175
|
+
PROXY_SUFFIX=/api
|
|
176
|
+
|
|
177
|
+
# 应用 ID
|
|
178
|
+
APP_ID=<%= projectName %>
|
|
179
|
+
|
|
180
|
+
# SSO 相关
|
|
181
|
+
LOGIN_ENDPOINT=/auth/login
|
|
182
|
+
REFRESH_ENDPOINT=/auth/refresh
|
|
183
|
+
EXTERNAL_LOGIN_PATH=https://sso.example.com/login
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## 错误处理
|
|
187
|
+
|
|
188
|
+
### 业务错误码
|
|
189
|
+
```typescript
|
|
190
|
+
// 响应拦截器处理 result.code
|
|
191
|
+
addResponseInterceptor(async (data) => {
|
|
192
|
+
if (data?.result?.code !== 0) {
|
|
193
|
+
const error = new Error(data.result.desc);
|
|
194
|
+
error.code = data.result.code;
|
|
195
|
+
error.response = data;
|
|
196
|
+
throw error;
|
|
197
|
+
}
|
|
198
|
+
return data;
|
|
199
|
+
});
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### 使用 try-catch
|
|
203
|
+
```typescript
|
|
204
|
+
try {
|
|
205
|
+
const data = await request('/api/users');
|
|
206
|
+
} catch (error) {
|
|
207
|
+
if (error.code === 1001) {
|
|
208
|
+
// 处理特定错误码
|
|
209
|
+
}
|
|
210
|
+
console.error('请求失败:', error.message);
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## 注意事项
|
|
215
|
+
|
|
216
|
+
1. **统一使用 request**: 不要直接使用 `fetch` 或 `axios`
|
|
217
|
+
2. **Token 自动处理**: 请求头自动携带 authtoken
|
|
218
|
+
3. **错误自动提示**: success: false 时自动弹出错误消息
|
|
219
|
+
4. **子应用共享**: 微应用应使用主应用传递的 request 实例
|
|
220
|
+
5. **防重复刷新**: token 刷新期间的请求会进入等待队列
|