@4399ywkf/cli 1.0.7 → 1.0.9

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 (254) hide show
  1. package/dist/templates/AntdStaticMethods/index.tsx +20 -0
  2. package/dist/templates/AppTheme.tsx +136 -0
  3. package/dist/templates/DIRECTORY_STRUCTURE.md +141 -0
  4. package/dist/templates/GlobalProvider/AppTheme.tsx +136 -0
  5. package/dist/templates/GlobalProvider/Locale.tsx +84 -0
  6. package/dist/templates/GlobalProvider/Query.tsx +12 -0
  7. package/dist/templates/GlobalProvider/StyleRegistry.tsx +9 -0
  8. package/dist/templates/GlobalProvider/index.tsx +23 -0
  9. package/dist/templates/HarmonyOS_Sans_Bold.woff2 +0 -0
  10. package/dist/templates/HarmonyOS_Sans_Medium.woff2 +0 -0
  11. package/dist/templates/HarmonyOS_Sans_Regular.woff2 +0 -0
  12. package/dist/templates/Locale.tsx +49 -54
  13. package/dist/templates/MainContentWrap.tsx +11 -15
  14. package/dist/templates/Query.tsx +12 -0
  15. package/dist/templates/StyleRegistry.tsx +9 -0
  16. package/dist/templates/ThemeContext.tsx +27 -24
  17. package/dist/templates/analyzeUnusedKeys.ts +506 -0
  18. package/dist/templates/app/.i18nrc.js +57 -0
  19. package/dist/templates/app/config/env/.env.public.tpl +2 -19
  20. package/dist/templates/app/config/jwt/index.ts +4 -4
  21. package/dist/templates/app/config/request/error-handler.ts +67 -0
  22. package/dist/templates/app/config/request/index.ts +127 -129
  23. package/dist/templates/app/config/request/interceptors.ts +118 -0
  24. package/dist/templates/app/config/request/token-manager.ts +23 -0
  25. package/dist/templates/app/config/request/types.ts +63 -0
  26. package/dist/templates/app/config/rspack/rspack.config.mjs +62 -61
  27. package/dist/templates/app/config/rspack/rspack.prod.mjs +41 -62
  28. package/dist/templates/app/docs/DIRECTORY_STRUCTURE.md +141 -0
  29. package/dist/templates/app/docs/glossary.md +11 -0
  30. package/dist/templates/app/locales/zh-CN/common.json +3 -0
  31. package/dist/templates/app/package.json.tpl +8 -25
  32. package/dist/templates/app/public/fonts/HarmonyOS_Sans_Bold.woff2 +0 -0
  33. package/dist/templates/app/public/fonts/HarmonyOS_Sans_Medium.woff2 +0 -0
  34. package/dist/templates/app/public/fonts/HarmonyOS_Sans_Regular.woff2 +0 -0
  35. package/dist/templates/app/react-app-env.d.ts +13 -8
  36. package/dist/templates/app/scripts/i18nWorkflow/analyzeUnusedKeys.ts +506 -0
  37. package/dist/templates/app/scripts/i18nWorkflow/cleanUnusedKeys.ts +344 -0
  38. package/dist/templates/app/scripts/i18nWorkflow/const.ts +18 -0
  39. package/dist/templates/app/scripts/i18nWorkflow/flattenLocaleKeys.ts +139 -0
  40. package/dist/templates/app/scripts/i18nWorkflow/genDefaultLocale.ts +19 -0
  41. package/dist/templates/app/scripts/i18nWorkflow/genDiff.ts +49 -0
  42. package/dist/templates/app/scripts/i18nWorkflow/i18nConfig.ts +7 -0
  43. package/dist/templates/app/scripts/i18nWorkflow/index.ts +11 -0
  44. package/dist/templates/app/scripts/i18nWorkflow/protectedPatterns.ts +91 -0
  45. package/dist/templates/app/scripts/i18nWorkflow/utils.ts +76 -0
  46. package/dist/templates/app/src/bootstrap/index.ts +34 -0
  47. package/dist/templates/app/src/components/AntdStaticMethods/index.tsx +20 -0
  48. package/dist/templates/app/src/config/env.ts +84 -0
  49. package/dist/templates/app/src/index.tsx +13 -51
  50. package/dist/templates/app/src/layout/GlobalProvider/AppTheme.tsx +136 -0
  51. package/dist/templates/app/src/layout/GlobalProvider/Locale.tsx +84 -0
  52. package/dist/templates/app/src/layout/GlobalProvider/Query.tsx +12 -0
  53. package/dist/templates/app/src/layout/GlobalProvider/StyleRegistry.tsx +9 -0
  54. package/dist/templates/app/src/layout/GlobalProvider/index.tsx +23 -0
  55. package/dist/templates/app/src/layout/Locale.tsx +14 -18
  56. package/dist/templates/app/src/layout/MainContentWrap.tsx +11 -15
  57. package/dist/templates/app/src/layout/ThemeContext.tsx +27 -24
  58. package/dist/templates/app/src/locales/default/common.ts +3 -1
  59. package/dist/templates/app/src/locales/utils.ts +23 -0
  60. package/dist/templates/app/src/micro/garfish.ts +53 -0
  61. package/dist/templates/app/src/pages/base/index.tsx +280 -25
  62. package/dist/templates/app/src/routes.tsx +21 -12
  63. package/dist/templates/app/src/types/global.d.ts +19 -0
  64. package/dist/templates/app/src/utils/index.ts +3 -1
  65. package/dist/templates/app/store/middleware/createDevtools.ts +7 -7
  66. package/dist/templates/app/tsconfig.json +19 -3
  67. package/dist/templates/base/index.tsx +280 -25
  68. package/dist/templates/bootstrap/index.ts +34 -0
  69. package/dist/templates/cleanUnusedKeys.ts +344 -0
  70. package/dist/templates/common.json +3 -0
  71. package/dist/templates/common.ts +3 -1
  72. package/dist/templates/components/AntdStaticMethods/index.tsx +20 -0
  73. package/dist/templates/config/env/.env.public.tpl +2 -19
  74. package/dist/templates/config/env.ts +84 -0
  75. package/dist/templates/config/jwt/index.ts +4 -4
  76. package/dist/templates/config/request/error-handler.ts +67 -0
  77. package/dist/templates/config/request/index.ts +127 -129
  78. package/dist/templates/config/request/interceptors.ts +118 -0
  79. package/dist/templates/config/request/token-manager.ts +23 -0
  80. package/dist/templates/config/request/types.ts +63 -0
  81. package/dist/templates/config/rspack/rspack.config.mjs +62 -61
  82. package/dist/templates/config/rspack/rspack.prod.mjs +41 -62
  83. package/dist/templates/const.ts +18 -0
  84. package/dist/templates/createDevtools.ts +7 -7
  85. package/dist/templates/default/common.ts +3 -1
  86. package/dist/templates/docs/DIRECTORY_STRUCTURE.md +141 -0
  87. package/dist/templates/docs/glossary.md +11 -0
  88. package/dist/templates/env/.env.public.tpl +2 -19
  89. package/dist/templates/env.ts +83 -2
  90. package/dist/templates/error-handler.ts +67 -0
  91. package/dist/templates/flattenLocaleKeys.ts +139 -0
  92. package/dist/templates/fonts/HarmonyOS_Sans_Bold.woff2 +0 -0
  93. package/dist/templates/fonts/HarmonyOS_Sans_Medium.woff2 +0 -0
  94. package/dist/templates/fonts/HarmonyOS_Sans_Regular.woff2 +0 -0
  95. package/dist/templates/garfish.ts +53 -0
  96. package/dist/templates/genDefaultLocale.ts +19 -0
  97. package/dist/templates/genDiff.ts +49 -0
  98. package/dist/templates/global.d.ts +19 -0
  99. package/dist/templates/glossary.md +11 -0
  100. package/dist/templates/i18nConfig.ts +7 -0
  101. package/dist/templates/i18nWorkflow/analyzeUnusedKeys.ts +506 -0
  102. package/dist/templates/i18nWorkflow/cleanUnusedKeys.ts +344 -0
  103. package/dist/templates/i18nWorkflow/const.ts +18 -0
  104. package/dist/templates/i18nWorkflow/flattenLocaleKeys.ts +139 -0
  105. package/dist/templates/i18nWorkflow/genDefaultLocale.ts +19 -0
  106. package/dist/templates/i18nWorkflow/genDiff.ts +49 -0
  107. package/dist/templates/i18nWorkflow/i18nConfig.ts +7 -0
  108. package/dist/templates/i18nWorkflow/index.ts +11 -0
  109. package/dist/templates/i18nWorkflow/protectedPatterns.ts +91 -0
  110. package/dist/templates/i18nWorkflow/utils.ts +76 -0
  111. package/dist/templates/index.tsx +280 -25
  112. package/dist/templates/interceptors.ts +118 -0
  113. package/dist/templates/jwt/index.ts +4 -4
  114. package/dist/templates/layout/GlobalProvider/AppTheme.tsx +136 -0
  115. package/dist/templates/layout/GlobalProvider/Locale.tsx +84 -0
  116. package/dist/templates/layout/GlobalProvider/Query.tsx +12 -0
  117. package/dist/templates/layout/GlobalProvider/StyleRegistry.tsx +9 -0
  118. package/dist/templates/layout/GlobalProvider/index.tsx +23 -0
  119. package/dist/templates/layout/Locale.tsx +14 -18
  120. package/dist/templates/layout/MainContentWrap.tsx +11 -15
  121. package/dist/templates/layout/ThemeContext.tsx +27 -24
  122. package/dist/templates/locales/default/common.ts +3 -1
  123. package/dist/templates/locales/utils.ts +23 -0
  124. package/dist/templates/locales/zh-CN/common.json +3 -0
  125. package/dist/templates/micro/garfish.ts +53 -0
  126. package/dist/templates/middleware/createDevtools.ts +7 -7
  127. package/dist/templates/package.json.tpl +8 -25
  128. package/dist/templates/page.tsx +21 -19
  129. package/dist/templates/pages/base/index.tsx +280 -25
  130. package/dist/templates/protectedPatterns.ts +91 -0
  131. package/dist/templates/public/fonts/HarmonyOS_Sans_Bold.woff2 +0 -0
  132. package/dist/templates/public/fonts/HarmonyOS_Sans_Medium.woff2 +0 -0
  133. package/dist/templates/public/fonts/HarmonyOS_Sans_Regular.woff2 +0 -0
  134. package/dist/templates/react-app-env.d.ts +13 -8
  135. package/dist/templates/request/error-handler.ts +67 -0
  136. package/dist/templates/request/index.ts +127 -129
  137. package/dist/templates/request/interceptors.ts +118 -0
  138. package/dist/templates/request/token-manager.ts +23 -0
  139. package/dist/templates/request/types.ts +63 -0
  140. package/dist/templates/routes.tsx +21 -12
  141. package/dist/templates/rspack/rspack.config.mjs +62 -61
  142. package/dist/templates/rspack/rspack.prod.mjs +41 -62
  143. package/dist/templates/rspack.config.mjs +62 -61
  144. package/dist/templates/rspack.prod.mjs +41 -62
  145. package/dist/templates/scripts/i18nWorkflow/analyzeUnusedKeys.ts +506 -0
  146. package/dist/templates/scripts/i18nWorkflow/cleanUnusedKeys.ts +344 -0
  147. package/dist/templates/scripts/i18nWorkflow/const.ts +18 -0
  148. package/dist/templates/scripts/i18nWorkflow/flattenLocaleKeys.ts +139 -0
  149. package/dist/templates/scripts/i18nWorkflow/genDefaultLocale.ts +19 -0
  150. package/dist/templates/scripts/i18nWorkflow/genDiff.ts +49 -0
  151. package/dist/templates/scripts/i18nWorkflow/i18nConfig.ts +7 -0
  152. package/dist/templates/scripts/i18nWorkflow/index.ts +11 -0
  153. package/dist/templates/scripts/i18nWorkflow/protectedPatterns.ts +91 -0
  154. package/dist/templates/scripts/i18nWorkflow/utils.ts +76 -0
  155. package/dist/templates/src/bootstrap/index.ts +34 -0
  156. package/dist/templates/src/components/AntdStaticMethods/index.tsx +20 -0
  157. package/dist/templates/src/config/env.ts +84 -0
  158. package/dist/templates/src/index.tsx +13 -51
  159. package/dist/templates/src/layout/GlobalProvider/AppTheme.tsx +136 -0
  160. package/dist/templates/src/layout/GlobalProvider/Locale.tsx +84 -0
  161. package/dist/templates/src/layout/GlobalProvider/Query.tsx +12 -0
  162. package/dist/templates/src/layout/GlobalProvider/StyleRegistry.tsx +9 -0
  163. package/dist/templates/src/layout/GlobalProvider/index.tsx +23 -0
  164. package/dist/templates/src/layout/Locale.tsx +14 -18
  165. package/dist/templates/src/layout/MainContentWrap.tsx +11 -15
  166. package/dist/templates/src/layout/ThemeContext.tsx +27 -24
  167. package/dist/templates/src/locales/default/common.ts +3 -1
  168. package/dist/templates/src/locales/utils.ts +23 -0
  169. package/dist/templates/src/micro/garfish.ts +53 -0
  170. package/dist/templates/src/pages/base/index.tsx +280 -25
  171. package/dist/templates/src/routes.tsx +21 -12
  172. package/dist/templates/src/types/global.d.ts +19 -0
  173. package/dist/templates/src/utils/index.ts +3 -1
  174. package/dist/templates/store/middleware/createDevtools.ts +7 -7
  175. package/dist/templates/token-manager.ts +23 -0
  176. package/dist/templates/tsconfig.json +19 -3
  177. package/dist/templates/type.ts +23 -24
  178. package/dist/templates/types/global.d.ts +19 -0
  179. package/dist/templates/utils/index.ts +3 -1
  180. package/dist/templates/utils.ts +23 -0
  181. package/dist/templates/zh-CN/common.json +3 -0
  182. package/package.json +19 -21
  183. package/dist/templates/app/config/sentry/sentry.config.ts +0 -188
  184. package/dist/templates/app/src/hooks/useRouteTitle.tsx +0 -36
  185. package/dist/templates/app/src/hooks/useSentry.ts +0 -92
  186. package/dist/templates/app/src/pages/base/layout.tsx +0 -6
  187. package/dist/templates/app/src/pages/base/page.tsx +0 -25
  188. package/dist/templates/app/src/utils/env.ts +0 -3
  189. package/dist/templates/app/src/utils/format.ts +0 -21
  190. package/dist/templates/app/src/utils/getMicroApp.ts +0 -39
  191. package/dist/templates/app/src/utils/sentry.ts +0 -187
  192. package/dist/templates/app/src/utils/sentryDecorators.ts +0 -34
  193. package/dist/templates/app/src/utils/updateVersion.ts +0 -186
  194. package/dist/templates/base/layout.tsx +0 -6
  195. package/dist/templates/base/page.tsx +0 -25
  196. package/dist/templates/config/public/404.png +0 -0
  197. package/dist/templates/config/public/favicon.ico +0 -0
  198. package/dist/templates/config/public/images/banner_market_modal.webp +0 -0
  199. package/dist/templates/config/public/images/chatmode_chat_dark.webp +0 -0
  200. package/dist/templates/config/public/images/chatmode_chat_light.webp +0 -0
  201. package/dist/templates/config/public/images/chatmode_docs_dark.webp +0 -0
  202. package/dist/templates/config/public/images/chatmode_docs_light.webp +0 -0
  203. package/dist/templates/config/public/images/empty_topic_dark.webp +0 -0
  204. package/dist/templates/config/public/images/empty_topic_light.webp +0 -0
  205. package/dist/templates/config/public/images/screenshot_background.webp +0 -0
  206. package/dist/templates/config/public/images/theme_auto.webp +0 -0
  207. package/dist/templates/config/public/images/theme_dark.webp +0 -0
  208. package/dist/templates/config/public/images/theme_light.webp +0 -0
  209. package/dist/templates/config/public/index.html +0 -29
  210. package/dist/templates/config/sentry/sentry.config.ts +0 -188
  211. package/dist/templates/format.ts +0 -21
  212. package/dist/templates/getMicroApp.ts +0 -39
  213. package/dist/templates/hooks/useRouteTitle.tsx +0 -36
  214. package/dist/templates/hooks/useSentry.ts +0 -92
  215. package/dist/templates/layout.tsx +0 -6
  216. package/dist/templates/pages/base/layout.tsx +0 -6
  217. package/dist/templates/pages/base/page.tsx +0 -25
  218. package/dist/templates/sentry/sentry.config.ts +0 -188
  219. package/dist/templates/sentry.config.ts +0 -188
  220. package/dist/templates/sentry.ts +0 -187
  221. package/dist/templates/sentryDecorators.ts +0 -34
  222. package/dist/templates/src/hooks/useRouteTitle.tsx +0 -36
  223. package/dist/templates/src/hooks/useSentry.ts +0 -92
  224. package/dist/templates/src/pages/base/layout.tsx +0 -6
  225. package/dist/templates/src/pages/base/page.tsx +0 -25
  226. package/dist/templates/src/utils/env.ts +0 -3
  227. package/dist/templates/src/utils/format.ts +0 -21
  228. package/dist/templates/src/utils/getMicroApp.ts +0 -39
  229. package/dist/templates/src/utils/sentry.ts +0 -187
  230. package/dist/templates/src/utils/sentryDecorators.ts +0 -34
  231. package/dist/templates/src/utils/updateVersion.ts +0 -186
  232. package/dist/templates/updateVersion.ts +0 -186
  233. package/dist/templates/useRouteTitle.tsx +0 -36
  234. package/dist/templates/useSentry.ts +0 -92
  235. package/dist/templates/utils/env.ts +0 -3
  236. package/dist/templates/utils/format.ts +0 -21
  237. package/dist/templates/utils/getMicroApp.ts +0 -39
  238. package/dist/templates/utils/sentry.ts +0 -187
  239. package/dist/templates/utils/sentryDecorators.ts +0 -34
  240. package/dist/templates/utils/updateVersion.ts +0 -186
  241. /package/dist/templates/app/{config/public → public}/404.png +0 -0
  242. /package/dist/templates/app/{config/public → public}/favicon.ico +0 -0
  243. /package/dist/templates/app/{config/public → public}/images/banner_market_modal.webp +0 -0
  244. /package/dist/templates/app/{config/public → public}/images/chatmode_chat_dark.webp +0 -0
  245. /package/dist/templates/app/{config/public → public}/images/chatmode_chat_light.webp +0 -0
  246. /package/dist/templates/app/{config/public → public}/images/chatmode_docs_dark.webp +0 -0
  247. /package/dist/templates/app/{config/public → public}/images/chatmode_docs_light.webp +0 -0
  248. /package/dist/templates/app/{config/public → public}/images/empty_topic_dark.webp +0 -0
  249. /package/dist/templates/app/{config/public → public}/images/empty_topic_light.webp +0 -0
  250. /package/dist/templates/app/{config/public → public}/images/screenshot_background.webp +0 -0
  251. /package/dist/templates/app/{config/public → public}/images/theme_auto.webp +0 -0
  252. /package/dist/templates/app/{config/public → public}/images/theme_dark.webp +0 -0
  253. /package/dist/templates/app/{config/public → public}/images/theme_light.webp +0 -0
  254. /package/dist/templates/app/{config/public → public}/index.html +0 -0
