@qlover/create-app 0.6.1 → 0.6.3

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 (68) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/templates/react-app/README.en.md +257 -0
  5. package/dist/templates/react-app/README.md +29 -231
  6. package/dist/templates/react-app/config/IOCIdentifier.ts +13 -0
  7. package/dist/templates/react-app/docs/en/bootstrap.md +562 -0
  8. package/dist/templates/react-app/docs/en/development-guide.md +523 -0
  9. package/dist/templates/react-app/docs/en/env.md +482 -0
  10. package/dist/templates/react-app/docs/en/global.md +509 -0
  11. package/dist/templates/react-app/docs/en/i18n.md +268 -0
  12. package/dist/templates/react-app/docs/en/index.md +173 -0
  13. package/dist/templates/react-app/docs/en/ioc.md +424 -0
  14. package/dist/templates/react-app/docs/en/project-structure.md +434 -0
  15. package/dist/templates/react-app/docs/en/request.md +425 -0
  16. package/dist/templates/react-app/docs/en/router.md +404 -0
  17. package/dist/templates/react-app/docs/en/store.md +321 -0
  18. package/dist/templates/react-app/docs/en/theme.md +424 -0
  19. package/dist/templates/react-app/docs/en/typescript-guide.md +473 -0
  20. package/dist/templates/react-app/docs/zh/bootstrap.md +562 -0
  21. package/dist/templates/react-app/docs/zh/development-guide.md +523 -0
  22. package/dist/templates/react-app/docs/zh/env.md +479 -0
  23. package/dist/templates/react-app/docs/zh/global.md +511 -0
  24. package/dist/templates/react-app/docs/zh/i18n.md +268 -0
  25. package/dist/templates/react-app/docs/zh/index.md +173 -0
  26. package/dist/templates/react-app/docs/zh/ioc.md +422 -0
  27. package/dist/templates/react-app/docs/zh/project-structure.md +434 -0
  28. package/dist/templates/react-app/docs/zh/request.md +429 -0
  29. package/dist/templates/react-app/docs/zh/router.md +408 -0
  30. package/dist/templates/react-app/docs/zh/store.md +321 -0
  31. package/dist/templates/react-app/docs/zh/theme.md +424 -0
  32. package/dist/templates/react-app/docs/zh/typescript-guide.md +473 -0
  33. package/dist/templates/react-app/package.json +2 -2
  34. package/dist/templates/react-app/src/base/apis/AiApi.ts +10 -5
  35. package/dist/templates/react-app/src/base/apis/feApi/FeApiAdapter.ts +1 -1
  36. package/dist/templates/react-app/src/base/apis/feApi/FeApiBootstarp.ts +1 -1
  37. package/dist/templates/react-app/src/base/apis/userApi/UserApi.ts +10 -17
  38. package/dist/templates/react-app/src/base/apis/userApi/UserApiAdapter.ts +1 -1
  39. package/dist/templates/react-app/src/base/apis/userApi/UserApiBootstarp.ts +2 -1
  40. package/dist/templates/react-app/src/base/apis/userApi/UserApiType.ts +7 -5
  41. package/dist/templates/react-app/src/base/cases/I18nKeyErrorPlugin.ts +3 -2
  42. package/dist/templates/react-app/src/base/cases/InversifyContainer.ts +33 -0
  43. package/dist/templates/react-app/src/base/cases/RequestLogger.ts +1 -1
  44. package/dist/templates/react-app/src/base/cases/RequestStatusCatcher.ts +2 -2
  45. package/dist/templates/react-app/src/base/services/ProcesserExecutor.ts +1 -1
  46. package/dist/templates/react-app/src/base/services/RouteService.ts +5 -2
  47. package/dist/templates/react-app/src/base/services/UserService.ts +8 -10
  48. package/dist/templates/react-app/src/core/IOC.ts +73 -83
  49. package/dist/templates/react-app/src/core/bootstraps/BootstrapApp.ts +52 -4
  50. package/dist/templates/react-app/src/core/bootstraps/{index.ts → BootstrapsRegistry.ts} +2 -3
  51. package/dist/templates/react-app/src/core/registers/IocRegisterImpl.ts +25 -0
  52. package/dist/templates/react-app/src/core/registers/RegisterCommon.ts +11 -17
  53. package/dist/templates/react-app/src/core/registers/RegisterControllers.ts +10 -4
  54. package/dist/templates/react-app/src/core/registers/RegisterGlobals.ts +6 -15
  55. package/dist/templates/react-app/src/main.tsx +2 -5
  56. package/dist/templates/react-app/src/styles/css/antd-themes/dark.css +3 -1
  57. package/dist/templates/react-app/src/styles/css/antd-themes/index.css +1 -1
  58. package/dist/templates/react-app/src/styles/css/antd-themes/pink.css +6 -1
  59. package/dist/templates/react-app/src/styles/css/page.css +1 -1
  60. package/dist/templates/react-app/src/uikit/controllers/JSONStorageController.ts +1 -1
  61. package/dist/templates/react-app/tsconfig.app.json +2 -1
  62. package/dist/templates/react-app/tsconfig.node.json +2 -1
  63. package/package.json +2 -2
  64. package/dist/templates/react-app/src/base/port/ApiTransactionInterface.ts +0 -7
  65. package/dist/templates/react-app/src/base/port/RequestCatcherInterface.ts +0 -12
  66. package/dist/templates/react-app/src/core/bootstrap.ts +0 -58
  67. package/dist/templates/react-app/src/core/registers/RegisterApi.ts +0 -5
  68. package/dist/templates/react-app/src/core/registers/index.ts +0 -32
