@qlover/create-app 0.6.2 → 0.7.0
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.
- package/CHANGELOG.md +53 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/templates/react-app/README.en.md +257 -0
- package/dist/templates/react-app/README.md +29 -231
- package/dist/templates/react-app/__tests__/__mocks__/I18nService.ts +13 -0
- package/dist/templates/react-app/__tests__/__mocks__/MockAppConfit.ts +48 -0
- package/dist/templates/react-app/__tests__/__mocks__/MockDialogHandler.ts +16 -0
- package/dist/templates/react-app/__tests__/__mocks__/MockLogger.ts +14 -0
- package/dist/templates/react-app/__tests__/__mocks__/createMockGlobals.ts +92 -0
- package/dist/templates/react-app/__tests__/setup/index.ts +51 -0
- package/dist/templates/react-app/__tests__/src/App.test.tsx +139 -0
- package/dist/templates/react-app/__tests__/src/base/cases/AppConfig.test.ts +288 -0
- package/dist/templates/react-app/__tests__/src/base/cases/AppError.test.ts +102 -0
- package/dist/templates/react-app/__tests__/src/base/cases/DialogHandler.test.ts +228 -0
- package/dist/templates/react-app/__tests__/src/base/cases/I18nKeyErrorPlugin.test.ts +207 -0
- package/dist/templates/react-app/__tests__/src/base/cases/InversifyContainer.test.ts +181 -0
- package/dist/templates/react-app/__tests__/src/base/cases/PublicAssetsPath.test.ts +61 -0
- package/dist/templates/react-app/__tests__/src/base/cases/RequestLogger.test.ts +199 -0
- package/dist/templates/react-app/__tests__/src/base/cases/RequestStatusCatcher.test.ts +192 -0
- package/dist/templates/react-app/__tests__/src/base/cases/RouterLoader.test.ts +235 -0
- package/dist/templates/react-app/__tests__/src/base/services/I18nService.test.ts +224 -0
- package/dist/templates/react-app/__tests__/src/core/IOC.test.ts +257 -0
- package/dist/templates/react-app/__tests__/src/core/bootstraps/BootstrapsApp.test.ts +72 -0
- package/dist/templates/react-app/__tests__/src/main.integration.test.tsx +62 -0
- package/dist/templates/react-app/__tests__/src/main.test.tsx +46 -0
- package/dist/templates/react-app/__tests__/src/uikit/components/BaseHeader.test.tsx +88 -0
- package/dist/templates/react-app/config/app.router.ts +155 -0
- package/dist/templates/react-app/config/common.ts +9 -1
- package/dist/templates/react-app/docs/en/bootstrap.md +562 -0
- package/dist/templates/react-app/docs/en/development-guide.md +523 -0
- package/dist/templates/react-app/docs/en/env.md +482 -0
- package/dist/templates/react-app/docs/en/global.md +509 -0
- package/dist/templates/react-app/docs/en/i18n.md +268 -0
- package/dist/templates/react-app/docs/en/index.md +173 -0
- package/dist/templates/react-app/docs/en/ioc.md +424 -0
- package/dist/templates/react-app/docs/en/project-structure.md +434 -0
- package/dist/templates/react-app/docs/en/request.md +425 -0
- package/dist/templates/react-app/docs/en/router.md +404 -0
- package/dist/templates/react-app/docs/en/store.md +321 -0
- package/dist/templates/react-app/docs/en/test-guide.md +782 -0
- package/dist/templates/react-app/docs/en/theme.md +424 -0
- package/dist/templates/react-app/docs/en/typescript-guide.md +473 -0
- package/dist/templates/react-app/docs/zh/bootstrap.md +7 -0
- package/dist/templates/react-app/docs/zh/development-guide.md +523 -0
- package/dist/templates/react-app/docs/zh/env.md +24 -25
- package/dist/templates/react-app/docs/zh/global.md +28 -27
- package/dist/templates/react-app/docs/zh/i18n.md +268 -0
- package/dist/templates/react-app/docs/zh/index.md +173 -0
- package/dist/templates/react-app/docs/zh/ioc.md +44 -32
- package/dist/templates/react-app/docs/zh/project-structure.md +434 -0
- package/dist/templates/react-app/docs/zh/request.md +429 -0
- package/dist/templates/react-app/docs/zh/router.md +408 -0
- package/dist/templates/react-app/docs/zh/store.md +321 -0
- package/dist/templates/react-app/docs/zh/test-guide.md +782 -0
- package/dist/templates/react-app/docs/zh/theme.md +424 -0
- package/dist/templates/react-app/docs/zh/typescript-guide.md +473 -0
- package/dist/templates/react-app/package.json +9 -20
- package/dist/templates/react-app/src/base/cases/AppConfig.ts +16 -9
- package/dist/templates/react-app/src/base/cases/PublicAssetsPath.ts +7 -1
- package/dist/templates/react-app/src/base/services/I18nService.ts +15 -4
- package/dist/templates/react-app/src/base/services/RouteService.ts +43 -7
- package/dist/templates/react-app/src/core/bootstraps/BootstrapApp.ts +31 -10
- package/dist/templates/react-app/src/core/bootstraps/BootstrapsRegistry.ts +1 -1
- package/dist/templates/react-app/src/core/globals.ts +1 -3
- package/dist/templates/react-app/src/core/registers/RegisterCommon.ts +5 -3
- package/dist/templates/react-app/src/main.tsx +6 -1
- package/dist/templates/react-app/src/pages/404.tsx +0 -1
- package/dist/templates/react-app/src/pages/500.tsx +1 -1
- package/dist/templates/react-app/src/pages/base/RedirectPathname.tsx +3 -1
- package/dist/templates/react-app/src/styles/css/antd-themes/dark.css +3 -1
- package/dist/templates/react-app/src/styles/css/antd-themes/index.css +1 -1
- package/dist/templates/react-app/src/styles/css/antd-themes/pink.css +6 -1
- package/dist/templates/react-app/src/styles/css/page.css +1 -1
- package/dist/templates/react-app/src/uikit/components/BaseHeader.tsx +9 -2
- package/dist/templates/react-app/src/uikit/components/LocaleLink.tsx +5 -3
- package/dist/templates/react-app/src/uikit/hooks/useI18nGuard.ts +4 -6
- package/dist/templates/react-app/tsconfig.json +2 -1
- package/dist/templates/react-app/tsconfig.test.json +13 -0
- package/dist/templates/react-app/vite.config.ts +3 -2
- package/package.json +1 -1
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
# Environment Variables Injection
|
|
2
|
+
|
|
3
|
+
## What is Environment Variables Injection?
|
|
4
|
+
|
|
5
|
+
Environment variables injection is a crucial feature of Bootstrap that allows us to automatically inject environment variables into application configuration, enabling centralized configuration management and environment isolation.
|
|
6
|
+
|
|
7
|
+
**In simple terms**: Just like dressing your application in different clothes, based on different environments (development, testing, production), the application will use different configurations.
|
|
8
|
+
|
|
9
|
+
## How It Works
|
|
10
|
+
|
|
11
|
+
### 1. Environment Variables Loading Process
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
App Start → Bootstrap Initialization → InjectEnv Plugin → Load Environment Variables → Inject into AppConfig → App Uses Config
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### 2. Core Technology Stack
|
|
18
|
+
|
|
19
|
+
- **@qlover/env-loader**: Environment variables loader
|
|
20
|
+
- **@qlover/corekit-bridge/vite-env-config**: Vite environment variables configuration plugin
|
|
21
|
+
- **dotenv**: .env file parser
|
|
22
|
+
- **Vite**: Frontend build tool
|
|
23
|
+
|
|
24
|
+
### 3. File Structure
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
Project Root/
|
|
28
|
+
├── .env # Default environment variables
|
|
29
|
+
├── .env.local # Local environment variables (git ignored)
|
|
30
|
+
├── .env.development # Development environment variables
|
|
31
|
+
├── .env.production # Production environment variables
|
|
32
|
+
├── .env.staging # Testing environment variables
|
|
33
|
+
├── vite.config.ts # Vite configuration
|
|
34
|
+
└── src/
|
|
35
|
+
└── base/
|
|
36
|
+
└── cases/
|
|
37
|
+
└── AppConfig.ts # Application configuration class
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Environment Variable Files
|
|
41
|
+
|
|
42
|
+
### 1. File Loading Priority
|
|
43
|
+
|
|
44
|
+
Vite loads environment variable files in the following priority:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
.env.local > .env.[mode] > .env
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Examples**:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Development mode
|
|
54
|
+
vite dev --mode development
|
|
55
|
+
# Loading order: .env.local > .env.development > .env
|
|
56
|
+
|
|
57
|
+
# Production mode
|
|
58
|
+
vite build --mode production
|
|
59
|
+
# Loading order: .env.local > .env.production > .env
|
|
60
|
+
|
|
61
|
+
# Custom mode
|
|
62
|
+
vite dev --mode staging
|
|
63
|
+
# Loading order: .env.local > .env.staging > .env
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 2. Environment Variable File Examples
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# .env (default configuration)
|
|
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 (development environment)
|
|
75
|
+
VITE_API_BASE_URL=http://localhost:3000/api
|
|
76
|
+
VITE_DEBUG=true
|
|
77
|
+
|
|
78
|
+
# .env.production (production environment)
|
|
79
|
+
VITE_API_BASE_URL=https://api.production.com
|
|
80
|
+
VITE_DEBUG=false
|
|
81
|
+
|
|
82
|
+
# .env.local (local override, not committed to git)
|
|
83
|
+
VITE_API_KEY=your_secret_key
|
|
84
|
+
VITE_LOCAL_DEBUG=true
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Implementation in Project
|
|
88
|
+
|
|
89
|
+
### 1. Vite Configuration
|
|
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, // Enable environment variables loading
|
|
99
|
+
envPrefix: 'VITE_', // Environment variables prefix
|
|
100
|
+
records: [
|
|
101
|
+
['APP_NAME', name], // Inject application name
|
|
102
|
+
['APP_VERSION', version] // Inject application version
|
|
103
|
+
]
|
|
104
|
+
})
|
|
105
|
+
],
|
|
106
|
+
envPrefix: 'VITE_', // Vite environment variables prefix
|
|
107
|
+
server: {
|
|
108
|
+
port: Number(process.env.VITE_SERVER_PORT || 3200)
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 2. Application Configuration Class
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
// src/base/cases/AppConfig.ts
|
|
117
|
+
export class AppConfig implements EnvConfigInterface {
|
|
118
|
+
/**
|
|
119
|
+
* Application name
|
|
120
|
+
* @description Injected from VITE_APP_NAME environment variable
|
|
121
|
+
*/
|
|
122
|
+
readonly appName = '';
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Application version
|
|
126
|
+
* @description Injected from VITE_APP_VERSION environment variable
|
|
127
|
+
*/
|
|
128
|
+
readonly appVersion = '';
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Current environment mode
|
|
132
|
+
* @description Retrieved from Vite's mode
|
|
133
|
+
*/
|
|
134
|
+
readonly env: string = import.meta.env.MODE;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* User token storage key
|
|
138
|
+
* @description Injected from VITE_USER_TOKEN_STORAGE_KEY environment variable
|
|
139
|
+
*/
|
|
140
|
+
readonly userTokenStorageKey = '__fe_user_token__';
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* AI API base URL
|
|
144
|
+
* @description Injected from VITE_AI_API_BASE_URL environment variable
|
|
145
|
+
*/
|
|
146
|
+
readonly aiApiBaseUrl = 'https://api.openai.com/v1';
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* AI API token
|
|
150
|
+
* @description Injected from VITE_AI_API_TOKEN environment variable
|
|
151
|
+
*/
|
|
152
|
+
readonly aiApiToken = '';
|
|
153
|
+
|
|
154
|
+
// ... more configuration items
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### 3. Injection in 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, // Injection target
|
|
171
|
+
source: {
|
|
172
|
+
...import.meta.env, // Environment variables source
|
|
173
|
+
[envPrefix + 'BOOT_HREF']: root.location.href
|
|
174
|
+
},
|
|
175
|
+
prefix: envPrefix, // Environment variables prefix
|
|
176
|
+
blackList: envBlackList // Blacklist (variables not to inject)
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Multi-Environment Configuration
|
|
182
|
+
|
|
183
|
+
### 1. Development Environment Configuration
|
|
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. Testing Environment Configuration
|
|
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. Production Environment Configuration
|
|
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. Local Override Configuration
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
# .env.local (not committed to git)
|
|
228
|
+
VITE_API_KEY=your_secret_key
|
|
229
|
+
VITE_LOCAL_DEBUG=true
|
|
230
|
+
VITE_CUSTOM_FEATURE=true
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Usage in Code
|
|
234
|
+
|
|
235
|
+
### 1. Direct Use of Environment Variables
|
|
236
|
+
|
|
237
|
+
```tsx
|
|
238
|
+
// Using in components directly
|
|
239
|
+
function App() {
|
|
240
|
+
const apiUrl = import.meta.env.VITE_API_BASE_URL;
|
|
241
|
+
const isDebug = import.meta.env.VITE_DEBUG === 'true';
|
|
242
|
+
|
|
243
|
+
return (
|
|
244
|
+
<div>
|
|
245
|
+
<p>API URL: {apiUrl}</p>
|
|
246
|
+
{isDebug && <p>Debug mode enabled</p>}
|
|
247
|
+
</div>
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### 2. Using Through AppConfig
|
|
253
|
+
|
|
254
|
+
```tsx
|
|
255
|
+
// Getting configuration through IOC
|
|
256
|
+
function UserService() {
|
|
257
|
+
const appConfig = IOC(IOCIdentifier.AppConfig);
|
|
258
|
+
|
|
259
|
+
const apiUrl = appConfig.aiApiBaseUrl;
|
|
260
|
+
const token = appConfig.aiApiToken;
|
|
261
|
+
|
|
262
|
+
// Using configuration for API calls
|
|
263
|
+
const response = await fetch(`${apiUrl}/chat`, {
|
|
264
|
+
headers: {
|
|
265
|
+
Authorization: `Bearer ${token}`
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### 3. Using in Services
|
|
272
|
+
|
|
273
|
+
```tsx
|
|
274
|
+
@injectable()
|
|
275
|
+
export class ApiService {
|
|
276
|
+
constructor(@inject(IOCIdentifier.AppConfig) private appConfig: AppConfig) {}
|
|
277
|
+
|
|
278
|
+
async makeRequest() {
|
|
279
|
+
const baseUrl = this.appConfig.aiApiBaseUrl;
|
|
280
|
+
const token = this.appConfig.aiApiToken;
|
|
281
|
+
|
|
282
|
+
return fetch(`${baseUrl}/api/endpoint`, {
|
|
283
|
+
headers: {
|
|
284
|
+
Authorization: `Bearer ${token}`
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
## Environment Variables Injection Plugin
|
|
292
|
+
|
|
293
|
+
### 1. InjectEnv Plugin Working Principle
|
|
294
|
+
|
|
295
|
+
```tsx
|
|
296
|
+
// corekit-bridge/src/core/bootstrap/plugins/InjectEnv.ts
|
|
297
|
+
export class InjectEnv implements BootstrapExecutorPlugin {
|
|
298
|
+
readonly pluginName = 'InjectEnv';
|
|
299
|
+
|
|
300
|
+
constructor(protected options: InjectEnvConfig) {}
|
|
301
|
+
|
|
302
|
+
onBefore(): void {
|
|
303
|
+
const { target, source, prefix, blackList } = this.options;
|
|
304
|
+
|
|
305
|
+
// Iterate through target object properties
|
|
306
|
+
for (const key in target) {
|
|
307
|
+
if (blackList.includes(key)) {
|
|
308
|
+
continue; // Skip properties in blacklist
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
const value = target[key as keyof typeof target];
|
|
312
|
+
const envValue = this.env(key, value); // Get environment variable value
|
|
313
|
+
|
|
314
|
+
// If environment variable exists and differs from default value, inject it
|
|
315
|
+
if (!this.isEmpty(envValue) && envValue !== value) {
|
|
316
|
+
target[key as keyof typeof target] = envValue;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### 2. Environment Variable Retrieval Logic
|
|
324
|
+
|
|
325
|
+
```tsx
|
|
326
|
+
env<D>(key: string, defaultValue?: D): D {
|
|
327
|
+
const { prefix = '', source = {} } = this.options;
|
|
328
|
+
|
|
329
|
+
// Convert camelCase to SNAKE_CASE
|
|
330
|
+
const formattedKey = key.replace(/([a-z])([A-Z])/g, '$1_$2').toUpperCase();
|
|
331
|
+
const envKey = `${prefix}${formattedKey}`;
|
|
332
|
+
|
|
333
|
+
const value = source[envKey];
|
|
334
|
+
|
|
335
|
+
// If it's a JSON string, parse it
|
|
336
|
+
if (typeof value === 'string' && InjectEnv.isJSONString(value)) {
|
|
337
|
+
return JSON.parse(value);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return (value ?? defaultValue) as D;
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## Best Practices
|
|
345
|
+
|
|
346
|
+
### 1. Environment Variable Naming Conventions
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
# ✅ Good naming
|
|
350
|
+
VITE_APP_NAME=MyApp
|
|
351
|
+
VITE_API_BASE_URL=https://api.example.com
|
|
352
|
+
VITE_USER_TOKEN_STORAGE_KEY=user_token
|
|
353
|
+
VITE_DEBUG=true
|
|
354
|
+
|
|
355
|
+
# ❌ Bad naming
|
|
356
|
+
VITE_app_name=MyApp
|
|
357
|
+
VITE_API_BASE_URL=https://api.example.com
|
|
358
|
+
VITE_USER_TOKEN_STORAGE_KEY=user_token
|
|
359
|
+
VITE_DEBUG=true
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### 2. Sensitive Information Handling
|
|
363
|
+
|
|
364
|
+
```bash
|
|
365
|
+
# .env.local (not committed to git)
|
|
366
|
+
VITE_API_KEY=your_secret_key
|
|
367
|
+
VITE_DATABASE_PASSWORD=your_password
|
|
368
|
+
|
|
369
|
+
# .env.template (committed to git, as template)
|
|
370
|
+
VITE_API_KEY=your_api_key_here
|
|
371
|
+
VITE_DATABASE_PASSWORD=your_password_here
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### 3. Type Safety
|
|
375
|
+
|
|
376
|
+
```tsx
|
|
377
|
+
// Define environment variables type
|
|
378
|
+
interface EnvVariables {
|
|
379
|
+
VITE_APP_NAME: string;
|
|
380
|
+
VITE_API_BASE_URL: string;
|
|
381
|
+
VITE_DEBUG: boolean;
|
|
382
|
+
VITE_PORT: number;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// Use in AppConfig
|
|
386
|
+
export class AppConfig implements EnvConfigInterface {
|
|
387
|
+
readonly appName: string = '';
|
|
388
|
+
readonly apiBaseUrl: string = '';
|
|
389
|
+
readonly debug: boolean = false;
|
|
390
|
+
readonly port: number = 3000;
|
|
391
|
+
}
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### 4. Environment Variables Validation
|
|
395
|
+
|
|
396
|
+
```tsx
|
|
397
|
+
// Validate required environment variables at application startup
|
|
398
|
+
export class AppConfig implements EnvConfigInterface {
|
|
399
|
+
constructor() {
|
|
400
|
+
this.validateRequiredEnvVars();
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
private validateRequiredEnvVars(): void {
|
|
404
|
+
const required = ['VITE_API_BASE_URL', 'VITE_APP_NAME'];
|
|
405
|
+
|
|
406
|
+
for (const envVar of required) {
|
|
407
|
+
if (!import.meta.env[envVar]) {
|
|
408
|
+
throw new Error(`Missing required environment variable: ${envVar}`);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
## Debugging and Troubleshooting
|
|
416
|
+
|
|
417
|
+
### 1. Check Environment Variables Loading
|
|
418
|
+
|
|
419
|
+
```tsx
|
|
420
|
+
// Check environment variables in console
|
|
421
|
+
console.log('import.meta.env:', import.meta.env);
|
|
422
|
+
console.log('AppConfig:', IOC(IOCIdentifier.AppConfig));
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### 2. Common Issues
|
|
426
|
+
|
|
427
|
+
**Issue 1: Environment Variables Not Injected**
|
|
428
|
+
|
|
429
|
+
```bash
|
|
430
|
+
# Check environment variable prefix
|
|
431
|
+
# Make sure to use VITE_ prefix
|
|
432
|
+
VITE_APP_NAME=MyApp # ✅ Correct
|
|
433
|
+
APP_NAME=MyApp # ❌ Wrong, won't be injected
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
**Issue 2: Environment Variable Files Not Loaded**
|
|
437
|
+
|
|
438
|
+
```bash
|
|
439
|
+
# Check file naming
|
|
440
|
+
.env.development # ✅ Correct
|
|
441
|
+
.env.dev # ❌ Wrong, Vite doesn't recognize it
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
**Issue 3: Environment Variables Filtered by Blacklist**
|
|
445
|
+
|
|
446
|
+
```tsx
|
|
447
|
+
// Check blacklist configuration
|
|
448
|
+
export const envBlackList = ['env', 'userNodeEnv'];
|
|
449
|
+
// Make sure your environment variables are not in the blacklist
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### 3. Debugging Tools
|
|
453
|
+
|
|
454
|
+
```tsx
|
|
455
|
+
// Create debugging tool
|
|
456
|
+
export class EnvDebugger {
|
|
457
|
+
static logEnvVars(config: AppConfig): void {
|
|
458
|
+
console.group('Environment Variables Debug');
|
|
459
|
+
console.log('Current Mode:', import.meta.env.MODE);
|
|
460
|
+
console.log('AppConfig:', config);
|
|
461
|
+
console.log('All Env Vars:', import.meta.env);
|
|
462
|
+
console.groupEnd();
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// Use in development environment
|
|
467
|
+
if (import.meta.env.DEV) {
|
|
468
|
+
EnvDebugger.logEnvVars(IOC(IOCIdentifier.AppConfig));
|
|
469
|
+
}
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
## Summary
|
|
473
|
+
|
|
474
|
+
The environment variables injection system provides:
|
|
475
|
+
|
|
476
|
+
1. **Environment Isolation**: Different environments use different configurations
|
|
477
|
+
2. **Type Safety**: Type checking through TypeScript
|
|
478
|
+
3. **Centralized Management**: All configurations are managed uniformly in AppConfig
|
|
479
|
+
4. **Flexible Configuration**: Support for multiple environment variable files
|
|
480
|
+
5. **Security Handling**: Sensitive information can be managed locally through .env.local
|
|
481
|
+
|
|
482
|
+
Through proper use of environment variables injection, applications can run correctly in different environments while maintaining configuration flexibility and security.
|