@qlover/create-app 0.6.1 → 0.6.2

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