@@ -0,0 +1,76 @@
1
+ import { consola } from "consola";
2
+ import { colors } from "consola/utils";
3
+ import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
4
+ import { resolve, dirname } from "node:path";
5
+ import prettier from "@prettier/sync";
6
+ import i18nConfig from "./i18nConfig";
7
+
8
+ let prettierOptions = prettier.resolveConfig(
9
+ resolve(__dirname, "../../.prettierrc.js"),
10
+ );
11
+
12
+ export const readJSON = (filePath: string) => {
13
+ const data = readFileSync(filePath, "utf8");
14
+ return JSON.parse(data);
15
+ };
16
+
17
+ export const writeJSON = (filePath: string, data: any) => {
18
+ const jsonStr = JSON.stringify(data, null, 2);
19
+ writeFileSync(filePath, jsonStr, "utf8");
20
+ };
21
+
22
+ export const writeJSONWithPrettier = (filePath: string, data: any) => {
23
+ mkdirSync(dirname(filePath), { recursive: true });
24
+ const jsonStr = JSON.stringify(data, null, 2);
25
+ const formatted = prettier.format(jsonStr, {
26
+ ...prettierOptions,
27
+ parser: "json",
28
+ });
29
+ writeFileSync(filePath, formatted, "utf8");
30
+ };
31
+
32
+ export const genResourcesContent = (locales: string[]) => {
33
+ let index = "";
34
+ let indexObj = "";
35
+
36
+ for (const locale of locales) {
37
+ index += `import ${locale} from "./${locale}";\n`;
38
+ indexObj += ` "${locale.replace("_", "-")}": ${locale},\n`;
39
+ }
40
+
41
+ return `${index}
42
+ const resources = {
43
+ ${indexObj}} as const;
44
+ export default resources;
45
+ export const defaultResources = ${i18nConfig.entryLocale};
46
+ export type Resources = typeof resources;
47
+ export type DefaultResources = typeof defaultResources;
48
+ export type Namespaces = keyof DefaultResources;
49
+ export type Locales = keyof Resources;
50
+ `;
51
+ };
52
+
53
+ export const genNamespaceList = (files: string[], locale: string) => {
54
+ return files.map((file) => ({
55
+ name: file.replace(".json", ""),
56
+ path: resolve(i18nConfig.output, locale, file),
57
+ }));
58
+ };
59
+
60
+ export const tagBlue = (text: string) =>
61
+ colors.bgBlueBright(colors.black(` ${text} `));
62
+ export const tagYellow = (text: string) =>
63
+ colors.bgYellowBright(colors.black(` ${text} `));
64
+ export const tagGreen = (text: string) =>
65
+ colors.bgGreenBright(colors.black(` ${text} `));
66
+ export const tagWhite = (text: string) =>
67
+ colors.bgWhiteBright(colors.black(` ${text} `));
68
+
69
+ export const split = (name: string) => {
70
+ consola.log("");
71
+ consola.log(
72
+ colors.gray(
73
+ `========================== ${name} ==============================`,
74
+ ),
75
+ );
76
+ };
@@ -0,0 +1,34 @@
1
+ import "dayjs/locale/zh-cn";
2
+ import dayjs from "dayjs";
3
+ import { ConfigProvider } from "antd";
4
+ import { env } from "@/config/env";
5
+
6
+ interface BootstrapConfig {
7
+ appName: string;
8
+ }
9
+
10
+ /**
11
+ * 应用启动前的初始化配置
12
+ */
13
+ export function bootstrap(config: BootstrapConfig) {
14
+ const { appName } = config;
15
+
16
+ // 配置 dayjs 国际化
17
+ dayjs.locale("zh-cn");
18
+
19
+ // 配置 antd 静态方法的前缀
20
+ ConfigProvider.config({
21
+ prefixCls: appName,
22
+ });
23
+
24
+ console.log(`✅ Application [${appName}] bootstrapped successfully`);
25
+ }
26
+
27
+ /**
28
+ * 使用环境变量初始化应用
29
+ */
30
+ export function bootstrapWithEnv() {
31
+ bootstrap({
32
+ appName: env.APP_NAME,
33
+ });
34
+ }
@@ -0,0 +1,20 @@
1
+ // Entry component
2
+ import { App } from 'antd';
3
+ import type { MessageInstance } from 'antd/es/message/interface';
4
+ import type { ModalStaticFunctions } from 'antd/es/modal/confirm';
5
+ import type { NotificationInstance } from 'antd/es/notification/interface';
6
+ import { memo } from 'react';
7
+
8
+ let message: MessageInstance;
9
+ let notification: NotificationInstance;
10
+ let modal: Omit<ModalStaticFunctions, 'warn'>;
11
+
12
+ export default memo(() => {
13
+ const staticFunction = App.useApp();
14
+ message = staticFunction.message;
15
+ modal = staticFunction.modal;
16
+ notification = staticFunction.notification;
17
+ return null;
18
+ });
19
+
20
+ export { message, modal, notification };
@@ -0,0 +1,84 @@
1
+ import { z } from "zod";
2
+
3
+ /**
4
+ * 环境变量 Schema 定义
5
+ */
6
+ const envSchema = z.object({
7
+ // Node 环境
8
+ NODE_ENV: z
9
+ .enum(["development", "test", "testDevelopment", "production"])
10
+ .default("development"),
11
+
12
+ // 应用配置
13
+ APP_NAME: z.string().min(1, "应用名称不能为空").default("app"),
14
+ APP_CNAME: z.string().default("应用"),
15
+ BASENAME: z.string().optional(),
16
+
17
+ // API 配置
18
+ API_PREFIX: z.string().default("/api"),
19
+ API_TIMEOUT: z
20
+ .string()
21
+ .transform(Number)
22
+ .pipe(z.number().positive())
23
+ .default(30000),
24
+
25
+ // Cookie 配置
26
+ COOKIE_NAME: z.string().default("access_token"),
27
+
28
+ // 其他配置
29
+ HELP_CENTER_URL: z.string().url().optional(),
30
+ OUTPUT_PATH: z.string().default("dist"),
31
+ PUBLIC_PATH: z.string().default("/"),
32
+ });
33
+
34
+ /**
35
+ * 安全解析环境变量(开发模式下使用默认值)
36
+ */
37
+ function safeParseEnv() {
38
+ const result = envSchema.safeParse(process.env);
39
+
40
+ if (!result.success) {
41
+ if (process.env.NODE_ENV === "production") {
42
+ // 生产环境严格校验
43
+ console.error("❌ 环境变量验证失败:");
44
+ result.error.issues.forEach((err) => {
45
+ console.error(` - ${err.path.join(".")}: ${err.message}`);
46
+ });
47
+ throw new Error("环境变量配置错误");
48
+ } else {
49
+ // 开发环境警告但不中断
50
+ console.warn("⚠️ 环境变量验证警告:");
51
+ result.error.issues.forEach((err) => {
52
+ console.warn(` - ${err.path.join(".")}: ${err.message}`);
53
+ });
54
+ }
55
+ }
56
+
57
+ return result.success ? result.data : envSchema.parse({});
58
+ }
59
+
60
+ /**
61
+ * 导出类型安全的环境变量
62
+ */
63
+ export const env = safeParseEnv();
64
+
65
+ /**
66
+ * 环境变量类型
67
+ */
68
+ export type Env = z.infer<typeof envSchema>;
69
+
70
+ /**
71
+ * 工具函数:判断是否为开发环境
72
+ */
73
+ export const isDev = env.NODE_ENV === "development";
74
+
75
+ /**
76
+ * 工具函数:判断是否为生产环境
77
+ */
78
+ export const isProd = env.NODE_ENV === "production";
79
+
80
+ /**
81
+ * 工具函数:判断是否为测试环境
82
+ */
83
+ export const isTest =
84
+ env.NODE_ENV === "test" || env.NODE_ENV === "testDevelopment";
@@ -1,53 +1,15 @@
1
- import "dayjs/locale/zh-cn";
2
-
3
- import { renderClient } from "@config/router";
4
- import { ConfigProvider } from "antd";
5
- import dayjs from "dayjs";
6
- import React from "react";
7
-
8
- import { createRouter } from "@/routes";
9
- import { openUpdateVersionNotify } from "@/utils/updateVersion";
10
-
11
- dayjs.locale("zh-cn");
12
-
13
1
  import "./index.css";
