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,54 @@
1
+ #!/bin/bash
2
+ source ~/.bashrc
3
+ node -v
4
+ nvm -v
5
+ nvm install 22.20.0
6
+ nvm use 22.20.0
7
+ npm i -g pnpm@10.18.2 --registry=https://registry.npmmirror.com
8
+ pnpm install
9
+
10
+ # 获取当前脚本所在目录
11
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12
+ # 获取项目根目录(假设脚本在 CICD 目录下,所以向上一层)
13
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
14
+
15
+ # 用 node 命令读取 package.json 里的 version 字段
16
+ VERSION=$(node -p "require('$PROJECT_ROOT/package.json').version")
17
+ # 输出项目版本号
18
+ echo "项目版本: $VERSION"
19
+
20
+ # 切换到项目根目录,确保后续命令在根目录下运行
21
+ cd "$PROJECT_ROOT"
22
+
23
+ # 导出 PROJECT_ROOT 供 before_build.sh 使用
24
+ export PROJECT_ROOT
25
+
26
+ # 在执行构建前,计算 BASE_REF / TURBO_FILTER 等增量构建信息
27
+ if [ -f "$PROJECT_ROOT/CICD/before_build.sh" ]; then
28
+ # shellcheck disable=SC1090
29
+ source "$PROJECT_ROOT/CICD/before_build.sh"
30
+ fi
31
+
32
+ # 设置子应用的 CDN 公共路径(开发环境)
33
+ # 路径格式: https://cdn-xxx.com/<prefix>/<projectName>/<version>/
34
+ export CDN_PUBLIC_PATH="https://cdn-portal-dev.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/${VERSION}/"
35
+ echo "CDN_PUBLIC_PATH: $CDN_PUBLIC_PATH"
36
+
37
+ # 开发环境,不上传 sourcemap。调试时如有需要再解开
38
+ # # ========== Sentry Auth Token ==========
39
+ # # SENTRY_AUTH_TOKEN 从 Jenkins 服务器文件读取(敏感信息,不写在脚本中)
40
+ # SENTRY_TOKEN_FILE="/var/lib/jenkins/.portal_sentry_auth_token"
41
+ # if [ -f "$SENTRY_TOKEN_FILE" ]; then
42
+ # export SENTRY_AUTH_TOKEN=$(cat "$SENTRY_TOKEN_FILE")
43
+ # fi
44
+
45
+ # if [ -z "$SENTRY_AUTH_TOKEN" ]; then
46
+ # echo "警告:SENTRY_AUTH_TOKEN 未设置(文件 $SENTRY_TOKEN_FILE 不存在),跳过 sourcemap 上传"
47
+ # fi
48
+
49
+ pnpm run build:development
50
+
51
+ # 只有在 CI 环境时才写入版本号文件(覆盖写入)
52
+ if [ "${CI}" = "true" ]; then
53
+ echo "VERSION=$VERSION" > .env_x_<%= projectName %>
54
+ fi
@@ -0,0 +1,30 @@
1
+ #!/bin/bash
2
+ source ~/.bashrc
3
+ node -v
4
+ nvm -v
5
+ nvm install 22.20.0
6
+ nvm use 22.20.0
7
+ npm i -g pnpm@10.18.2 --registry=https://registry.npmmirror.com
8
+ pnpm install
9
+
10
+ # 获取当前脚本所在目录
11
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12
+ # 获取项目根目录(假设脚本在 CICD 目录下,所以向上一层)
13
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
14
+
15
+ # 用 node 命令读取 package.json 里的 version 字段
16
+ VERSION=$(node -p "require('$PROJECT_ROOT/package.json').version")
17
+ # 输出项目版本号
18
+ echo "项目版本: $VERSION"
19
+
20
+ # 切换到项目根目录,确保后续命令在根目录下运行
21
+ cd "$PROJECT_ROOT"
22
+
23
+ # 设置子应用的 CDN 公共路径(本地环境使用相对路径)
24
+ export CDN_PUBLIC_PATH="./"
25
+ echo "CDN_PUBLIC_PATH: $CDN_PUBLIC_PATH"
26
+
27
+ pnpm run build:local
28
+
29
+ echo "VERSION=$VERSION" > .env_x_<%= projectName %>
30
+
@@ -0,0 +1,53 @@
1
+ #!/bin/bash
2
+ source ~/.bashrc
3
+ node -v
4
+ nvm -v
5
+ nvm install 22.20.0
6
+ nvm use 22.20.0
7
+ npm i -g pnpm@10.18.2 --registry=https://registry.npmmirror.com
8
+ pnpm install
9
+
10
+ # 获取当前脚本所在目录
11
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12
+ # 获取项目根目录(假设脚本在 CICD 目录下,所以向上一层)
13
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
14
+
15
+ # 用 node 命令读取 package.json 里的 version 字段
16
+ VERSION=$(node -p "require('$PROJECT_ROOT/package.json').version")
17
+ # 输出项目版本号
18
+ echo "项目版本: $VERSION"
19
+
20
+ # 切换到项目根目录,确保后续命令在根目录下运行
21
+ cd "$PROJECT_ROOT"
22
+
23
+ # 导出 PROJECT_ROOT 供 before_build.sh 使用
24
+ export PROJECT_ROOT
25
+
26
+ # 在执行构建前,计算 BASE_REF / TURBO_FILTER 等增量构建信息(用于增量构建)
27
+ if [ -f "$PROJECT_ROOT/CICD/before_build.sh" ]; then
28
+ # shellcheck disable=SC1090
29
+ source "$PROJECT_ROOT/CICD/before_build.sh"
30
+ fi
31
+
32
+ # 设置子应用的 CDN 公共路径(生产环境)
33
+ # 路径格式: https://cdn-xxx.com/<prefix>/<projectName>/<version>/
34
+ export CDN_PUBLIC_PATH="https://cdn-portal.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/${VERSION}/"
35
+ echo "CDN_PUBLIC_PATH: $CDN_PUBLIC_PATH"
36
+
37
+ # ========== Sentry Auth Token ==========
38
+ # SENTRY_AUTH_TOKEN 从 Jenkins 服务器文件读取(敏感信息,不写在脚本中)
39
+ SENTRY_TOKEN_FILE="/var/lib/jenkins/.portal_sentry_auth_token"
40
+ if [ -f "$SENTRY_TOKEN_FILE" ]; then
41
+ export SENTRY_AUTH_TOKEN=$(cat "$SENTRY_TOKEN_FILE")
42
+ fi
43
+
44
+ if [ -z "$SENTRY_AUTH_TOKEN" ]; then
45
+ echo "警告:SENTRY_AUTH_TOKEN 未设置(文件 $SENTRY_TOKEN_FILE 不存在),跳过 sourcemap 上传"
46
+ fi
47
+
48
+ pnpm run build:production
49
+
50
+ # 只有在 CI 环境时才写入版本号文件(覆盖写入)
51
+ if [ "${CI}" = "true" ]; then
52
+ echo "VERSION=$VERSION" > .env_x_<%= projectName %>
53
+ fi
@@ -0,0 +1,55 @@
1
+ #!/bin/bash
2
+ source ~/.bashrc
3
+ node -v
4
+ nvm -v
5
+ nvm install 22.20.0
6
+ nvm use 22.20.0
7
+ npm i -g pnpm@10.18.2 --registry=https://registry.npmmirror.com
8
+ pnpm install
9
+
10
+ # 获取当前脚本所在目录
11
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12
+ # 获取项目根目录(假设脚本在 CICD 目录下,所以向上一层)
13
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
14
+
15
+ # 用 node 命令读取 package.json 里的 version 字段
16
+ VERSION=$(node -p "require('$PROJECT_ROOT/package.json').version")
17
+ # 输出项目版本号
18
+ echo "项目版本: $VERSION"
19
+
20
+ # 切换到项目根目录,确保后续命令在根目录下运行
21
+ cd "$PROJECT_ROOT"
22
+
23
+ # 导出 PROJECT_ROOT 供 before_build.sh 使用
24
+ export PROJECT_ROOT
25
+
26
+ # 在执行构建前,计算 BASE_REF / TURBO_FILTER 等增量构建信息
27
+ if [ -f "$PROJECT_ROOT/CICD/before_build.sh" ]; then
28
+ # shellcheck disable=SC1090
29
+ source "$PROJECT_ROOT/CICD/before_build.sh"
30
+ fi
31
+
32
+
33
+ # 设置子应用的 CDN 公共路径(测试环境)
34
+ # 路径格式: https://cdn-xxx.com/<prefix>/<projectName>/<version>/
35
+ export CDN_PUBLIC_PATH="https://cdn-portal-test.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/${VERSION}/"
36
+ echo "CDN_PUBLIC_PATH: $CDN_PUBLIC_PATH"
37
+
38
+ # 测试环境,不上传 sourcemap。调试时如有需要再解开
39
+ # # ========== Sentry Auth Token ==========
40
+ # # SENTRY_AUTH_TOKEN 从 Jenkins 服务器文件读取(敏感信息,不写在脚本中)
41
+ # SENTRY_TOKEN_FILE="/var/lib/jenkins/.portal_sentry_auth_token"
42
+ # if [ -f "$SENTRY_TOKEN_FILE" ]; then
43
+ # export SENTRY_AUTH_TOKEN=$(cat "$SENTRY_TOKEN_FILE")
44
+ # fi
45
+
46
+ # if [ -z "$SENTRY_AUTH_TOKEN" ]; then
47
+ # echo "警告:SENTRY_AUTH_TOKEN 未设置(文件 $SENTRY_TOKEN_FILE 不存在),跳过 sourcemap 上传"
48
+ # fi
49
+
50
+ pnpm run build:testing
51
+
52
+ # 只有在 CI 环境时才写入版本号文件(覆盖写入)
53
+ if [ "${CI}" = "true" ]; then
54
+ echo "VERSION=$VERSION" > .env_x_<%= projectName %>
55
+ fi
@@ -0,0 +1,19 @@
1
+ #!/bin/bash
2
+ version=$1
3
+ username="mico_fresh"
4
+ apiKey=$(cat ~/.wangsu_key)
5
+ date=`env LANG="en_US.UTF-8" date -u "+%a, %d %b %Y %H:%M:%S GMT"`
6
+ password=`echo -en "$date" | openssl dgst -sha1 -hmac $apiKey -binary | openssl enc -base64`
7
+ echo "打印刷新地址"
8
+ echo "dir1:http://cdn-portal-dev.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version/"
9
+ echo "dir2:https://cdn-portal-dev.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version/"
10
+ curl -i --url "https://open.chinanetcenter.com/ccm/purge/ItemIdReceiver" -X "POST" -u "$username:$password" -H "Date:$date" -H "Content-Type: application/json" --data-binary @- <<EOF
11
+ {
12
+ "dirs": [
13
+ "http://cdn-portal-dev.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version",
14
+ "https://cdn-portal-dev.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version"
15
+ ],
16
+ "dirAction":"expire"
17
+ }
18
+ EOF
19
+
@@ -0,0 +1,19 @@
1
+ #!/bin/bash
2
+ version=$1
3
+ username="mico_fresh"
4
+ apiKey=$(cat ~/.wangsu_key)
5
+ date=`env LANG="en_US.UTF-8" date -u "+%a, %d %b %Y %H:%M:%S GMT"`
6
+ password=`echo -en "$date" | openssl dgst -sha1 -hmac $apiKey -binary | openssl enc -base64`
7
+ echo "打印刷新地址"
8
+ echo "dir1:http://cdn-portal.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version/"
9
+ echo "dir2:https://cdn-portal.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version/"
10
+ curl -i --url "https://open.chinanetcenter.com/ccm/purge/ItemIdReceiver" -X "POST" -u "$username:$password" -H "Date:$date" -H "Content-Type: application/json" --data-binary @- <<EOF
11
+ {
12
+ "dirs": [
13
+ "http://cdn-portal.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version",
14
+ "https://cdn-portal.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version"
15
+ ],
16
+ "dirAction":"expire"
17
+ }
18
+ EOF
19
+
@@ -0,0 +1,19 @@
1
+ #!/bin/bash
2
+ version=$1
3
+ username="mico_fresh"
4
+ apiKey=$(cat ~/.wangsu_key)
5
+ date=`env LANG="en_US.UTF-8" date -u "+%a, %d %b %Y %H:%M:%S GMT"`
6
+ password=`echo -en "$date" | openssl dgst -sha1 -hmac $apiKey -binary | openssl enc -base64`
7
+ echo "打印刷新地址"
8
+ echo "dir1:http://cdn-portal-test.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version/"
9
+ echo "dir2:https://cdn-portal-test.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version/"
10
+ curl -i --url "https://open.chinanetcenter.com/ccm/purge/ItemIdReceiver" -X "POST" -u "$username:$password" -H "Date:$date" -H "Content-Type: application/json" --data-binary @- <<EOF
11
+ {
12
+ "dirs": [
13
+ "http://cdn-portal-test.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version",
14
+ "https://cdn-portal-test.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/$version"
15
+ ],
16
+ "dirAction":"expire"
17
+ }
18
+ EOF
19
+
@@ -0,0 +1,301 @@
1
+ # <%= ProjectName %>(<%= projectName %>)
2
+
3
+ 基于 **pnpm workspace** 与 **Turborepo** 的 **H5 Monorepo**:多个 [Umi 4](https://umijs.org/) 子应用、共享内部包与 ESLint 配置;根目录提供**开发网关**(按 `page.config.ts` 并行启动子应用并由单一端口反向代理)、**dev 预设**(并行启动预设列表中的应用),以及 **`pnpm dev`**(`scripts/dev.js`:在仓库根**交互式**只启动**一个**子应用,见下文)。
4
+
5
+ ## 脚手架与子应用
6
+
7
+ | 场景 | 命令 |
8
+ |------|------|
9
+ | 新建本 Monorepo,并生成**首个**子应用 | 在空目录执行 **`mico create h5-react`**;交互中会询问 **CDN 路径前缀**(可选,用于 `CICD/` 中 `CDN_PUBLIC_PATH` 等,与 `micro-react` 语义一致)、首个子应用目录名(默认 `app`)及本地 dev 端口。基座生成后会**联动** **`subapp-h5`**,不在 h5-react 模板中重复维护子应用目录。 |
10
+ | 已有本仓库,再增加子应用 | 在**仓库根目录**执行 **`mico create subapp-h5`**,可多次执行;生成器会创建 `apps/<名>/`,并更新根目录 **`page.config.ts`**、**`dev.preset.json`**(`presets.full.apps`)。 |
11
+
12
+ 约定:子应用目录名为 **kebab-case**,且 **`apps/<目录>/package.json` 的 `name` 与目录名一致**,以便 `pnpm dev:preset` 与 `pnpm --filter` 行为一致。
13
+
14
+ ## 技术栈
15
+
16
+ | 类别 | 技术 |
17
+ |------|------|
18
+ | 包管理 | [pnpm](https://pnpm.io/) workspace(根目录 `packageManager` 钉扎 **pnpm@10.18.2**,可用 [Corepack](https://nodejs.org/api/corepack.html) 对齐版本) |
19
+ | 构建编排 | [Turborepo](https://turbo.build/)(根目录 `build` / `build:development` / `build:testing` / `build:production` 与 `lint` 等走 `turbo run`;`turbo.json` 中 `dev` 任务供各包声明;根 **`pnpm dev`** 为 `scripts/dev.js`,见「根脚本说明」) |
20
+ | 应用框架 | [Umi](https://umijs.org/) **4.x**(`catalog` 见 `pnpm-workspace.yaml`) |
21
+ | 子应用配置 | **`<%= packageScope %>/umi-config`** 工厂(`createBaseConfig` / `createProConfig` / `createProductionConfig` 等):所有子应用 `config/*.ts` 都委托到此包,避免重抄基础字段(详见下文与 **`.cursor/rules/umi-config.mdc`**) |
22
+ | UI | React **18**(catalog);**`<%= packageScope %>/components`** 提供项目级 `Layout` / `ImmersiveHeader` / `LayoutFooter` 等 |
23
+ | 客户端通信 | **`<%= packageScope %>/js-bridge`**:iOS `MCAIJsBridge.post` / Android `Omigo.post`,统一 `callJSBridgeMethods<D, T>`、`getUserInfo`、`closeH5Page` 等 |
24
+ | 样式 | [Tailwind CSS](https://tailwindcss.com/) **3.x** + **`tailwindcss-safe-area`** 安全区工具类(**`subapp-h5` 模板默认接入** `@umijs/plugins`;与 Less 等可并存) |
25
+ | HTTP / 开发联调 | Umi **`@umijs/plugins/dist/request`** + **`<%= packageScope %>/request`**(统一 URL 与拦截器);开发期 **`defineMock`** + **`mock/`**,公共逻辑(**`baseUrl`** / **`tryProxy`** 远程透传 / **`validateBody`** zod 校验)来自 **`<%= packageScope %>/utils/mock`**;请求/响应类型就近定义在 **`src/services/`** 下对应模块中(约定见 **`.cursor/rules/umi-mock.mdc`**、**`.cursor/rules/workspace-request.mdc`**) |
26
+ | 监控与 Source Map | 子应用依赖 **`@common-web/sentry`**(布局 **`SentryErrorBoundary`**、生产 **`externals`**);**`<%= packageScope %>/umi-config`** 中的 `createProductionConfig` 自动注入 **`@sentry/webpack-plugin`**,在生产构建时上传 Legacy Sourcemap(需 **`SENTRY_AUTH_TOKEN`**,见下文) |
27
+ | 语言 | TypeScript 5 |
28
+ | 代码质量 | ESLint **9**(扁平 **`eslint.config.*`**、**`typescript-eslint`** + **`<%= packageScope %>/eslint`** + Prettier)、Stylelint **14**、Husky、lint-staged(**仓库根 `.lintstagedrc.js` 集中维护**)、[commitlint](https://commitlint.js.org/) |
29
+ | 格式化 | 根目录 `.prettierrc.json`;子应用通过 ESLint 的 `eslint-plugin-prettier` / `eslint-config-prettier` 与 Prettier 对齐 |
30
+ | 环境变量 | [dotenv-cli](https://github.com/entropitor/dotenv-cli);**仓库根**集中维护 `.env`、`.env.development`、`.env.testing`、`.env.production` |
31
+
32
+ ## 环境要求
33
+
34
+ - **Node.js**:建议 **22 LTS 及以上**。
35
+ - **pnpm**:与根 **`packageManager`** 一致。
36
+
37
+ ## 环境变量文件
38
+
39
+ `.env*` 集中在仓库**根目录**维护(**不要**在每个子应用下重复放)。根 `package.json` 中各脚本通过 `dotenv-cli` 按以下顺序加载(后者存在才生效):
40
+
41
+ | 命令 | 加载链 |
42
+ |------|------|
43
+ | `pnpm dev:gateway` | `.env` → `.env.local` → `.env.development` → `.env.development.local` |
44
+ | `pnpm build` / `pnpm build:production` | `.env` → `.env.local` → `.env.production` → `.env.production.local` |
45
+ | `pnpm build:development` | `.env` → `.env.local` → `.env.development` → `.env.development.local` |
46
+ | `pnpm build:testing` | `.env` → `.env.local` → `.env.testing` → `.env.testing.local` |
47
+
48
+ 模板默认提供:
49
+
50
+ - **`.env.development`**:本地开发;`UMI_APP_API_BASE_URL=/api`(配合 `createDevConfig` 的默认 `/api` 代理到测试环境)
51
+ - **`.env.testing`**:测试环境
52
+ - **`.env.production`**:生产环境
53
+
54
+ 四个环境内含 `CHECK_TIMEOUT`、`UMI_APP_API_BASE_URL`、`UMI_APP_CDN_BASE_URL`、`UMI_APP_LANG_BASE_URL`、`UMI_APP_ENV` 等变量;`UMI_APP_ENV` 用于 **`<%= packageScope %>/utils/env`** 的 `isDev` / `isTest` / `isProd` / `isDebug` 判断,与 `UMI_ENV` 共同决定运行/构建行为。
55
+
56
+ ## 快速开始
57
+
58
+ ```bash
59
+ pnpm install
60
+
61
+ # 方式一:网关(读取 page.config.ts,单端口代理多应用)
62
+ pnpm dev:gateway
63
+
64
+ # 方式二:dev 预设(并行启动预设中的应用,无统一网关端口)
65
+ pnpm dev:preset
66
+ pnpm list:preset
67
+
68
+ # 方式三:根目录交互式启动单个子应用(扫描 apps/;仅一个应用时直启,多个时终端选序号)
69
+ pnpm dev
70
+ ```
71
+
72
+ 单独开发某一子应用:
73
+
74
+ ```bash
75
+ cd apps/<子应用目录>
76
+ pnpm dev
77
+ ```
78
+
79
+ ## 目录结构(示意)
80
+
81
+ ```
82
+ .
83
+ ├── apps/ # 各 Umi 子应用(目录名 = page.config 键)
84
+ │ └── <子应用>/ # 由 h5-react / subapp-h5 生成;含 eslint.config.ts、config/(薄封装到 umi-config 工厂)、src/(含 intl、app 运行时、services/、layouts/、pages/)、mock/、Tailwind 等
85
+ ├── packages/
86
+ │ ├── common-intl/ # <%= packageScope %>/common-intl — @common-web/common-intl 的项目级封装(re-export + 预配置 init());依赖 domain、request、js-bridge
87
+ │ ├── components/ # <%= packageScope %>/components — Layout / ImmersiveHeader / LayoutFooter 等项目级 UI;依赖 js-bridge、utils
88
+ │ ├── constant/ # <%= packageScope %>/constant — 业务常量(如 MEMBER_CONSTANT),按业务域拆文件
89
+ │ ├── deeplink/ # <%= packageScope %>/deeplink — 客户端跳转链接的语义层(占位实现,按业务协议改写)
90
+ │ ├── domain/ # <%= packageScope %>/domain — 运行时/环境变量解析 API、CDN、多语言接口等基址(window.__MICO_CONFIG__ 与 UMI_APP_*)
91
+ │ ├── eslint/ # <%= packageScope %>/eslint — ESLint 9 扁平共享配置(base / react 导出)
92
+ │ ├── js-bridge/ # <%= packageScope %>/js-bridge — H5 与原生通信(callJSBridgeMethods、getUserInfo、closeH5Page 等)
93
+ │ ├── request/ # <%= packageScope %>/request — 基于 Umi `request` 的统一 HTTP 封装(拦截器、URL 与 apiBaseUrl 拼接;common-intl 的 init() 已内部绑定)
94
+ │ ├── typescript/ # <%= packageScope %>/typescript — 共享 tsconfig(base / react)
95
+ │ ├── umi-config/ # <%= packageScope %>/umi-config — 子应用 Umi 配置工厂(base / dev / prod / 各 UMI_ENV)+ Sentry 上传插件
96
+ │ └── utils/ # <%= packageScope %>/utils — 工具函数(env / url / number / date / md5 / Tailwind cn / mock baseUrl & tryProxy & validateBody 等)
97
+ ├── CICD/ # Jenkins:环境构建、CDN_PUBLIC_PATH、网宿刷新等(创建时按 cdnPrefix 生成路径)
98
+ ├── scripts/
99
+ │ ├── dev.js # 根目录 pnpm dev:选单个子应用 + dotenv + pnpm --filter
100
+ │ ├── gateway.ts # 开发网关:起子应用 + http-proxy
101
+ │ ├── dev-preset.js # 按 dev.preset.json 并行启动指定应用
102
+ │ ├── dev-preset.schema.json
103
+ │ └── collect-dist.js # 将各 apps/*/dist 汇总到根目录 dist/*(build / test 成功后执行)
104
+ ├── dev.preset.json # dev:preset 的预设
105
+ ├── page.config.ts # 网关要启动的应用(键 = apps 下文件夹名)
106
+ ├── turbo.json # Turborepo 任务:build / build:development / build:testing / build:production / dev / lint / lint:fix
107
+ ├── pnpm-workspace.yaml # workspace 范围 + catalog 版本钉扎
108
+ ├── package.json # 根包名:<%= projectName %>
109
+ ├── .env / .env.development / .env.testing / .env.production # 集中环境变量
110
+ ├── .lintstagedrc.js # 仓库根集中维护的 lint-staged 规则
111
+ ├── .prettierrc.json # Prettier 根配置
112
+ ├── .commitlintrc.js # commitlint 规则(继承 conventional)
113
+ └── README.md
114
+ ```
115
+
116
+ > **Sentry sourcemap 上传插件已迁移**到 **`packages/umi-config/src/plugins/apply-sentry-plugin.ts`**,由 `createProductionConfig` 自动调用;仓库根 `scripts/` 不再持有该文件。
117
+
118
+ ## 根脚本说明
119
+
120
+ | 命令 | 说明 |
121
+ |------|------|
122
+ | `pnpm dev:gateway` | 运行 `scripts/gateway.ts`:根据 `page.config.ts` 启动子应用并起代理;访问路径为 `/{apps 下目录名}` |
123
+ | `pnpm dev:preset` | 按 `dev.preset.json` 的默认预设(或 `pnpm dev:preset <预设名>`)并行启动指定应用;通过 `pnpm --filter <包名>` 调用各包 `dev`,并注入与根目录一致的 dotenv 文件链 |
124
+ | `pnpm list:preset` | 列出 `dev.preset.json` 中全部预设及应用列表;`pnpm dev:preset --config` 可打印配置文件路径 |
125
+ | `pnpm dev` | 运行 `scripts/dev.js`:扫描 `apps/` 下存在 `package.json` 且含 `scripts.dev` 的目录;**仅一个**时直接启动,**多个**时在终端按序号选择;经解析到的 **dotenv-cli** 加载根目录 `.env` 链后执行 `pnpm --filter <包名> run dev`。**不是** `turbo run dev` |
126
+ | `pnpm build` | `turbo run build` 成功后执行 `scripts/collect-dist.js`:`build` 任务依赖上游包的 `^build`(见 `turbo.json`),并纳入生产相关 env 作为输入;各 Umi 应用先产出 `apps/<名>/dist/**`,脚本再**移动**为根目录 `dist/<名>/`(并删除根级 `.map`,便于 CDN 部署、与 Sentry sourcemap 流程配合) |
127
+ | `pnpm build:development` | 与开发环境 CICD 对应:`UMI_ENV=development` 的各包构建 + `collect-dist`;支持可选环境变量 **`TURBO_FILTER`** 限定子包 |
128
+ | `pnpm build:testing` | 与测试环境 CICD 对应:`UMI_ENV=testing` |
129
+ | `pnpm build:production` | 与生产环境 CICD 对应:`UMI_ENV=production`(子应用 `package.json` 中默认 `build` 指向此项) |
130
+ | `pnpm lint` / `pnpm lint:fix` | `turbo run lint` / `turbo run lint:fix` |
131
+ | `pnpm lint-staged` | 供 Husky 使用,**直接调用 `lint-staged`**(读根 `.lintstagedrc.js`,**不**经过 Turborepo) |
132
+ | `pnpm prepare` | 安装 Husky(`pnpm install` 后由 pnpm 自动执行) |
133
+
134
+ ## Turborepo(`turbo.json`)要点
135
+
136
+ - **`build` / `build:development` / `build:testing` / `build:production`**:分别 `dependsOn` 自身的 **`^<同名>`**,并将根目录对应的 `.env*` 链纳入 `inputs`(如 `build:development` 会绑定 `.env`、`.env.local`、`.env.development`、`.env.development.local`);各包声明的产出为 `dist/**`(Umi 子应用即 `apps/<应用名>/dist`)。子应用 **`scripts.build`** 默认指向 `build:production`。
137
+ - **`dev`**:`persistent: true`、`cache: false`;供各包声明 `dev` 脚本时使用。根目录 **`pnpm dev` 不经过 Turborepo**,而是由 `scripts/dev.js` 只拉起**一个**子应用(见上表)。
138
+ - **`lint` / `lint:fix`**:无额外产物输出配置,便于并行检查。
139
+ - **`test`**:当前未在 `tasks` 中定义;若启用测试流水线,需补充 `test` 任务及各包脚本(见下文「常见问题」)。
140
+ - **`globalEnv`**:模板已包含 **`CDN_PUBLIC_PATH`**、**`BRANCH_OR_TAG`**、**`VERSION`**、**`SENTRY_AUTH_TOKEN`**;**`envMode: "loose"`**,避免严格模式下未声明的 env 影响开发体验。可按需追加业务变量。
141
+
142
+ ## 构建产物汇总(`scripts/collect-dist.js`)
143
+
144
+ 在 **`pnpm build`** 或 **`pnpm test`** 中 Turborepo 阶段成功结束后执行:遍历 `apps/` 下每个子目录,若存在 `apps/<名>/dist`,则将其**移动**到仓库根目录 **`dist/<名>/`**(根 `dist/` 已列入 `.gitignore`)。脚本会删除汇总目录中的 **`.map`** 文件(注释说明为配合 Sentry 上传 sourcemap、避免把 map 部署到 CDN)。**注意**:移动后原 `apps/<名>/dist` 不再存在,需重新构建才能再次得到子应用本地 `dist`。
145
+
146
+ ## 子应用 Umi 配置(委托给 `<%= packageScope %>/umi-config`)
147
+
148
+ 子应用 **`config/`** 下的所有文件都是**薄封装**,只 `import` 工厂并把业务自定义 delta 作为第二参数传入。Umi 在加载时按 `config.ts` < `config.[UMI_ENV].ts` < `config.[dev|prod].ts` < `config.[dev|prod].[UMI_ENV].ts` 顺序合并,因此本包按「基础 + 环境 delta」拆为 6 个工厂:
149
+
150
+ | 工厂 | 子应用文件 | 职责 |
151
+ |------|-----------|------|
152
+ | `createBaseConfig` | `config/config.ts` | 公共基础配置:`mountElementId`、`history`、Tailwind / request 插件、`postcss-pxtorem`、`monorepoRedirect` 等(沿用 Umi 默认 `codeSplitting`,**不**显式声明) |
153
+ | `createDevConfig` | `config/config.dev.ts` | `umi dev` delta:默认 `/api` 代理 |
154
+ | `createProConfig` | `config/config.prod.ts` | 构建公共 delta:`publicPath: 'auto'` + `cssPublicPath: './'`(运行时按 HTML 加载位置解析,与 qiankun `runtimePublicPath` 兼容)、`externals`、`chainWebpack` 关闭 `runtimeChunk`(runtime 内联进入口 `umi.js`)+ 删 `runtimePublicPath` 插件 + 把异步 chunk 命名为 `[name].[contenthash:8].async.js`。**单参**调用,不再需要 `appName` |
155
+ | `createDevelopmentConfig` | `config/config.prod.development.ts` | `UMI_ENV=development` delta(默认空,保留扩展点) |
156
+ | `createTestingConfig` | `config/config.prod.testing.ts` | `UMI_ENV=testing` delta(默认空) |
157
+ | `createProductionConfig` | `config/config.prod.production.ts` | `UMI_ENV=production` delta:`hidden-source-map` + 自动 Sentry sourcemap 上传 |
158
+
159
+ ```ts
160
+ // 示例:apps/<应用>/config/config.prod.production.ts
161
+ import { createProductionConfig } from '<%= packageScope %>/umi-config/config.prod.production';
162
+ export default createProductionConfig({ appName: '<子应用 name>' }, { /* custom delta */ });
163
+ ```
164
+
165
+ 约束与细节(含 Sentry urlPrefix、各文件职责、不要在子应用里重抄 externals 等)见 **`.cursor/rules/umi-config.mdc`**。
166
+
167
+ ## Sentry 运行时与 Source Map 上传
168
+
169
+ - **依赖**:根 **`pnpm-workspace.yaml`** 的 **`catalog`** 声明 **`@common-web/sentry`**;子应用 `package.json` 用 **`catalog:`** 引用。**`@sentry/webpack-plugin`** 安装在 **`packages/umi-config`** 的 `devDependencies`(不在仓库根,也不在子应用),由 `createProductionConfig` 自动加载。
170
+ - **运行时**:各子应用 **`src/layouts/index.tsx`** 使用 **`SentryErrorBoundary`** 包裹 **`Outlet`**。生产 **`externals`** 把 **`react`**、**`react-dom`**、**`@common-web/sentry`** 标记为 **`React` / `ReactDOM` / `CommonWebSentry`**,需与主应用或页面注入的全局变量保持一致。
171
+ - **Source Map 上传**:由 **`packages/umi-config/src/plugins/apply-sentry-plugin.ts`** 实现,在 `createProductionConfig` 的 `chainWebpack` 中自动 `apply`;使用 Legacy Sourcemap 路径(`urlPrefix` = `~/<%= cdnPrefixPath %><%= projectName %>/<version>/<appName>`,与 CICD 写出的 `CDN_PUBLIC_PATH` 一致);构建前需注入 **`SENTRY_AUTH_TOKEN`**(**`turbo.json`** 的 **`globalEnv`** 已声明)。
172
+ - **开发/生产差异**:开发使用 `createBaseConfig` 默认配置(沿用 Umi 默认 `codeSplitting`,支持动态 `import()`);构建时 `createProConfig` 关闭 `runtimeChunk`、删除 `runtimePublicPath` 插件、固定异步 chunk 命名为 `[name].[contenthash:8].async.js`——宿主页只引一个入口 JS 即可启动,按需切片仍走 webpack 5 默认的 `document.currentScript.src` 解析逻辑,与 CDN 部署兼容。
173
+
174
+ ## CI/CD(`CICD/`)
175
+
176
+ 根目录 **`CICD/`** 提供 Jenkins 流水线脚本(如 `before_build.sh`、`start_dev.sh`、`start_test.sh`、`start_prod.sh`、`start_local.sh`、`wangsu_fresh_*.sh` 等)。创建项目时 **`mico create h5-react`** 会按交互输入的 **CDN 路径前缀**(可选,对应 `.micorc` 的 `cdnPrefix`)生成脚本中的 **`CDN_PUBLIC_PATH`** 与网宿刷新路径中的占位,格式为:
177
+
178
+ `https://cdn-portal[-env].micoplatform.com/<prefix>/<projectName>/<version>/`(无前缀时省略 `<prefix>/` 段)。
179
+
180
+ 与 `micro-react` 一致:前缀用于区分不同业务线在 CDN 上的目录。
181
+
182
+ ## 子应用与网关
183
+
184
+ - **`page.config.ts`**:导出对象,**键**为 `apps/` 下的文件夹名,值为 `true` 等占位即可。新增子应用后键名由 **`mico create subapp-h5`** 写入(也可手工维护)。
185
+ - **代理**:网关从 **3000** 起探测可用端口;各子应用使用递增的本地端口(自 **4000** 起探测)。控制台会打印直连地址与经网关访问的 URL。访问网关根路径 `/` 会展示各子应用链接列表。
186
+ - **路径与 Umi**:网关将 `/{key}` 前缀**改写**后再转发到子应用,因此经网关访问使用带前缀的 URL;**单独**在某应用目录执行 `pnpm dev` 时,一般为 Umi 默认根路径 `/`。
187
+ - **路由**:**`config/routes.ts`** 模板只包含静态基础路由(如首页);注释约定动态菜单可从 **`window.__MICO_MENUS__`** 等获取,按业务自行接入。
188
+
189
+ ## dev 预设(`dev.preset.json`)
190
+
191
+ `dev.preset.json` 的 `presets.<名>.apps` 为要并行启动的包名列表(与 `apps/<目录>/package.json` 的 `name` 一致)。初始创建后 `full` 预设会包含首个子应用;后续每执行一次 **`mico create subapp-h5`** 会将新应用追加到 `full.apps`(若尚未存在)。
192
+
193
+ 若预设中 `apps` 为空,执行 `pnpm dev:preset` 会报错——请先至少创建一个子应用或编辑预设。
194
+
195
+ ## Tailwind CSS(Umi 子应用)
196
+
197
+ 由 **`mico create subapp-h5`** 生成的子应用**已默认接入** Tailwind 3 + **`tailwindcss-safe-area`**:
198
+
199
+ - `package.json` 中 `tailwindcss`、`tailwindcss-safe-area`、`@umijs/plugins` 为 **`catalog:`**
200
+ - 应用根目录含 **`tailwind.css`**(含 `@tailwind base/components/utilities`,并配置 `font-size: 16px;` 与 `1vw` 适配,与 `postcss-pxtorem` 配合做 H5 字号缩放)
201
+ - 应用根目录含 **`tailwind.config.js`**(**ESM**,扫描 `./src/**`、排除 `.umi*`,并把 **`packages/components/src`** 加入 `content`,挂 `safeAreaConfig` 插件)
202
+ - **`@umijs/plugins/dist/tailwindcss`** 与 **`tailwindcss: {}`** 由 `createBaseConfig` 默认注入,子应用 **`config/config.ts`** 不需要再写
203
+
204
+ 可直接在页面里写 Tailwind 类名,包括安全区工具类(`pt-safe`、`pb-safe-or-4`、`px-safe`、`size-safe` 等)。**`<%= packageScope %>/components`** 中 `Layout` / `ImmersiveHeader` / `LayoutFooter` 已基于这些类名实现,依赖子应用把组件包源码加入 `content`。
205
+
206
+ 手工接入或旧应用补全的步骤(含 `content` 路径、ESM 写法等)见 **`.cursor/rules/tailwind-umi.mdc`**。
207
+
208
+ ## 内部包
209
+
210
+ > 完整规则见 **`.cursor/rules/internal-packages.mdc`**;列表概览:
211
+
212
+ - **`<%= packageScope %>/utils`**:通用工具(`tailwind` 的 `cn`/`cva`/`VariantProps`、`env` 平台/环境判断、`url`、`number`、`date`、`md5`、**`mock`**:开发 mock 复用的 **`baseUrl`** + **`tryProxy`** 远程透传 + **`validateBody`** zod 入参校验),按 **`./<文件>`** 子路径直接 import。
213
+ - **`<%= packageScope %>/domain`**:导出 **`apiBaseUrl`**、**`cdnBaseUrl`**、**`langBaseUrl`** 等;优先读 **`window.__MICO_CONFIG__`**,否则回退 **`UMI_APP_API_BASE_URL`** / **`UMI_APP_CDN_BASE_URL`** / **`UMI_APP_LANG_BASE_URL`**。被 **`request`**、**`common-intl`**、**`js-bridge`** 等依赖。
214
+ - **`<%= packageScope %>/js-bridge`**:H5 ↔ 原生通信。**`canUseJSBridge`** + **`callJSBridgeMethods<D, T>(method, payload, options?)`**(处理 Android `postID` 路由 / iOS callback / Loading 防抖);常用方法子路径如 **`./getUserInfo`**、**`./closeH5Page`**。开发期 `getUserInfo` 在 `isDebug` 下可回退 fetch 远程登录接口,便于本地联调(**线上不要开放**)。
215
+ - **`<%= packageScope %>/request`**:对 Umi 运行时 **`request`** 的薄封装——统一 URL 解析(相对路径会拼 **`apiBaseUrl`**)、请求/响应拦截器、错误归一化、并发请求池。`isShowLoading` 默认 `true`,`skipRequestInterceptors` / `skipResponseInterceptors` / `rawUrl` 等选项见 **`.cursor/rules/workspace-request.mdc`**。`common-intl` 的 `init()` 内部已绑定该实例。
216
+ - **`<%= packageScope %>/common-intl`**:**`@common-web/common-intl`** 的项目级封装——re-export 上游全部 API,并提供预配置的 **`init()`**(内部使用 **`<%= packageScope %>/js-bridge` 的 `getUserInfo()`** 取语言、绑定 `request` + `langBaseUrl`)。无构建步骤,`exports` 直接指向源码 TS。详见 **`packages/common-intl/README.md`** 与 **`.cursor/rules/common-intl.mdc`**。
217
+ - **`<%= packageScope %>/components`**:项目级 UI(**`Layout`** / **`ImmersiveHeader`**(默认头:返回按钮通过 `closeH5Page` 走 JSBridge)/ **`LayoutFooter`**)。按子路径 import(如 `import Layout from '<%= packageScope %>/components/Layout'`);图片资源通过 **`./assets/*`** 导出。
218
+ - **`<%= packageScope %>/constant`**:业务常量集中地,按业务域拆文件(如 `member.ts`),`exports` 同时导出 **`.`** 与 **`./<文件>`**。
219
+ - **`<%= packageScope %>/deeplink`**:客户端跳转链接的语义层(占位实现,业务侧需按客户端 deeplink 协议改写)。
220
+ - **`<%= packageScope %>/umi-config`**:子应用 Umi 配置工厂集合(`createBaseConfig` / `createDevConfig` / `createProConfig` / `createDevelopmentConfig` / `createTestingConfig` / `createProductionConfig`)+ 内部 **`plugins/apply-sentry-plugin.ts`**。**所有子应用 `config/*.ts` 必须委托到本包**,详见 **`.cursor/rules/umi-config.mdc`**。
221
+ - **`<%= packageScope %>/eslint`**(`"type": "module"`):**`exports`**:**`.`** → `eslint.config.base.ts`(推荐 + TS + Prettier,已 ignore `mock/**`、`tailwind.config.*`、`postcss.config.*`、`src/.umi*`),**`./react`** → `eslint.config.react.ts`(再叠 React / Hooks / Refresh)。子应用在应用根目录维护 **`eslint.config.ts`**,`import` **`<%= packageScope %>/eslint/react`** 并 `defineConfig` 展开。
222
+ - **`<%= packageScope %>/typescript`**:提供 `tsconfig.base.json`、`react` 等导出;当前 Umi 子应用与 **`packages/components`** / **`packages/umi-config`** 等含 Umi 类型的包默认继承 **Umi 生成的** `./src/.umi/tsconfig.json`,纯 TS 包则 `extends "<%= packageScope %>/typescript"`。
223
+
224
+ ## 子应用:请求、多语言与 Mock(`subapp-h5` 模板约定)
225
+
226
+ 由 **`mico create subapp-h5`** 生成的子应用默认包含:
227
+
228
+ - **`config/`** 全部委托到 **`<%= packageScope %>/umi-config`**(含 `plugins`、`request: {}` 等基础字段,子应用内不重复)。
229
+ - **`src/intl.ts`**:使用 **`init({ tag, indexedDBParams })`**(`<%= packageScope %>/common-intl` 预配置封装)取得 `{ fetchMultilingualData, i18n }`,再用 **`addIntl({ ... }, i18n)`** 定义文案对象并 `export default`,同时 `export { fetchMultilingualData }`。`init()` 内部经 **`<%= packageScope %>/js-bridge` 的 `getUserInfo()`** 拿语言,并已绑定 **`<%= packageScope %>/request`** + **`langBaseUrl`**,**子应用无需再传 `requestInstance` / `lang` 等**。
230
+ - **`src/app.tsx`**:**`render`** 钩子在首屏前执行 **`fetchMultilingualData()`**,成功或失败都会 **`oldRender()`**(失败时用兜底文案)。
231
+ - **`src/layouts/index.tsx`**:用 **`SentryErrorBoundary`** 包裹 **`<Outlet />`**。
232
+ - **`src/services/<域>.ts`**:请求/响应类型 + 服务函数就近定义(与 `request<响应, 请求>(...)` 泛型、Mock 响应共用同一套类型)。
233
+ - **`mock/<域>.ts`**:从 **`<%= packageScope %>/utils/mock`** 引入 **`baseUrl`** / **`tryProxy`** / **`validateBody`**,统一 mock 路径键、referer 透传与入参校验逻辑;入参用 **zod** schema + `validateBody(req.body, schema, res)`,响应用 **mockjs** 占位。约定见 **`.cursor/rules/umi-mock.mdc`**。
234
+
235
+ 微前端场景下仍可按 **`packages/common-intl/README.md`**:主应用初始化后子应用只读共享文案;独立 H5 子应用则以 **`@/intl`** 为业务入口。
236
+
237
+ ## ESLint / Stylelint / Prettier
238
+
239
+ - **ESLint**:子应用 **`package.json`** 的 `lint` / `lint:fix` 为 **`eslint`** / **`eslint --fix`** 与 **stylelint** 组合(见各应用脚本);配置为应用根目录 **`eslint.config.ts`**(flat config),继承 workspace **`<%= packageScope %>/eslint/react`**。各内部包同样在自身根目录维护 **`eslint.config.ts`**(继承 **`<%= packageScope %>/eslint`** 或 **`/react`**)。版本由根 **`pnpm-workspace.yaml`** 的 **`catalog.eslint`**(**^9**)钉扎。
240
+ - **Stylelint**:子应用 **`.stylelintrc.js`** 继承 **`umi/stylelint`**,与 `lint` 脚本中的 stylelint 命令一致;`packages/*` 不跑 stylelint。
241
+ - **Prettier**:由共享 ESLint 配置中的 **`eslint-plugin-prettier` / `eslint-config-prettier`** 与根 **`.prettierrc.json`** 对齐。
242
+ - 根目录 **`pnpm lint`** 通过 Turborepo 调度各子应用 / 内部包的 `lint` 脚本;**`pnpm lint-staged`** 走根 `.lintstagedrc.js`,命中文件按 **`v10_config_lookup_from_file`** 解析最近的 flat config。
243
+
244
+ ## Git 钩子
245
+
246
+ - **Husky**:根目录 `package.json` 已配置 **`"prepare": "husky"`**,在 **`pnpm install`** 时会安装钩子。新克隆仓库后务必先执行一次 `pnpm install`。
247
+ - **pre-commit**(`.husky/pre-commit`):提交前执行 `pnpm run lint-staged`,再 `git add .` 把格式化结果重新暂存。
248
+ - **commit-msg**(`.husky/commit-msg`):通过 `pnpm exec commitlint --edit` 校验提交说明;规则见根目录 **`.commitlintrc.js`**。
249
+ - **lint-staged**:**统一在仓库根 `.lintstagedrc.js`**(CommonJS)维护:
250
+ - `apps/*/**/*.{js,jsx,ts,tsx}` → `eslint --flag v10_config_lookup_from_file --fix`
251
+ - `apps/*/**/*.{css,less}` → `stylelint --fix`
252
+ - `packages/!(eslint)/**/*.{js,jsx,ts,tsx}` → `eslint --flag v10_config_lookup_from_file --fix`
253
+ - **不再**在每个 `packages/<x>/` 下放 `.lintstagedrc`,新增包/应用直接被根 glob 命中。
254
+
255
+ 使用 `git commit --no-verify` 会跳过上述校验。
256
+
257
+ ## Cursor 规则(`.cursor/rules/`)
258
+
259
+ 仓库内预置 **`.mdc`** 规则,便于编辑器与协作时对齐约定:
260
+
261
+ - **`monorepo`**:总览(目录、scripts、env、catalog 等)
262
+ - **`umi-app`**:子应用 TS / ESLint / 委托 `umi-config` 工厂的写法
263
+ - **`umi-config`**:子应用配置工厂(`createBaseConfig` / ... / `createProductionConfig`)与 Sentry 接入
264
+ - **`umi-mock`**:Mock + `<%= packageScope %>/utils/mock`(`baseUrl` / `tryProxy` / `validateBody`)+ 与 `src/services/` 类型对齐
265
+ - **`workspace-request`**:**`<%= packageScope %>/request`** API 与拦截器
266
+ - **`common-intl`**:**`<%= packageScope %>/common-intl`** 与 `init()`(含 `js-bridge.getUserInfo` 取语言)
267
+ - **`tailwind-umi`**:Tailwind 3 + `tailwindcss-safe-area` + 与 `<%= packageScope %>/components` 配合
268
+ - **`internal-packages`**:所有 `packages/*` 的命名空间、exports、依赖关系
269
+ - **`package-json`**:`workspace:^` / `catalog:` / 根脚本 / lint-staged
270
+ - **`cicd-deploy`**:Jenkins、CDN、Sentry 注意事项
271
+ - **`git-hooks`**:Husky / 根目录 `.lintstagedrc.js` / commitlint
272
+
273
+ 修改 **配置工厂、Mock、请求封装、多语言、Tailwind、JSBridge** 等公共能力时,优先打开对应规则对照。
274
+
275
+ ## 配置要点
276
+
277
+ - **`.npmrc`**:可按团队需要配置 **scope 级 registry**(例如 **`@common-web`**),请勿将令牌提交到公开仓库;模板默认指向自建 nexus 仓库与 `package-lock=false`。
278
+ - **根 `package.json`**:装 **ESLint、Stylelint**(catalog)、**`@types/http-proxy`**、**`@types/mockjs`**、**`http-proxy`**、**`mockjs`**、**`zod`**、**`portfinder`**、**`chalk`**、**`dotenv-cli`**、**`turbo`**、**`prettier`** 等,供 Turborepo / Mock / Gateway 等使用;子应用通过 `catalog:` 与 workspace 对齐版本。
279
+ - **`@sentry/webpack-plugin`** 安装在 **`packages/umi-config`** 的 `devDependencies`(不在仓库根、不在子应用),保持 Sentry 上传逻辑闭环。
280
+ - **`pnpm.overrides`**:固定 `eslint: catalog:` 与 `jiti: ^2`;`peerDependencyRules.allowedVersions` 放行 `eslint@9` / `react@18` / `react-dom@18`,避免 ESLint 9 / React 18 在子包间出现冲突的 peer 警告。
281
+
282
+ ## 常见问题
283
+
284
+ 1. **网关 404**
285
+ 检查 `page.config.ts` 是否包含对应键,且 `apps/<键>` 存在有效 `package.json`。
286
+
287
+ 2. **`pnpm dev` 与 `pnpm dev:gateway` / `pnpm dev:preset` 区别**
288
+ 根目录 **`pnpm dev`** 只启动**一个**子应用(`scripts/dev.js`,交互或自动选定);**`pnpm dev:gateway`** 按 **`page.config.ts`** 拉起**全部**已配置键对应的应用并走统一代理;**`pnpm dev:preset`** 按 **`dev.preset.json`** 并行启动预设里的应用列表(无网关)。若需要「Turbo 并行 dev 多个包」,需在根 `package.json` 自行增加脚本(例如 `turbo run dev`),默认模板未将根 `pnpm dev` 绑定到 Turborepo。
289
+
290
+ 3. **`pnpm test` 失败**
291
+ 需在 `turbo.json` 与各包中补齐 `test` 任务与脚本。
292
+
293
+ 4. **Windows**
294
+ `gateway.ts` 子进程在 Windows 上使用 `shell: true`。
295
+
296
+ 5. **子进程 stderr 中的 Rebuilding…**
297
+ 多为 Tailwind 等工具进度输出,一般不是错误。
298
+
299
+ ---
300
+
301
+ 维护者可根据团队规范补充部署、分支策略与发布流程等。
@@ -0,0 +1,30 @@
1
+ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2
+
3
+ # dependencies
4
+ node_modules
5
+ .umirc.local.ts
6
+ config/config.local.ts
7
+ **/src/.umi
8
+ **/src/.umi-production
9
+ **/src/.umi-test
10
+ dist
11
+ .swc
12
+
13
+ # misc
14
+ .DS_Store
15
+ *.pem
16
+
17
+ # debug
18
+ npm-debug.log*
19
+ yarn-debug.log*
20
+ yarn-error.log*
21
+ .pnpm-debug.log*
22
+
23
+ # env files
24
+ .env.local
25
+ .env.*.local
26
+
27
+
28
+ # Turborepo cache
29
+ .turbo
30
+ .turbopack
@@ -0,0 +1,6 @@
1
+ registry=https://registry.npmjs.com/
2
+ @mico-platform:registry=https://nexus-vywrajy.micoworld.net/repository/mico-base-common/
3
+ @common-web:registry=https://nexus-vywrajy.micoworld.net/repository/mico-base-common/
4
+ link-workspace-packages=true
5
+ //nexus-vywrajy.micoworld.net/repository/mico-base-common/:_auth=bWljby1ucG06SDR4WUROazdad1NeczltblJMTw==
6
+
File without changes
@@ -0,0 +1,10 @@
1
+ {
2
+ "$schema": "./scripts/dev-preset.schema.json",
3
+ "presets": {
4
+ "full": {
5
+ "description": "启动所有应用",
6
+ "apps": []
7
+ }
8
+ },
9
+ "default": "full"
10
+ }