generator-mico-cli 0.2.30 → 0.2.32

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 (183) hide show
  1. package/README.md +146 -18
  2. package/bin/mico.js +76 -0
  3. package/generators/h5-react/ignore-list.json +1 -0
  4. package/generators/h5-react/index.js +349 -0
  5. package/generators/h5-react/meta.json +11 -0
  6. package/generators/h5-react/templates/.commitlintrc.js +7 -0
  7. package/generators/h5-react/templates/.cursor/rules/cicd-deploy.mdc +104 -0
  8. package/generators/h5-react/templates/.cursor/rules/common-intl.mdc +42 -0
  9. package/generators/h5-react/templates/.cursor/rules/git-hooks.mdc +40 -0
  10. package/generators/h5-react/templates/.cursor/rules/internal-packages.mdc +46 -0
  11. package/generators/h5-react/templates/.cursor/rules/monorepo.mdc +64 -0
  12. package/generators/h5-react/templates/.cursor/rules/package-json.mdc +52 -0
  13. package/generators/h5-react/templates/.cursor/rules/tailwind-umi.mdc +60 -0
  14. package/generators/h5-react/templates/.cursor/rules/umi-app.mdc +74 -0
  15. package/generators/h5-react/templates/.cursor/rules/umi-config.mdc +86 -0
  16. package/generators/h5-react/templates/.cursor/rules/umi-mock.mdc +80 -0
  17. package/generators/h5-react/templates/.cursor/rules/workspace-request.mdc +52 -0
  18. package/generators/h5-react/templates/.cursor/skills/biz-app-analyzer/SKILL.md +213 -0
  19. package/generators/h5-react/templates/.cursor/skills/biz-app-analyzer/evals/evals.json +23 -0
  20. package/generators/h5-react/templates/.cursor/skills/biz-app-analyzer/references/cursor-rule-template.md +60 -0
  21. package/generators/h5-react/templates/.cursor/skills/biz-app-analyzer/references/phase-1-scanning.md +102 -0
  22. package/generators/h5-react/templates/.cursor/skills/biz-app-analyzer/references/phase-2-context-analysis.md +102 -0
  23. package/generators/h5-react/templates/.cursor/skills/biz-app-analyzer/references/phase-3-pattern-extraction.md +105 -0
  24. package/generators/h5-react/templates/.cursor/skills/biz-app-analyzer/references/phase-4-module-mapping.md +65 -0
  25. package/generators/h5-react/templates/.cursor/skills/biz-app-analyzer/references/phase-5-glossary.md +63 -0
  26. package/generators/h5-react/templates/.cursor/skills/biz-app-analyzer/references/templates/DEV_PATTERNS.tpl.md +77 -0
  27. package/generators/h5-react/templates/.cursor/skills/biz-app-analyzer/references/templates/GLOSSARY.tpl.md +17 -0
  28. package/generators/h5-react/templates/.cursor/skills/biz-app-analyzer/references/templates/MODULE_MAP.tpl.md +45 -0
  29. package/generators/h5-react/templates/.cursor/skills/biz-app-analyzer/references/templates/PROJECT_CONTEXT.tpl.md +155 -0
  30. package/generators/h5-react/templates/.cursor/skills/biz-app-analyzer/references/update-mode.md +116 -0
  31. package/generators/h5-react/templates/.env.development +5 -0
  32. package/generators/h5-react/templates/.env.production +5 -0
  33. package/generators/h5-react/templates/.env.testing +5 -0
  34. package/generators/h5-react/templates/.husky/commit-msg +2 -0
  35. package/generators/h5-react/templates/.husky/pre-commit +2 -0
  36. package/generators/h5-react/templates/.lintstagedrc.js +8 -0
  37. package/generators/h5-react/templates/.prettierrc.json +7 -0
  38. package/generators/h5-react/templates/CICD/before_build.sh +76 -0
  39. package/generators/h5-react/templates/CICD/start_dev.sh +54 -0
  40. package/generators/h5-react/templates/CICD/start_local.sh +30 -0
  41. package/generators/h5-react/templates/CICD/start_prod.sh +53 -0
  42. package/generators/h5-react/templates/CICD/start_test.sh +55 -0
  43. package/generators/h5-react/templates/CICD/wangsu_fresh_dev.sh +19 -0
  44. package/generators/h5-react/templates/CICD/wangsu_fresh_prod.sh +19 -0
  45. package/generators/h5-react/templates/CICD/wangsu_fresh_test.sh +19 -0
  46. package/generators/h5-react/templates/README.md +301 -0
  47. package/generators/h5-react/templates/_gitignore +30 -0
  48. package/generators/h5-react/templates/_npmrc +6 -0
  49. package/generators/h5-react/templates/apps/.gitkeep +0 -0
  50. package/generators/h5-react/templates/dev.preset.json +10 -0
  51. package/generators/h5-react/templates/package.json +56 -0
  52. package/generators/h5-react/templates/packages/common-intl/README.md +180 -0
  53. package/generators/h5-react/templates/packages/common-intl/eslint.config.ts +12 -0
  54. package/generators/h5-react/templates/packages/common-intl/package.json +31 -0
  55. package/generators/h5-react/templates/packages/common-intl/src/index.ts +3 -0
  56. package/generators/h5-react/templates/packages/common-intl/src/intl.ts +100 -0
  57. package/generators/h5-react/templates/packages/common-intl/tsconfig.json +3 -0
  58. package/generators/h5-react/templates/packages/components/eslint.config.ts +12 -0
  59. package/generators/h5-react/templates/packages/components/package.json +32 -0
  60. package/generators/h5-react/templates/packages/components/src/Layout/ImmersiveHeader.tsx +126 -0
  61. package/generators/h5-react/templates/packages/components/src/Layout/LayoutFooter.tsx +72 -0
  62. package/generators/h5-react/templates/packages/components/src/Layout/index.tsx +121 -0
  63. package/generators/h5-react/templates/packages/components/src/assets/image/back.png +0 -0
  64. package/generators/h5-react/templates/packages/components/src/index.ts +0 -0
  65. package/generators/h5-react/templates/packages/components/tsconfig.json +13 -0
  66. package/generators/h5-react/templates/packages/components/typings.d.ts +1 -0
  67. package/generators/h5-react/templates/packages/constant/eslint.config.ts +12 -0
  68. package/generators/h5-react/templates/packages/constant/package.json +19 -0
  69. package/generators/h5-react/templates/packages/constant/src/index.ts +0 -0
  70. package/generators/h5-react/templates/packages/constant/src/member.ts +8 -0
  71. package/generators/h5-react/templates/packages/constant/tsconfig.json +3 -0
  72. package/generators/h5-react/templates/packages/deeplink/eslint.config.ts +12 -0
  73. package/generators/h5-react/templates/packages/deeplink/package.json +18 -0
  74. package/generators/h5-react/templates/packages/deeplink/src/index.ts +7 -0
  75. package/generators/h5-react/templates/packages/deeplink/tsconfig.json +3 -0
  76. package/generators/h5-react/templates/packages/domain/eslint.config.ts +12 -0
  77. package/generators/h5-react/templates/packages/domain/package.json +18 -0
  78. package/generators/h5-react/templates/packages/domain/src/index.ts +29 -0
  79. package/generators/h5-react/templates/packages/domain/tsconfig.json +3 -0
  80. package/generators/h5-react/templates/packages/domain/types.d.ts +11 -0
  81. package/generators/h5-react/templates/packages/eslint/eslint.config.base.ts +36 -0
  82. package/generators/h5-react/templates/packages/eslint/eslint.config.react.ts +33 -0
  83. package/generators/h5-react/templates/packages/eslint/package.json +22 -0
  84. package/generators/h5-react/templates/packages/js-bridge/eslint.config.ts +17 -0
  85. package/generators/h5-react/templates/packages/js-bridge/package.json +23 -0
  86. package/generators/h5-react/templates/packages/js-bridge/src/call.ts +126 -0
  87. package/generators/h5-react/templates/packages/js-bridge/src/closeH5Page.ts +9 -0
  88. package/generators/h5-react/templates/packages/js-bridge/src/getUserInfo.ts +96 -0
  89. package/generators/h5-react/templates/packages/js-bridge/src/index.ts +15 -0
  90. package/generators/h5-react/templates/packages/js-bridge/tsconfig.json +3 -0
  91. package/generators/h5-react/templates/packages/js-bridge/type.d.ts +24 -0
  92. package/generators/h5-react/templates/packages/request/axios.d.ts +42 -0
  93. package/generators/h5-react/templates/packages/request/eslint.config.ts +17 -0
  94. package/generators/h5-react/templates/packages/request/package.json +22 -0
  95. package/generators/h5-react/templates/packages/request/src/index.ts +165 -0
  96. package/generators/h5-react/templates/packages/request/src/interceptors.ts +126 -0
  97. package/generators/h5-react/templates/packages/request/src/types.ts +101 -0
  98. package/generators/h5-react/templates/packages/request/src/url-resolver.ts +66 -0
  99. package/generators/h5-react/templates/packages/request/src/utils.ts +12 -0
  100. package/generators/h5-react/templates/packages/request/tsconfig.json +3 -0
  101. package/generators/h5-react/templates/packages/request/umi.d.ts +94 -0
  102. package/generators/h5-react/templates/packages/typescript/package.json +11 -0
  103. package/generators/h5-react/templates/packages/typescript/tsconfig.base.json +23 -0
  104. package/generators/h5-react/templates/packages/typescript/tsconfig.react.json +7 -0
  105. package/generators/h5-react/templates/packages/umi-config/eslint.config.ts +12 -0
  106. package/generators/h5-react/templates/packages/umi-config/package.json +31 -0
  107. package/generators/h5-react/templates/packages/umi-config/src/config.dev.ts +34 -0
  108. package/generators/h5-react/templates/packages/umi-config/src/config.prod.development.ts +17 -0
  109. package/generators/h5-react/templates/packages/umi-config/src/config.prod.production.ts +42 -0
  110. package/generators/h5-react/templates/packages/umi-config/src/config.prod.testing.ts +17 -0
  111. package/generators/h5-react/templates/packages/umi-config/src/config.prod.ts +56 -0
  112. package/generators/h5-react/templates/packages/umi-config/src/config.ts +86 -0
  113. package/generators/h5-react/templates/packages/umi-config/src/index.ts +25 -0
  114. package/generators/h5-react/templates/packages/umi-config/src/plugins/apply-sentry-plugin.ts +57 -0
  115. package/generators/h5-react/templates/packages/umi-config/src/type.d.ts +3 -0
  116. package/generators/h5-react/templates/packages/umi-config/tsconfig.json +3 -0
  117. package/generators/h5-react/templates/packages/utils/eslint.config.ts +12 -0
  118. package/generators/h5-react/templates/packages/utils/package.json +27 -0
  119. package/generators/h5-react/templates/packages/utils/src/date.ts +21 -0
  120. package/generators/h5-react/templates/packages/utils/src/env.ts +40 -0
  121. package/generators/h5-react/templates/packages/utils/src/index.ts +3 -0
  122. package/generators/h5-react/templates/packages/utils/src/md5.ts +17 -0
  123. package/generators/h5-react/templates/packages/utils/src/mock.ts +83 -0
  124. package/generators/h5-react/templates/packages/utils/src/number.ts +23 -0
  125. package/generators/h5-react/templates/packages/utils/src/tailwind.ts +12 -0
  126. package/generators/h5-react/templates/packages/utils/src/url.ts +19 -0
  127. package/generators/h5-react/templates/packages/utils/tsconfig.json +9 -0
  128. package/generators/h5-react/templates/page.config.ts +1 -0
  129. package/generators/h5-react/templates/pnpm-workspace.yaml +17 -0
  130. package/generators/h5-react/templates/scripts/collect-dist.js +78 -0
  131. package/generators/h5-react/templates/scripts/dev-preset.js +265 -0
  132. package/generators/h5-react/templates/scripts/dev-preset.schema.json +39 -0
  133. package/generators/h5-react/templates/scripts/dev.js +133 -0
  134. package/generators/h5-react/templates/scripts/gateway.ts +241 -0
  135. package/generators/h5-react/templates/turbo.json +86 -0
  136. package/generators/micro-react/README.md +34 -0
  137. package/generators/micro-react/index.js +2 -0
  138. package/generators/micro-react/templates/apps/layout/config/config.dev.ts +21 -1
  139. package/generators/micro-react/templates/apps/layout/config/config.ts +0 -15
  140. 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 +16 -8
  141. 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 +49 -3
  142. 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 +3 -1
  143. package/generators/micro-react/templates/apps/layout/docs/feature-/350/267/257/347/224/261/346/235/203/351/231/220/346/227/245/345/277/227.md +4 -4
  144. package/generators/micro-react/templates/apps/layout/src/app.tsx +10 -4
  145. package/generators/micro-react/templates/apps/layout/src/common/auth/auth-check-path.ts +14 -0
  146. package/generators/micro-react/templates/apps/layout/src/common/auth/index.ts +1 -0
  147. package/generators/micro-react/templates/apps/layout/src/common/logger.ts +51 -18
  148. package/generators/micro-react/templates/apps/layout/src/common/request/sso.ts +8 -5
  149. package/generators/micro-react/templates/package.json +1 -1
  150. package/generators/subapp-h5/ignore-list.json +1 -0
  151. package/generators/subapp-h5/index.js +424 -0
  152. package/generators/subapp-h5/meta.json +10 -0
  153. package/generators/subapp-h5/templates/.env +1 -0
  154. package/generators/subapp-h5/templates/.stylelintrc.js +22 -0
  155. package/generators/subapp-h5/templates/config/config.dev.ts +7 -0
  156. package/generators/subapp-h5/templates/config/config.prod.development.ts +7 -0
  157. package/generators/subapp-h5/templates/config/config.prod.production.ts +10 -0
  158. package/generators/subapp-h5/templates/config/config.prod.testing.ts +7 -0
  159. package/generators/subapp-h5/templates/config/config.prod.ts +7 -0
  160. package/generators/subapp-h5/templates/config/config.ts +6 -0
  161. package/generators/subapp-h5/templates/config/routes.ts +13 -0
  162. package/generators/subapp-h5/templates/eslint.config.ts +12 -0
  163. package/generators/subapp-h5/templates/mock/user.ts +34 -0
  164. package/generators/subapp-h5/templates/package.json +42 -0
  165. package/generators/subapp-h5/templates/src/app.tsx +14 -0
  166. package/generators/subapp-h5/templates/src/assets/yay.jpg +0 -0
  167. package/generators/subapp-h5/templates/src/intl.ts +37 -0
  168. package/generators/subapp-h5/templates/src/layouts/index.tsx +10 -0
  169. package/generators/subapp-h5/templates/src/pages/index.tsx +22 -0
  170. package/generators/subapp-h5/templates/src/services/user.ts +38 -0
  171. package/generators/subapp-h5/templates/tailwind.config.js +16 -0
  172. package/generators/subapp-h5/templates/tailwind.css +7 -0
  173. package/generators/subapp-h5/templates/tsconfig.json +3 -0
  174. package/generators/subapp-h5/templates/typings.d.ts +1 -0
  175. package/generators/subapp-react/README.md +43 -0
  176. package/generators/subapp-react/index.js +2 -0
  177. package/generators/subapp-react/templates/homepage/README.md +5 -1
  178. package/generators/subapp-react/templates/homepage/config/config.dev.ts +20 -0
  179. package/generators/subapp-react/templates/homepage/config/config.ts +0 -15
  180. package/generators/subapp-react/templates/homepage/src/common/logger.ts +50 -18
  181. package/generators/subapp-umd/README.md +37 -0
  182. package/lib/setup-multica-desktop.js +154 -0
  183. package/package.json +1 -1