14
-
15
- const AppName = process.env.APP_NAME ?? "";
16
- const BASENAME = process.env.BASENAME;
17
- const VERSION_NOTIFY_TIME = process.env.VERSION_NOTIFY_TIME;
18
-
19
- // 配置antd 静态方法使用的
20
- ConfigProvider.config({
21
- prefixCls: AppName,
22
- });
23
-
24
- const context = {
25
- basename: BASENAME,
26
- rootElement: document.getElementById(AppName) ?? document.body,
27
- };
28
-
29
- openUpdateVersionNotify(Number(VERSION_NOTIFY_TIME));
30
-
31
- // 子应用接入
32
- export const provider = () => {
33
- let root: any = null;
34
- return {
35
- destroy() {
36
- root?.unmount();
37
- },
38
- render({ basename }) {
39
- // 更改basename的值
40
- context.basename = basename;
41
- root = renderClient(context);
42
- window.Garfish.channel.emit("router", {
43
- name: AppName,
44
- routes: createRouter(basename),
45
- });
46
- },
47
- };
48
- };
49
-
50
- // 添加单独启动逻辑
51
- if (!window.__GARFISH__) {
52
- renderClient(context);
2
+ import { renderClient } from "@config/router";
3
+ import { createGarfishProvider, isMicroApp } from "@/micro/garfish";
4
+ import { env } from "@/config/env";
5
+
6
+ // 微前端模式:导出 Garfish 生命周期
7
+ export const provider = createGarfishProvider(env.APP_NAME);
8
+
9
+ // 独立运行模式:直接渲染
10
+ if (!isMicroApp()) {
11
+ renderClient({
12
+ basename: env.BASENAME,
13
+ rootElement: document.getElementById(env.APP_NAME) ?? document.body,
14
+ });
53
15
  }
@@ -0,0 +1,136 @@
1
+ import ThemeProvider from "@/components/ThemeProvider";
2
+ import { CLOUD_THEME_APPEARANCE } from "@/const/theme";
3
+ import { setCookie } from "@/utils/cookie";
4
+
5
+ // import { useGlobalStore } from "@store/global";
6
+ import React, { memo, useEffect, type ReactNode } from "react";
7
+
8
+ import { SYSTEM_PREFIX } from "@/const/system";
9
+ import { GlobalStyle } from "@/styles";
10
+ import { useUserStore } from "@store/user";
11
+ import { createStaticStyles, cx } from "antd-style";
12
+ import HarmonyOS_Sans_Regular from "@public/fonts/HarmonyOS_Sans_Regular.woff2";
13
+ import AntdStaticMethods from "@/components/AntdStaticMethods";
14
+
15
+ const styles = createStaticStyles(({ css, cssVar }) => ({
16
+ app: css`
17
+ position: relative;
18
+
19
+ overscroll-behavior: none;
20
+ display: flex;
21
+ flex-direction: column;
22
+ align-items: center;
23
+
24
+ height: 100%;
25
+ min-height: 100dvh;
26
+ max-height: 100dvh;
27
+
28
+ @media (min-device-width: 576px) {
29
+ overflow: hidden;
30
+ }
31
+ `,
32
+ // scrollbar-width and scrollbar-color are supported from Chrome 121
33
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/scrollbar-color
34
+ scrollbar: css`
35
+ scrollbar-color: ${cssVar.colorFill} transparent;
36
+ scrollbar-width: thin;
37
+
38
+ #lobe-mobile-scroll-container {
39
+ scrollbar-width: none;
40
+
41
+ ::-webkit-scrollbar {
42
+ width: 0;
43
+ height: 0;
44
+ }
45
+ }
46
+ `,
47
+
48
+ // so this is a polyfill for older browsers
49
+ scrollbarPolyfill: css`
50
+ ::-webkit-scrollbar {
51
+ width: 0.75em;
52
+ height: 0.75em;
53
+ }
54
+
55
+ ::-webkit-scrollbar-thumb {
56
+ border-radius: 10px;
57
+ }
58
+
59
+ :hover::-webkit-scrollbar-thumb {
60
+ border: 3px solid transparent;
61
+ background-color: ${cssVar.colorText};
62
+ background-clip: content-box;
63
+ }
64
+
65
+ ::-webkit-scrollbar-track {
66
+ background-color: transparent;
67
+ }
68
+ `,
69
+ }));
70
+
71
+ interface AppThemeProps {
72
+ children: ReactNode;
73
+ }
74
+
75
+ const AppTheme = memo(({ children }: AppThemeProps) => {
76
+ const themeMode = useUserStore((s) => s.themeMode);
77
+ const animationMode = useUserStore((s) => s.animationMode);
78
+ const neutralColor = useUserStore((s) => s.neutralColor);
79
+ const primaryColor = useUserStore((s) => s.primaryColor);
80
+
81
+ useEffect(() => {
82
+ // Update data-theme accordingly if user selects light or dark
83
+ if (themeMode !== "auto") {
84
+ document.documentElement.dataset.theme = themeMode;
85
+ return;
86
+ }
87
+
88
+ // For auto mode, we need to watch system preferences
89
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
90
+
91
+ // Set initial theme based on system preference
92
+ document.documentElement.dataset.theme = mediaQuery.matches
93
+ ? "dark"
94
+ : "light";
95
+
96
+ // Update theme when system preference changes
97
+ function handleChange(e) {
98
+ document.documentElement.dataset.theme = e.matches ? "dark" : "light";
99
+ }
100
+
101
+ mediaQuery.addEventListener("change", handleChange);
102
+ return () => mediaQuery.removeEventListener("change", handleChange);
103
+ }, [themeMode]);
104
+
105
+ return (
106
+ <ThemeProvider
107
+ prefixCls={SYSTEM_PREFIX}
108
+ appearance={themeMode !== "auto" ? themeMode : undefined}
109
+ className={cx(styles.app, styles.scrollbar, styles.scrollbarPolyfill)}
110
+ customTheme={{
111
+ neutralColor: neutralColor,
112
+ primaryColor: primaryColor,
113
+ }}
114
+ customFonts={[HarmonyOS_Sans_Regular]}
115
+ theme={{
116
+ cssVar: true,
117
+ token: {
118
+ motion: animationMode !== "disabled",
119
+ motionUnit: animationMode === "agile" ? 0.05 : 0.1,
120
+ },
121
+ }}
122
+ themeMode={themeMode}
123
+ onAppearanceChange={(appearance) => {
124
+ if (themeMode !== "auto") return;
125
+
126
+ setCookie(CLOUD_THEME_APPEARANCE, appearance);
127
+ }}
128
+ >
129
+ {children}
130
+ <AntdStaticMethods />
131
+ <GlobalStyle />
132
+ </ThemeProvider>
133
+ );
134
+ });
135
+
136
+ export default AppTheme;
@@ -0,0 +1,84 @@
1
+ import { ConfigProvider } from 'antd';
2
+ import dayjs from 'dayjs';
3
+ import { type PropsWithChildren, memo, useEffect, useState } from 'react';
4
+ import { isRtlLang } from 'rtl-detect';
5
+
6
+ import { createI18nNext } from '@/locales/create';
7
+ import { getAntdLocale } from '@/utils/locale';
8
+
9
+
10
+ const updateDayjs = async (lang: string) => {
11
+ let dayJSLocale;
12
+ try {
13
+ // dayjs locale is using `en` instead of `en-US`
14
+ // refs: https://github.com/lobehub/lobe-chat/issues/3396
15
+ const locale = lang!.toLowerCase() === 'en-us' ? 'en' : lang!.toLowerCase();
16
+
17
+ dayJSLocale = await import(`dayjs/locale/${locale}.js`);
18
+ } catch {
19
+ console.warn(`dayjs locale for ${lang} not found, fallback to en`);
20
+ dayJSLocale = await import(`dayjs/locale/en.js`);
21
+ }
22
+
23
+ dayjs.locale(dayJSLocale.default);
24
+ };
25
+
26
+ interface LocaleLayoutProps extends PropsWithChildren {
27
+ antdLocale?: any;
28
+ defaultLang?: string;
29
+ }
30
+
31
+ const Locale = memo<LocaleLayoutProps>(({ children, defaultLang, antdLocale }) => {
32
+ const [i18n] = useState(() => createI18nNext(defaultLang));
33
+ const [lang, setLang] = useState(defaultLang);
34
+ const [locale, setLocale] = useState(antdLocale);
35
+
36
+ if (!i18n.instance.isInitialized)
37
+ i18n.init().then(async () => {
38
+ if (!lang) return;
39
+
40
+ await updateDayjs(lang);
41
+ });
42
+
43
+ // handle i18n instance language change
44
+ useEffect(() => {
45
+ const handleLang = async (lng: string) => {
46
+ setLang(lng);
47
+
48
+ if (lang === lng) return;
49
+
50
+ const newLocale = await getAntdLocale(lng);
51
+ setLocale(newLocale);
52
+
53
+ await updateDayjs(lng);
54
+ };
55
+
56
+ i18n.instance.on('languageChanged', handleLang);
57
+ return () => {
58
+ i18n.instance.off('languageChanged', handleLang);
59
+ };
60
+ }, [i18n, lang]);
61
+
62
+ // detect document direction
63
+ const documentDir = isRtlLang(lang!) ? 'rtl' : 'ltr';
64
+
65
+ return (
66
+ <ConfigProvider
67
+ direction={documentDir}
68
+ locale={locale}
69
+ theme={{
70
+ components: {
71
+ Button: {
72
+ contentFontSizeSM: 12,
73
+ },
74
+ },
75
+ }}
76
+ >
77
+ {children}
78
+ </ConfigProvider>
79
+ );
80
+ });
81
+
82
+ Locale.displayName = 'Locale';
83
+
84
+ export default Locale;
@@ -0,0 +1,12 @@
1
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
2
+ import React, { type PropsWithChildren, useEffect, useState } from 'react';
3
+
4
+ const QueryProvider = ({ children }: PropsWithChildren) => {
5
+ const [queryClient] = useState(() => new QueryClient());
6
+
7
+ return (
8
+ <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
9
+ );
10
+ };
11
+
12
+ export default QueryProvider;
@@ -0,0 +1,9 @@
1
+ import { StyleProvider } from 'antd-style';
2
+ import { type PropsWithChildren } from 'react';
3
+
4
+
5
+ const StyleRegistry = ({ children }: PropsWithChildren) => {
6
+ return <StyleProvider>{children}</StyleProvider>;
7
+ };
8
+
9
+ export default StyleRegistry;
@@ -0,0 +1,23 @@
1
+ import StyleRegistry from "./StyleRegistry";
2
+ import AppTheme from "./AppTheme";
3
+ import QueryProvider from "./Query";
4
+ import Locale from "./Locale";
5
+ import { Outlet } from "react-router";
6
+
7
+ interface GlobalProviderProps {
8
+
9
+ }
10
+
11
+ export default function GlobalProvider({ }: GlobalProviderProps) {
12
+ return (
13
+ <StyleRegistry>
14
+ <Locale>
15
+ <AppTheme>
16
+ <QueryProvider>
17
+ <Outlet />
18
+ </QueryProvider>
19
+ </AppTheme>
20
+ </Locale>
21
+ </StyleRegistry>
22
+ );
23
+ }
@@ -1,17 +1,17 @@
1
- import { ConfigProvider } from 'antd';
2
- import type { Locale as AntdLocale } from 'antd/es/locale';
3
- import dayjs from 'dayjs';
1
+ import { ConfigProvider } from "antd";
2
+ import type { Locale as AntdLocale } from "antd/es/locale";
3
+ import dayjs from "dayjs";
4
4
  import React, {
5
5
  type PropsWithChildren,
6
6
  memo,
7
7
  useEffect,
8
8
  useState,
9
- } from 'react';
9
+ } from "react";
10
10
 