@@ -0,0 +1,479 @@
1
+ # 环境变量注入
2
+
3
+ ## 什么是环境变量注入?
4
+
5
+ 环境变量注入是 Bootstrap 的一个重要功能,它允许我们将环境变量自动注入到应用配置中,实现配置的集中管理和环境隔离。
6
+
7
+ **简单来说**:就像给应用穿上不同的衣服一样,根据不同的环境(开发、测试、生产),应用会使用不同的配置。
8
+
9
+ ## 工作原理
10
+
11
+ ### 1. 环境变量加载流程
12
+
13
+ ```
14
+ 应用启动 → Bootstrap 初始化 → InjectEnv 插件 → 加载环境变量 → 注入到 AppConfig → 应用使用配置
15
+ ```
16
+
17
+ ### 2. 核心技术栈
18
+
19
+ - **@qlover/env-loader**:环境变量加载器
20
+ - **@qlover/corekit-bridge/vite-env-config**:Vite 环境变量配置插件
21
+ - **dotenv**:.env 文件解析
22
+ - **Vite**:前端构建工具
23
+
24
+ ### 3. 文件结构
25
+
26
+ ```
27
+ 项目根目录/
28
+ ├── .env # 默认环境变量
29
+ ├── .env.local # 本地环境变量(git ignored)
30
+ ├── .env.development # 开发环境变量
31
+ ├── .env.production # 生产环境变量
32
+ ├── .env.staging # 测试环境变量
33
+ ├── vite.config.ts # Vite 配置
34
+ └── src/
35
+ └── base/
36
+ └── cases/
37
+ └── AppConfig.ts # 应用配置类
38
+ ```
39
+
40
+ ## 环境变量文件
41
+
42
+ ### 1. 文件加载优先级
43
+
44
+ Vite 会按照以下优先级加载环境变量文件:
45
+
46
+ ```
47
+ .env.local > .env.[mode] > .env
48
+ ```
49
+
50
+ **示例**:
51
+
52
+ ```bash
53
+ # 开发模式
54
+ vite dev --mode development
55
+ # 加载顺序:.env.local > .env.development > .env
56
+
57
+ # 生产模式
58
+ vite build --mode production
59
+ # 加载顺序:.env.local > .env.production > .env
60
+
61
+ # 自定义模式
62
+ vite dev --mode staging
63
+ # 加载顺序:.env.local > .env.staging > .env
64
+ ```
65
+
66
+ ### 2. 环境变量文件示例
67
+
68
+ ```bash
69
+ # .env (默认配置)
70
+ VITE_APP_NAME=MyApp
71
+ VITE_API_BASE_URL=http://api.example.com
72
+ VITE_USER_TOKEN_KEY=user_token
73
+
74
+ # .env.development (开发环境)
75
+ VITE_API_BASE_URL=http://localhost:3000/api
76
+ VITE_DEBUG=true
77
+
78
+ # .env.production (生产环境)
79
+ VITE_API_BASE_URL=https://api.production.com
80
+ VITE_DEBUG=false
81
+
82
+ # .env.local (本地覆盖,不提交到 git)
83
+ VITE_API_KEY=your_secret_key
84
+ VITE_LOCAL_DEBUG=true
85
+ ```
86
+
87
+ ## 项目中的实现
88
+
89
+ ### 1. Vite 配置
90
+
91
+ ```tsx
92
+ // vite.config.ts
93
+ import envConfig from '@qlover/corekit-bridge/vite-env-config';
94
+
95
+ export default defineConfig({
96
+ plugins: [
97
+ envConfig({
98
+ envPops: true, // 启用环境变量加载
99
+ envPrefix: 'VITE_', // 环境变量前缀
100
+ records: [
101
+ ['APP_NAME', name], // 注入应用名称
102
+ ['APP_VERSION', version] // 注入应用版本
103
+ ]
104
+ })
105
+ ],
106
+ envPrefix: 'VITE_', // Vite 环境变量前缀
107
+ server: {
108
+ port: Number(process.env.VITE_SERVER_PORT || 3200)
109
+ }
110
+ });
111
+ ```
112
+
113
+ ### 2. 应用配置类
114
+
115
+ ```tsx
116
+ // src/base/cases/AppConfig.ts
117
+ export class AppConfig implements EnvConfigInterface {
118
+ /**
119
+ * 应用名称
120
+ * @description 从 VITE_APP_NAME 环境变量注入
121
+ */
122
+ readonly appName = '';
123
+
124
+ /**
125
+ * 应用版本
126
+ * @description 从 VITE_APP_VERSION 环境变量注入
127
+ */
128
+ readonly appVersion = '';
129
+
130
+ /**
131
+ * 当前环境模式
132
+ * @description 从 Vite 的 mode 获取
133
+ */
134
+ readonly env: string = import.meta.env.MODE;
135
+
136
+ /**
137
+ * 用户令牌存储键
138
+ * @description 从 VITE_USER_TOKEN_STORAGE_KEY 环境变量注入
139
+ */
140
+ readonly userTokenStorageKey = '__fe_user_token__';
141
+
142
+ /**
143
+ * AI API 基础 URL
144
+ * @description 从 VITE_AI_API_BASE_URL 环境变量注入
145
+ */
146
+ readonly aiApiBaseUrl = 'https://api.openai.com/v1';
147
+
148
+ /**
149
+ * AI API 令牌
150
+ * @description 从 VITE_AI_API_TOKEN 环境变量注入
151
+ */
152
+ readonly aiApiToken = '';
153
+
154
+ // ... 更多配置项
155
+ }
156
+ ```
157
+
158
+ ### 3. Bootstrap 中的注入
159
+
160
+ ```tsx
161
+ // src/core/bootstraps/BootstrapApp.ts
162
+ const bootstrap = new Bootstrap({
163
+ root: window,
164
+ logger,
165
+ ioc: {
166
+ manager: IOC,
167
+ register: new IocRegisterImpl({ pathname, appConfig })
168
+ },
169
+ envOptions: {
170
+ target: appConfig, // 注入目标
171
+ source: {
172
+ ...import.meta.env, // 环境变量源
173
+ [envPrefix + 'BOOT_HREF']: root.location.href
174
+ },
175
+ prefix: envPrefix, // 环境变量前缀
176
+ blackList: envBlackList // 黑名单(不注入的变量)
177
+ }
178
+ });
179
+ ```
180
+
181
+ ## 多环境配置
182
+
183
+ ### 1. 开发环境配置
184
+
185
+ ```bash
186
+ # package.json
187
+ {
188
+ "scripts": {
189
+ "dev": "vite --mode localhost",
190
+ "dev:staging": "vite --mode staging",
191
+ "dev:prod": "vite --mode production"
192
+ }
193
+ }
194
+ ```
195
+
196
+ ```bash
197
+ # .env.development
198
+ VITE_APP_NAME=MyApp Dev
199
+ VITE_API_BASE_URL=http://localhost:3000/api
200
+ VITE_DEBUG=true
201
+ VITE_LOG_LEVEL=debug
202
+ ```
203
+
204
+ ### 2. 测试环境配置
205
+
206
+ ```bash
207
+ # .env.staging
208
+ VITE_APP_NAME=MyApp Staging
209
+ VITE_API_BASE_URL=https://api.staging.com
210
+ VITE_DEBUG=true
211
+ VITE_LOG_LEVEL=info
212
+ ```
213
+
214
+ ### 3. 生产环境配置
215
+
216
+ ```bash
217
+ # .env.production
218
+ VITE_APP_NAME=MyApp
219
+ VITE_API_BASE_URL=https://api.production.com
220
+ VITE_DEBUG=false
221
+ VITE_LOG_LEVEL=warn
222
+ ```
223
+
224
+ ### 4. 本地覆盖配置
225
+
226
+ ```bash
227
+ # .env.local (不提交到 git)
228
+ VITE_API_KEY=your_secret_key
229
+ VITE_LOCAL_DEBUG=true
230
+ VITE_CUSTOM_FEATURE=true
231
+ ```
232
+
233
+ ## 在代码中使用
234
+
235
+ ### 1. 直接使用环境变量
236
+
237
+ ```tsx
238
+ // 在组件中直接使用
239
+ function App() {
240
+ const apiUrl = import.meta.env.VITE_API_BASE_URL;
241
+ const isDebug = import.meta.env.VITE_DEBUG === 'true';
242
+ return (
243
+ <div>
244
+ <p>API URL: {apiUrl}</p>
245
+ {isDebug && <p>Debug mode enabled</p>}
246
+ </div>
247
+ );
248
+ }
249
+ ```
250
+
251
+ ### 2. 通过 AppConfig 使用
252
+
253
+ ```tsx
254
+ // 通过 IOC 获取配置
255
+ function UserService() {
256
+ const appConfig = IOC(IOCIdentifier.AppConfig);
257
+
258
+ const apiUrl = appConfig.aiApiBaseUrl;
259
+ const token = appConfig.aiApiToken;
260
+
261
+ // 使用配置进行 API 调用
262
+ const response = await fetch(`${apiUrl}/chat`, {
263
+ headers: {
264
+ Authorization: `Bearer ${token}`
265
+ }
266
+ });
267
+ }
268
+ ```
269
+
270
+ ### 3. 在服务中使用
271
+
272
+ ```tsx
273
+ @injectable()
274
+ export class ApiService {
275
+ constructor(@inject(IOCIdentifier.AppConfig) private appConfig: AppConfig) {}
276
+
277
+ async makeRequest() {
278
+ const baseUrl = this.appConfig.aiApiBaseUrl;
279
+ const token = this.appConfig.aiApiToken;
280
+
281
+ return fetch(`${baseUrl}/api/endpoint`, {
282
+ headers: {
283
+ Authorization: `Bearer ${token}`
284
+ }
285
+ });
286
+ }
287
+ }
288
+ ```
289
+
290
+ ## 环境变量注入插件
291
+
292
+ ### 1. InjectEnv 插件工作原理
293
+
294
+ ```tsx
295
+ // corekit-bridge/src/core/bootstrap/plugins/InjectEnv.ts
296
+ export class InjectEnv implements BootstrapExecutorPlugin {
297
+ readonly pluginName = 'InjectEnv';
298
+
299
+ constructor(protected options: InjectEnvConfig) {}
300
+
301
+ onBefore(): void {
302
+ const { target, source, prefix, blackList } = this.options;
303
+ // 遍历目标对象的属性
304
+ for (const key in target) {
305
+ if (blackList.includes(key)) {
306
+ continue; // 跳过黑名单中的属性
307
+ }
308
+
309
+ const value = target[key as keyof typeof target];
310
+ const envValue = this.env(key, value); // 获取环境变量值
311
+
312
+ // 如果环境变量存在且与默认值不同,则注入
313
+ if (!this.isEmpty(envValue) && envValue !== value) {
314
+ target[key as keyof typeof target] = envValue;
315
+ }
316
+ }
317
+ }
318
+ }
319
+ ```
320
+
321
+ ### 2. 环境变量获取逻辑
322
+
323
+ ```tsx
324
+ env<D>(key: string, defaultValue?: D): D {
325
+ const { prefix = '', source = {} } = this.options;
326
+
327
+ // 将驼峰命名转换为下划线命名
328
+ const formattedKey = key.replace(/([a-z])([A-Z])/g, '$1_$2').toUpperCase();
329
+ const envKey = `${prefix}${formattedKey}`;
330
+
331
+ const value = source[envKey];
332
+
333
+ // 如果是 JSON 字符串,则解析
334
+ if (typeof value === 'string' && InjectEnv.isJSONString(value)) {
335
+ return JSON.parse(value);
336
+ }
337
+
338
+ return (value ?? defaultValue) as D;
339
+ }
340
+ ```
341
+
342
+ ## 最佳实践
343
+
344
+ ### 1. 环境变量命名规范
345
+
346
+ ```bash
347
+ # ✅ 好的命名
348
+ VITE_APP_NAME=MyApp
349
+ VITE_API_BASE_URL=https://api.example.com
350
+ VITE_USER_TOKEN_STORAGE_KEY=user_token
351
+ VITE_DEBUG=true
352
+
353
+ # ❌ 不好的命名
354
+ VITE_app_name=MyApp
355
+ VITE_API_BASE_URL=https://api.example.com
356
+ VITE_USER_TOKEN_STORAGE_KEY=user_token
357
+ VITE_DEBUG=true
358
+ ```
359
+
360
+ ### 2. 敏感信息处理
361
+
362
+ ```bash
363
+ # .env.local (不提交到 git)
364
+ VITE_API_KEY=your_secret_key
365
+ VITE_DATABASE_PASSWORD=your_password
366
+
367
+ # .env.template (提交到 git,作为模板)
368
+ VITE_API_KEY=your_api_key_here
369
+ VITE_DATABASE_PASSWORD=your_password_here
370
+ ```
371
+
372
+ ### 3. 类型安全
373
+
374
+ ```tsx
375
+ // 定义环境变量类型
376
+ interface EnvVariables {
377
+ VITE_APP_NAME: string;
378
+ VITE_API_BASE_URL: string;
379
+ VITE_DEBUG: boolean;
380
+ VITE_PORT: number;
381
+ }
382
+
383
+ // 在 AppConfig 中使用
384
+ export class AppConfig implements EnvConfigInterface {
385
+ readonly appName: string = '';
386
+ readonly apiBaseUrl: string = '';
387
+ readonly debug: boolean = false;
388
+ readonly port: number = 3000;
389
+ }
390
+ ```
391
+
392
+ ### 4. 环境变量验证
393
+
394
+ ```tsx
395
+ // 在应用启动时验证必要的环境变量
396
+ export class AppConfig implements EnvConfigInterface {
397
+ constructor() {
398
+ this.validateRequiredEnvVars();
399
+ }
400
+
401
+ private validateRequiredEnvVars(): void {
402
+ const required = ['VITE_API_BASE_URL', 'VITE_APP_NAME'];
403
+ for (const envVar of required) {
404
+ if (!import.meta.env[envVar]) {
405
+ throw new Error(`Missing required environment variable: ${envVar}`);
406
+ }
407
+ }
408
+ }
409
+ }
410
+ ```
411
+
412
+ ## 调试和故障排除
413
+
414
+ ### 1. 检查环境变量加载
415
+
416
+ ```tsx
417
+ // 在控制台中检查环境变量
418
+ console.log('import.meta.env:', import.meta.env);
419
+ console.log('AppConfig:', IOC(IOCIdentifier.AppConfig));
420
+ ```
421
+
422
+ ### 2. 常见问题
423
+
424
+ **问题 1:环境变量未注入**
425
+
426
+ ```bash
427
+ # 检查环境变量前缀
428
+ # 确保使用 VITE_ 前缀
429
+ VITE_APP_NAME=MyApp # ✅ 正确
430
+ APP_NAME=MyApp # ❌ 错误,不会被注入
431
+ ```
432
+
433
+ **问题 2:环境变量文件未加载**
434
+
435
+ ```bash
436
+ # 检查文件命名
437
+ .env.development # ✅ 正确
438
+ .env.dev # ❌ 错误,Vite 不认识
439
+ ```
440
+
441
+ **问题 3:环境变量被黑名单过滤**
442
+
443
+ ```tsx
444
+ // 检查黑名单配置
445
+ export const envBlackList = ['env', 'userNodeEnv'];
446
+ // 确保你的环境变量不在黑名单中
447
+ ```
448
+
449
+ ### 3. 调试工具
450
+
451
+ ```tsx
452
+ // 创建调试工具
453
+ export class EnvDebugger {
454
+ static logEnvVars(config: AppConfig): void {
455
+ console.group('Environment Variables Debug');
456
+ console.log('Current Mode:', import.meta.env.MODE);
457
+ console.log('AppConfig:', config);
458
+ console.log('All Env Vars:', import.meta.env);
459
+ console.groupEnd();
460
+ }
461
+ }
462
+
463
+ // 在开发环境中使用
464
+ if (import.meta.env.DEV) {
465
+ EnvDebugger.logEnvVars(IOC(IOCIdentifier.AppConfig));
466
+ }
467
+ ```
468
+
469
+ ## 总结
470
+
471
+ 环境变量注入系统提供了:
472
+
473
+ 1. **环境隔离**:不同环境使用不同配置
474
+ 2. **类型安全**:通过 TypeScript 提供类型检查
475
+ 3. **集中管理**:所有配置在 AppConfig 中统一管理
476
+ 4. **灵活配置**:支持多种环境变量文件
477
+ 5. **安全处理**:敏感信息可以通过 .env.local 本地管理
478
+
479
+ 通过合理使用环境变量注入,可以让应用在不同环境中正确运行,同时保持配置的灵活性和安全性。