@@ -0,0 +1,12 @@
1
+ import baseConfig from '<%= packageScope %>/eslint/react';
2
+ import { defineConfig } from 'eslint/config';
3
+ export default defineConfig([
4
+ ...baseConfig,
5
+ {
6
+ languageOptions: {
7
+ parserOptions: {
8
+ tsconfigRootDir: import.meta.dirname,
9
+ },
10
+ },
11
+ },
12
+ ]);
@@ -0,0 +1,34 @@
1
+ import mockjs from 'mockjs';
2
+ import { z } from 'zod';
3
+ import { defineMock } from 'umi';
4
+ import { baseUrl, tryProxy, validateBody } from '<%= packageScope %>/utils/mock';
5
+
6
+ export default defineMock({
7
+ [`POST ${baseUrl}/user`]: async (req, res) => {
8
+ // 参数校验
9
+ const schema = z.object({
10
+ email: z.string(),
11
+ })
12
+ if (!validateBody(req.body, schema, res)) return;
13
+
14
+ if (await tryProxy(req, res)) return;
15
+
16
+ setTimeout(() => {
17
+ res.json(mockjs.mock({
18
+ 'code': 200,
19
+ 'message': '@cword(10, 20)',
20
+ 'content': {
21
+ 'token': {
22
+ 'accessToken': '@guid()',
23
+ 'refreshToken': '@guid()',
24
+ },
25
+ 'thirdProfile': {
26
+ 'name': '@cname()',
27
+ 'email': '@email()',
28
+ 'phone': /^1(3|5|8|7|9)\d{9}$/,
29
+ },
30
+ },
31
+ }));
32
+ }, 500);
33
+ },
34
+ });
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "<%= appName %>",
3
+ "version": "0.0.1",
4
+ "private": true,
5
+ "author": "<%= author %>",
6
+ "scripts": {
7
+ "dev": "umi dev",
8
+ "build": "npm run build:production",
9
+ "build:development": "cross-env UMI_ENV=development umi build",
10
+ "build:production": "cross-env UMI_ENV=production umi build",
11
+ "build:testing": "cross-env UMI_ENV=testing umi build",
12
+ "postinstall": "umi setup",
13
+ "setup": "umi setup",
14
+ "start": "npm run dev",
15
+ "lint": "eslint && stylelint \"**/*.{css,less}\"",
16
+ "lint:fix": "eslint --fix && stylelint \"**/*.{css,less}\" --fix"
17
+ },
18
+ "dependencies": {
19
+ "<%= packageScope %>/common-intl": "workspace:^",
20
+ "<%= packageScope %>/components": "workspace:^",
21
+ "<%= packageScope %>/constant": "workspace:^",
22
+ "<%= packageScope %>/deeplink": "workspace:^",
23
+ "<%= packageScope %>/domain": "workspace:^",
24
+ "<%= packageScope %>/js-bridge": "workspace:^",
25
+ "<%= packageScope %>/request": "workspace:^",
26
+ "<%= packageScope %>/umi-config": "workspace:^",
27
+ "<%= packageScope %>/utils": "workspace:^",
28
+ "react": "catalog:",
29
+ "react-dom": "catalog:",
30
+ "umi": "catalog:"
31
+ },
32
+ "devDependencies": {
33
+ "@common-web/sentry": "catalog:",
34
+ "<%= packageScope %>/eslint": "workspace:^",
35
+ "@types/react": "catalog:",
36
+ "@types/react-dom": "catalog:",
37
+ "@umijs/plugins": "catalog:",
38
+ "cross-env": "catalog:",
39
+ "tailwindcss": "catalog:",
40
+ "tailwindcss-safe-area": "catalog:"
41
+ }
42
+ }
@@ -0,0 +1,14 @@
1
+ import { fetchMultilingualData } from '@/intl';
2
+
3
+ export function render(oldRender: () => void) {
4
+ /**
5
+ * 在应用渲染前加载多语言数据,可根据需要自己调整逻辑
6
+ */
7
+ fetchMultilingualData()
8
+ .then(oldRender)
9
+ .catch((error: Error) => {
10
+ console.error('获取多语言文案失败', error);
11
+ // 即使失败也继续渲染,使用兜底文案
12
+ oldRender();
13
+ });
14
+ }
@@ -0,0 +1,37 @@
1
+ import { addIntl, init } from '<%= packageScope %>/common-intl';
2
+
3
+ const { fetchMultilingualData, i18n } = init({
4
+ tag: '<%= appName %>',
5
+ indexedDBParams: { dbName: 'i18n_<%= appName %>' },
6
+ });
7
+
8
+ /**
9
+ * 1. 调用方法
10
+ * fetchMultilingualData();
11
+ *
12
+ * 2. 使用文案
13
+ * import intl from '@/intl';
14
+ * intl.common_hello();
15
+ * intl.common_welcome_aa('张三');
16
+ */
17
+ const intl = addIntl(
18
+ {
19
+ // ============ 示例文案(可删除) ============
20
+ common_hello: () =>
21
+ i18n({
22
+ key: 'common_hello',
23
+ defaultMessage: '你好',
24
+ }),
25
+ common_welcome_aa: (name: string) =>
26
+ i18n({
27
+ key: 'common_welcome_aa',
28
+ interpolations: [name],
29
+ defaultMessage: `欢迎, ${name}`,
30
+ }),
31
+ },
32
+ i18n,
33
+ );
34
+
35
+ export { fetchMultilingualData };
36
+
37
+ export default intl;
@@ -0,0 +1,10 @@
1
+ import { SentryErrorBoundary } from '@common-web/sentry';
2
+ import { Outlet } from 'umi';
3
+
4
+ export default function Layout() {
5
+ return (
6
+ <SentryErrorBoundary>
7
+ <Outlet />
8
+ </SentryErrorBoundary>
9
+ );
10
+ }
@@ -0,0 +1,22 @@
1
+ import intl from '@/intl';
2
+ import { fetchUserInfo, type UserResponse } from '@/services/user';
3
+ import Layout from '<%= packageScope %>/components/Layout';
4
+ import { cn } from '<%= packageScope %>/utils/tailwind';
5
+ import { useState } from 'react';
6
+
7
+ export default function HomePage() {
8
+ const [userInfo, setUserInfo] = useState<UserResponse | null>(null);
9
+
10
+ const loadUserInfo = async () => {
11
+ const res = await fetchUserInfo();
12
+ setUserInfo(res);
13
+ };
14
+
15
+ return (
16
+ <Layout immersive={false}>
17
+ <h2 className={cn('text-2xl font-bold text-[16px]')}>app name: <%= appName %></h2>
18
+ <div onClick={loadUserInfo}>{intl.common_hello()}</div>
19
+ <div>{JSON.stringify(userInfo)}</div>
20
+ </Layout>
21
+ );
22
+ }
@@ -0,0 +1,38 @@
1
+ import { request } from '<%= packageScope %>/request';
2
+
3
+ //ts
4
+ export interface UserRequest {
5
+ email: string;
6
+ }
7
+
8
+ export interface UserResponse {
9
+ code: number;
10
+ message: string;
11
+ content: UserResponseContent;
12
+ }
13
+
14
+ export interface UserResponseContent {
15
+ token: UserResponseContentToken;
16
+ thirdProfile: UserResponseContentThirdProfile;
17
+ }
18
+
19
+ export interface UserResponseContentToken {
20
+ accessToken: string;
21
+ refreshToken: string;
22
+ }
23
+
24
+ export interface UserResponseContentThirdProfile {
25
+ name: string;
26
+ email: string;
27
+ phone: string;
28
+ }
29
+
30
+ export async function fetchUserInfo() {
31
+ const res = await request<UserResponse, UserRequest>('/user', {
32
+ method: 'POST',
33
+ data: {
34
+ email: 'test@micous.com',
35
+ },
36
+ });
37
+ return res;
38
+ }
@@ -0,0 +1,16 @@
1
+ import safeAreaConfig from "tailwindcss-safe-area"
2
+
3
+ const config = {
4
+ content: [
5
+ "./src/**/*.{js,jsx,ts,tsx,less,css}",
6
+ // 排除 .umi 目录,避免 Tailwind 重建时触发自己的 watch,导致无限循环
7
+ "!./src/.umi/**",
8
+ "!./src/.umi-production/**",
9
+ "./README.md",
10
+ "./docs/**/*.{md,mdx}",
11
+ "../../packages/components/src/**/*.{ts,tsx}",
12
+ ],
13
+ plugins: [safeAreaConfig],
14
+ }
15
+
16
+ export default config
@@ -0,0 +1,7 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+ html { font-size: 16px; }
5
+ @supports (font-size: calc(1px + 1vw)) {
6
+ html { font-size: calc(100vw / 375 * 16); }
7
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "./src/.umi/tsconfig.json"
3
+ }
@@ -0,0 +1 @@
1
+ import 'umi/typings';
@@ -0,0 +1,43 @@
1
+ # subapp-react 生成器
2
+
3
+ 在已有 Monorepo 的 `apps/` 下创建 React 子应用。详细说明见 [docs/generators.md#subapp-react](../../docs/generators.md#subapp-react)。
4
+
5
+ ## 快速索引
6
+
7
+ | 文件 | 职责 |
8
+ |---|---|
9
+ | `index.js` | 生成器主体;含三处对主应用的联动修改 |
10
+ | `meta.json` | `mico list` 展示信息 |
11
+ | `ignore-list.json` | 模板过滤清单 |
12
+ | `templates/homepage/` | 模板根,本生成器以 `homepage` 作为模板目录名 |
13
+
14
+ ## 使用
15
+
16
+ ```bash
17
+ cd <monorepo-root>
18
+ mico create subapp-react
19
+ ```
20
+
21
+ 要求 monorepo 根包含 `apps/` 目录。
22
+
23
+ ## 联动修改
24
+
25
+ 非 dry-run 时会尝试原位修改主应用以下文件(任一缺失静默跳过):
26
+
27
+ | 文件 | 修改 |
28
+ |---|---|
29
+ | `dev.preset.json` | 向 `presets.full.apps` 追加 `appName` |
30
+ | `apps/layout/mock/pages.ts` | 在兜底路由前插入页面项(`routeKey = cs_web_menu_<snake>_page`) |
31
+ | `apps/layout/mock/api.mock.ts` | 将 `routeKey` 加入 `menu_perms` |
32
+
33
+ 修改完成后 prettier 仅格式化这两个 mock 文件。
34
+
35
+ ## 模板同步
36
+
37
+ 从源仓库的 `apps/homepage` 同步模板:
38
+
39
+ ```bash
40
+ pnpm sync:subapp-react-template -- <source-project-root>
41
+ ```
42
+
43
+ 详见 [docs/scripts.md](../../docs/scripts.md)。
@@ -168,6 +168,8 @@ module.exports = class extends Generator {
168
168
  const templateData = {
169
169
  appName: this.appName,
170
170
  AppName: this.appNamePascal,
171
+ // 用于 MFSU mfName 等需要合法 JS 标识符的场景(不允许 `-`)
172
+ appNameSnake: this.appName.replace(/-/g, '_'),
171
173
  packageScope: this.packageScope,
172
174
  devPort: this.devPort,
173
175
  micoUiVersion: `^${micoUiVer}`,
@@ -64,7 +64,7 @@ PORT=8001
64
64
  │ ├── app.tsx # Umi 运行时配置
65
65
  │ ├── assets/ # 静态资源
66
66
  │ ├── common/ # 公共模块
67
- │ │ ├── logger.ts # 日志工具
67
+ │ │ ├── logger.ts # 日志工具(与 layout 一致:生产首屏 `?debug=1` 可开全量 log/info/warn)
68
68
  │ │ ├── mainApp.ts # 主应用通信
69
69
  │ │ └── request.ts # 请求封装
70
70
  │ ├── pages/ # 页面组件
@@ -75,6 +75,10 @@ PORT=8001
75
75
  └── tsconfig.json
76
76
  ```
77
77
 
78
+ ## 日志(logger)
79
+
80
+ 与 monorepo 内 **layout** 的 `src/common/logger.ts` 规则对齐:生产默认静默 `log`/`info`/`warn`,`error` 仍输出;首屏 URL 带 **`?debug=1`**(或 `debug=true` / `yes`)可在模块加载时打开全量日志。详见主应用文档 `apps/layout/docs/arch-日志与常量.md`(生成项目后路径以仓库为准)。
81
+
78
82
  ## 微前端配置
79
83
 
80
84
  本应用作为 qiankun 子应用运行,关键配置:
@@ -61,6 +61,26 @@ const config: ReturnType<typeof defineConfig> = {
61
61
  // @mico-platform/ui 基础样式(使用运行时解析的最新版本号,避免 latest 标签)
62
62
  `https://cdn-portal.micoplatform.com/portal-center/mico-ui/${MICO_UI_VERSION}/ui/dist/css/mico-ui.min.css`,
63
63
  ],
64
+
65
+ /**
66
+ * @name MFSU 配置
67
+ * @description
68
+ * - mfName: 唯一名隔离微前端 runtime,避免多应用共存时 MFSU 容器冲突
69
+ * - exclude:
70
+ * - `@mico-platform/theme`:theme 子路径解析
71
+ * - `@mico-platform/ui`:尽量与主应用一起编译
72
+ * - `<%= packageScope %>/*`:workspace 包走 webpack 编译,开发态可在 DevTools 直接定位到 packages/* 源码
73
+ * - shared: React 单例,确保 MFSU 预打包里的组件(如 UI 库)与应用共用同一份 React,否则 useContext 报 null
74
+ * @doc https://umijs.org/docs/api/config#mfsu
75
+ */
76
+ mfsu: {
77
+ mfName: 'mf_<%= appNameSnake %>',
78
+ exclude: ['@mico-platform/theme', '@mico-platform/ui', /^<%= packageScope %>\//],
79
+ shared: {
80
+ react: { singleton: true },
81
+ 'react-dom': { singleton: true },
82
+ },
83
+ },
64
84
  };
65
85
 
66
86
  export default defineConfig(config);
@@ -118,21 +118,6 @@ const config: ReturnType<typeof defineConfig> = {
118
118
  * @description 使用 @mico-platform/ui 的 babel preset,实现组件与图标的按需加载
119
119
  */
120
120
  extraBabelPresets: ['@mico-platform/ui/babel-preset'],
121
-
122
- /**
123
- * @name MFSU 配置
124
- * @description
125
- * - exclude: theme 子路径解析;ui 尽量与主应用一起编译
126
- * - shared: React 单例,确保 MFSU 预打包里的组件(如 UI 库)与应用共用同一份 React,否则 useContext 报 null
127
- * @doc https://umijs.org/docs/guides/mfsu
128
- */
129
- mfsu: {
130
- exclude: ['@mico-platform/theme', '@mico-platform/ui'],
131
- shared: {
132
- react: { singleton: true },
133
- 'react-dom': { singleton: true },
134
- },
135
- },
136
121
  };
137
122
 
138
123
  export default defineConfig(config);
@@ -1,38 +1,70 @@
1
1
  /**
2
2
  * 日志工具
3
- * 仅在开发环境下输出日志,生产环境自动静默
3
+ * - 开发环境:全量输出
4
+ * - 生产环境:默认仅 `error` 带前缀输出;可在**首屏 URL** 带 query 打开全量 `log` / `info` / `warn`(与 layout `apps/layout` 的 logger 行为一致)
4
5
  *
5
- * 使用 bind 保持原始调用位置,避免错误栈指向 logger 内部
6
+ * 生产开启方式:首次进入页面时地址栏带 `?debug=1`(或 `debug=true` / `yes`),
7
+ * 在**本 JS 模块加载时刻**解析一次并固定,后续路由或 query 变更**不会**再切换日志级别(需整页刷新带参 URL)。
8
+ *
9
+ * **安全与合规**:`debug` 仅用于临时排障;全量日志可能在控制台暴露业务或个人信息,**勿长期公开或转发**带 `debug` 的生产链接;若接入日志采集需自行脱敏。
10
+ *
11
+ * 使用 bind 保持原始调用位置,避免错误栈指向 logger 内部(在开启详细日志时)
6
12
  */
7
13
 
8
14
  const isDev = process.env.NODE_ENV === 'development';
9
15
 
10
- // 空操作函数(生产环境使用)
11
- const noop = (): void => {};
16
+ /** Query 参数名;与主应用 layout 一致,勿随意改名以免已分享的排障链接失效 */
17
+ export const DEBUG_LOGS_QUERY_KEY = 'debug';
12
18
 
13
- /**
14
- * 创建带前缀的日志函数
15
- * 使用 bind 绑定前缀,保持控制台显示正确的调用位置
16
- */
17
- const createLogger = (prefix: string) => {
18
- if (!isDev) {
19
- // 生产环境返回空操作
20
- return {
21
- log: noop,
22
- info: noop,
23
- warn: noop,
24
- error: noop,
25
- };
19
+ /** 模块初始化时读取一次 `location.search`,之后不变 */
20
+ function readVerboseDebugQueryOnce(): boolean {
21
+ if (typeof window === 'undefined') {
22
+ return false;
23
+ }
24
+ try {
25
+ const v = new URLSearchParams(window.location.search).get(DEBUG_LOGS_QUERY_KEY);
26
+ if (v == null || v === '') {
27
+ return false;
28
+ }
29
+ const normalized = v.toLowerCase();
30
+ return normalized === '1' || normalized === 'true' || normalized === 'yes';
31
+ } catch {
32
+ return false;
26
33
  }
34
+ }
27
35
 
28
- const formattedPrefix = `[${prefix}]`;
36
+ /** 开发环境,或生产环境首屏 URL 已带 `debug` 开关(模块加载时确定);供业务侧按需分支 */
37
+ export const isAppDebugLogsEnabled: boolean = isDev || readVerboseDebugQueryOnce();
38
+
39
+ const noop = (): void => {};
29
40
 
41
+ function createVerboseHandlers(formattedPrefix: string) {
30
42
  return {
31
43
  log: console.log.bind(console, formattedPrefix),
32
44
  info: console.info.bind(console, formattedPrefix),
33
45
  warn: console.warn.bind(console, formattedPrefix),
34
46
  error: console.error.bind(console, formattedPrefix),
35
47
  };
48
+ }
49
+
50
+ function createQuietHandlers(formattedPrefix: string) {
51
+ return {
52
+ log: noop,
53
+ info: noop,
54
+ warn: noop,
55
+ error: console.error.bind(console, formattedPrefix),
56
+ };
57
+ }
58
+
59
+ /**
60
+ * 创建带前缀的日志函数
61
+ * 使用 bind 绑定前缀,保持控制台显示正确的调用位置(在开启详细日志时)
62
+ */
63
+ const createLogger = (prefix: string) => {
64
+ const formattedPrefix = `[${prefix}]`;
65
+ return isAppDebugLogsEnabled
66
+ ? createVerboseHandlers(formattedPrefix)
67
+ : createQuietHandlers(formattedPrefix);
36
68
  };
37
69
 
38
70
  // 预定义的日志实例
@@ -0,0 +1,37 @@
1
+ # subapp-umd 生成器
2
+
3
+ 在已有 Monorepo 的 `packages/` 下创建 UMD 组件包(Webpack 构建)。详见 [docs/generators.md#subapp-umd](../../docs/generators.md#subapp-umd)。
4
+
5
+ ## 快速索引
6
+
7
+ | 文件 | 职责 |
8
+ |---|---|
9
+ | `index.js` | 生成器主体;无跨模块联动修改 |
10
+ | `meta.json` | `mico list` 展示信息 |
11
+ | `ignore-list.json` | 模板过滤清单 |
12
+ | `templates/` | 模板根 |
13
+
14
+ ## 使用
15
+
16
+ ```bash
17
+ cd <monorepo-root>
18
+ mico create subapp-umd
19
+ ```
20
+
21
+ 要求 monorepo 根包含 `packages/` 目录。
22
+
23
+ ## Prompt 默认值
24
+
25
+ | name | 默认 |
26
+ |---|---|
27
+ | `appName` | `.micorc.defaultUmdName` ?? `'my-widget'` |
28
+ | `umdGlobalName` | `toPascal(appName)` |
29
+ | `packageScope` | `.micorc.packageScope` ?? `detectPackageScope()` ?? `'@my-project'` |
30
+ | `devPort` | `.micorc.umdDevPort` ?? `'9100'` |
31
+
32
+ ## 运行产物
33
+
34
+ | URL | 说明 |
35
+ |---|---|
36
+ | `http://localhost:<devPort>/` | HTML 预览页 |
37
+ | `http://localhost:<devPort>/<appName>.umd.js` | UMD JS,供主应用通过 `jsUrls` 接入 |
@@ -0,0 +1,154 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * 为 Multica Desktop 写入自托管配置文件 `~/.multica/desktop.json`。
5
+ *
6
+ * 跨平台路径(统一由 os.homedir() 解析):
7
+ * macOS: /Users/<Username>/.multica/desktop.json
8
+ * Linux: /home/<Username>/.multica/desktop.json
9
+ * Windows: C:\Users\<Username>\.multica\desktop.json
10
+ *
11
+ * 参考:
12
+ * https://github.com/multica-ai/multica/blob/main/apps/docs/content/docs/desktop-app.zh.mdx
13
+ * https://github.com/multica-ai/multica/pull/2012
14
+ */
15
+
16
+ const fs = require('node:fs');
17
+ const os = require('node:os');
18
+ const path = require('node:path');
19
+
20
+ const DEFAULT_CONFIG = Object.freeze({
21
+ schemaVersion: 1,
22
+ apiUrl: 'https://multica-api.micoplatform.com',
23
+ appUrl: 'https://multica.micoplatform.com',
24
+ });
25
+
26
+ /**
27
+ * 解析配置文件路径。
28
+ * @param {string} [homedir] 可注入的 home 目录(便于测试)
29
+ * @returns {{ home: string, dir: string, file: string }}
30
+ */
31
+ function resolvePaths(homedir = os.homedir()) {
32
+ if (!homedir) {
33
+ throw new Error('无法解析当前用户的 home 目录(请检查 HOME / USERPROFILE 环境变量)');
34
+ }
35
+ const dir = path.join(homedir, '.multica');
36
+ const file = path.join(dir, 'desktop.json');
37
+ return { home: homedir, dir, file };
38
+ }
39
+
40
+ /**
41
+ * 基于默认值与覆盖项构造最终配置对象。
42
+ * @param {{ apiUrl?: string, appUrl?: string, wsUrl?: string }} overrides
43
+ * @returns {{ schemaVersion: 1, apiUrl: string, appUrl: string, wsUrl?: string }}
44
+ */
45
+ function buildConfig(overrides = {}) {
46
+ const config = { ...DEFAULT_CONFIG };
47
+ if (overrides.apiUrl) config.apiUrl = overrides.apiUrl;
48
+ if (overrides.appUrl) config.appUrl = overrides.appUrl;
49
+ if (overrides.wsUrl) config.wsUrl = overrides.wsUrl;
50
+ return config;
51
+ }
52
+
53
+ function formatBackupSuffix(date = new Date()) {
54
+ const pad = (n) => String(n).padStart(2, '0');
55
+ return [
56
+ date.getFullYear(),
57
+ pad(date.getMonth() + 1),
58
+ pad(date.getDate()),
59
+ pad(date.getHours()),
60
+ pad(date.getMinutes()),
61
+ pad(date.getSeconds()),
62
+ ].join('');
63
+ }
64
+
65
+ /**
66
+ * 执行 `~/.multica/desktop.json` 的写入流程。
67
+ *
68
+ * @param {object} [options]
69
+ * @param {string} [options.apiUrl] 覆盖默认 apiUrl
70
+ * @param {string} [options.appUrl] 覆盖默认 appUrl
71
+ * @param {string} [options.wsUrl] 显式设置 wsUrl(不传则由 Desktop 自动推导)
72
+ * @param {boolean} [options.dryRun=false] 仅预览,不写盘
73
+ * @param {boolean} [options.force=false] 已存在时不备份直接覆盖
74
+ * @param {boolean} [options.noBackup=false] 不生成 .bak 文件
75
+ * @param {string} [options.homedir] 注入 home 目录(测试用)
76
+ * @param {(msg: string) => void} [options.logger=console.log]
77
+ * @returns {{
78
+ * file: string,
79
+ * dir: string,
80
+ * created: boolean,
81
+ * backedUpTo: string | null,
82
+ * config: object,
83
+ * dryRun: boolean
84
+ * }}
85
+ */
86
+ function runSetupMulticaDesktop(options = {}) {
87
+ const {
88
+ apiUrl,
89
+ appUrl,
90
+ wsUrl,
91
+ dryRun = false,
92
+ force = false,
93
+ noBackup = false,
94
+ homedir,
95
+ logger = console.log,
96
+ } = options;
97
+
98
+ const { dir, file } = resolvePaths(homedir);
99
+ const config = buildConfig({ apiUrl, appUrl, wsUrl });
100
+
101
+ logger(`平台: ${process.platform} (${os.arch()})`);
102
+ logger(`目标文件: ${file}`);
103
+
104
+ const existed = fs.existsSync(file);
105
+ let backedUpTo = null;
106
+
107
+ if (existed && !force && !noBackup) {
108
+ backedUpTo = `${file}.bak.${formatBackupSuffix()}`;
109
+ if (dryRun) {
110
+ logger(`[dry-run] 备份现有文件 -> ${backedUpTo}`);
111
+ } else {
112
+ fs.copyFileSync(file, backedUpTo);
113
+ logger(`已备份现有文件 -> ${backedUpTo}`);
114
+ }
115
+ } else if (existed && force) {
116
+ logger('检测到现有配置(--force,将直接覆盖且不备份)');
117
+ } else if (existed && noBackup) {
118
+ logger('检测到现有配置(--no-backup,将直接覆盖)');
119
+ }
120
+
121
+ if (!fs.existsSync(dir)) {
122
+ if (dryRun) {
123
+ logger(`[dry-run] 创建目录: ${dir}`);
124
+ } else {
125
+ fs.mkdirSync(dir, { recursive: true });
126
+ logger(`已创建目录: ${dir}`);
127
+ }
128
+ }
129
+
130
+ const content = `${JSON.stringify(config, null, 2)}\n`;
131
+ if (dryRun) {
132
+ logger(`[dry-run] 将写入 ${file}:\n${content}`);
133
+ } else {
134
+ fs.writeFileSync(file, content, { encoding: 'utf8' });
135
+ logger(`已写入配置: ${file}`);
136
+ logger('完成。请重启 Multica Desktop 让配置生效。');
137
+ }
138
+
139
+ return {
140
+ file,
141
+ dir,
142
+ created: !existed,
143
+ backedUpTo,
144
+ config,
145
+ dryRun,
146
+ };
147
+ }
148
+
149
+ module.exports = {
150
+ DEFAULT_CONFIG,
151
+ resolvePaths,
152
+ buildConfig,
153
+ runSetupMulticaDesktop,
154
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "generator-mico-cli",
3
- "version": "0.2.30",
3
+ "version": "0.2.32",
4
4
  "description": "Yeoman generator for Mico CLI projects",
5
5
  "keywords": [
6
6
  "yeoman-generator",