11
- import { isRtlLang } from 'rtl-detect';
11
+ import { isRtlLang } from "rtl-detect";
12
12
 
13
- import { createI18nNext } from '@/locales/create';
14
- import { getAntdLocale } from '@/utils/locale';
13
+ import { createI18nNext } from "@/locales/create";
14
+ import { getAntdLocale } from "@/utils/locale";
15
15
 
16
16
  const updateDayjs = async (lang: string) => {
17
17
  // load default lang
@@ -19,12 +19,12 @@ const updateDayjs = async (lang: string) => {
19
19
  try {
20
20
  // dayjs locale is using `en` instead of `en-US`
21
21
  // refs: https://github.com/lobehub/lobe-chat/issues/3396
22
- const locale = lang.toLowerCase() === 'en-us' ? 'en' : lang.toLowerCase();
22
+ const locale = lang.toLowerCase() === "en-us" ? "en" : lang.toLowerCase();
23
23
 
24
24
  dayJSLocale = await import(`dayjs/locale/${locale}.js`);
25
25
  } catch {
26
26
  console.warn(`dayjs locale for ${lang} not found, fallback to en`);
27
- dayJSLocale = await import('dayjs/locale/en.js');
27
+ dayJSLocale = await import("dayjs/locale/en.js");
28
28
  }
29
29
 
30
30
  dayjs.locale(dayJSLocale.default);
@@ -41,8 +41,6 @@ const Locale = memo<LocaleLayoutProps>(
41
41
  const [lang, setLang] = useState(defaultLang);
42
42
  const [locale, setLocale] = useState(antdLocale);
43
43
 
44
- console.log(antdLocale, defaultLang);
45
-
46
44
  // if on browser side, init i18n instance only once
47
45
  if (!i18n.instance.isInitialized)
48
46
  // console.debug('locale', lang);
@@ -65,25 +63,23 @@ const Locale = memo<LocaleLayoutProps>(
65
63
  await updateDayjs(lng);
66
64
  };
67
65
 
68
- i18n.instance.on('languageChanged', handleLang);
66
+ i18n.instance.on("languageChanged", handleLang);
69
67
  return () => {
70
- i18n.instance.off('languageChanged', handleLang);
68
+ i18n.instance.off("languageChanged", handleLang);
71
69
  };
72
70
  }, [i18n, lang]);
73
71
 
74
72
  // detect document direction
75
- const documentDir = isRtlLang(lang) ? 'rtl' : 'ltr';
76
-
77
- console.log(documentDir, locale);
73
+ const documentDir = isRtlLang(lang) ? "rtl" : "ltr";
78
74
 
79
75
  return (
80
76
  <ConfigProvider direction={documentDir} locale={locale as AntdLocale}>
81
77
  {children}
82
78
  </ConfigProvider>
83
79
  );
84
- },
80
+ }
85
81
  );
86
82
 
87
- Locale.displayName = 'Locale';
83
+ Locale.displayName = "Locale";
88
84
 
89
85
  export default Locale;
@@ -1,19 +1,15 @@
1
- import { ConfigProvider, theme } from 'antd';
2
- import type { Locale as AntdLocale } from 'antd/es/locale';
3
- import React, { useState, useEffect } from 'react';
1
+ import React, { useState, useEffect } from "react";
4
2
 
5
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
6
- import { Outlet } from 'react-router';
7
- import '../index.css';
8
- import { DEFAULT_LANG } from '@/const/locale';
9
- import { useRouteTitle } from '@/hooks/useRouteTitle';
10
- import { getAntdLocale } from '@/utils/locale';
11
- import queryString from 'query-string';
12
- import Locale from './Locale';
13
- import AppTheme from './ThemeContext';
3
+ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
4
+ import { Outlet } from "react-router";
5
+ import "../index.css";
6
+ import { DEFAULT_LANG } from "@/const/locale";
7
+ import { getAntdLocale } from "@/utils";
8
+ import queryString from "query-string";
9
+ import Locale from "./Locale";
10
+ import AppTheme from "./ThemeContext";
14
11
 
15
12
  export const MainContentWrap = () => {
16
- useRouteTitle();
17
13
  const [antdLocale, setAntdLocale] = useState<unknown>(null);
18
14
  const [isLocaleLoaded, setIsLocaleLoaded] = useState(false);
19
15
 
@@ -32,11 +28,11 @@ export const MainContentWrap = () => {
32
28
  const loadLocale = async () => {
33
29
  try {
34
30
  const loadedLocale = await getAntdLocale(
35
- (lang as string) ?? DEFAULT_LANG,
31
+ (lang as string) ?? DEFAULT_LANG
36
32
  );
37
33
  setAntdLocale(loadedLocale);
38
34
  } catch (error) {
39
- console.error('Failed to load locale:', error);
35
+ console.error("Failed to load locale:", error);
40
36
  // 保持默认的中文 locale
41
37
  } finally {
42
38
  setIsLocaleLoaded(true);