0
# Resource Processing
1
2
Pre-compilation and transformation of i18n resource files including JSON, YAML, JavaScript, and TypeScript locale files. Handles static bundling and virtual module generation.
3
4
## Capabilities
5
6
### Virtual Module System
7
8
Access to pre-compiled locale messages through virtual imports.
9
10
```typescript { .api }
11
/**
12
* Virtual module providing all compiled locale messages
13
* Automatically merges all included locale resources by locale key
14
*/
15
declare module '@intlify/unplugin-vue-i18n/messages' {
16
import type { I18nOptions } from 'vue-i18n';
17
const messages: I18nOptions['messages'];
18
export default messages;
19
}
20
```
21
22
**Usage Example:**
23
24
```typescript
25
import { createI18n } from 'vue-i18n';
26
import messages from '@intlify/unplugin-vue-i18n/messages';
27
28
const i18n = createI18n({
29
locale: 'en',
30
messages // Pre-compiled and merged messages
31
});
32
```
33
34
### Static Resource Importing
35
36
Individual locale file imports with pre-compilation.
37
38
```typescript { .api }
39
/**
40
* Import individual locale files
41
* Files are pre-compiled based on their format
42
*/
43
declare module '*.json' {
44
const messages: Record<string, any>;
45
export default messages;
46
}
47
48
declare module '*.yaml' {
49
const messages: Record<string, any>;
50
export default messages;
51
}
52
53
declare module '*.yml' {
54
const messages: Record<string, any>;
55
export default messages;
56
}
57
58
declare module '*.json5' {
59
const messages: Record<string, any>;
60
export default messages;
61
}
62
```
63
64
**Usage Example:**
65
66
```typescript
67
// Individual imports
68
import en from './locales/en.json';
69
import fr from './locales/fr.yaml';
70
import de from './locales/de.json5';
71
72
const i18n = createI18n({
73
locale: 'en',
74
messages: { en, fr, de }
75
});
76
```
77
78
### Supported File Formats
79
80
The plugin supports multiple locale resource formats with automatic format detection.
81
82
```typescript { .api }
83
/**
84
* Supported locale resource formats
85
*/
86
type SupportedFormats =
87
| 'json' // Standard JSON format
88
| 'json5' // JSON5 with comments and trailing commas
89
| 'yaml' // YAML format
90
| 'yml' // YAML format (alternative extension)
91
| 'js' // JavaScript modules with export default
92
| 'ts'; // TypeScript modules with export default
93
```
94
95
### Resource Configuration
96
97
Configure how resources are processed and included.
98
99
```typescript { .api }
100
interface ResourceProcessingOptions {
101
/**
102
* Pattern(s) to include i18n resource files
103
* Supports glob patterns and arrays
104
*/
105
include?: string | string[];
106
107
/**
108
* Specific locales to include in bundle
109
* Other locales will be excluded
110
*/
111
onlyLocales?: string | string[];
112
113
/**
114
* Allow dynamic resource construction for JS/TS files
115
* Enables programmatic message loading
116
* @default false
117
*/
118
allowDynamic?: boolean;
119
120
/**
121
* Force stringify non-string values (numbers, booleans, null)
122
* Converts them to message functions returning strings
123
* @default false
124
*/
125
forceStringify?: boolean;
126
}
127
```
128
129
### JavaScript/TypeScript Resources
130
131
Handle JavaScript and TypeScript locale files with both static and dynamic patterns.
132
133
```typescript { .api }
134
/**
135
* Static export pattern for JS/TS resources
136
*/
137
interface StaticJSResource {
138
// Simple default export of locale object
139
export default {
140
hello: 'Hello, {name}!',
141
welcome: 'Welcome to our app'
142
};
143
}
144
145
/**
146
* Dynamic resource construction for JS/TS files
147
* Requires allowDynamic: true
148
*/
149
interface DynamicJSResource {
150
// Export function for dynamic resource construction
151
export default async function loadResource(url?: string): Promise<Record<string, any>>;
152
}
153
```
154
155
**Static JS/TS Example:**
156
157
```javascript
158
// locales/en.js
159
export default {
160
greeting: 'Hello, {name}!',
161
navigation: {
162
home: 'Home',
163
about: 'About',
164
contact: 'Contact'
165
},
166
validation: {
167
required: 'This field is required',
168
email: 'Please enter a valid email'
169
}
170
};
171
```
172
173
**Dynamic JS/TS Example:**
174
175
```javascript
176
// locales/dynamic.js
177
import baseMessages from './base.json';
178
179
export default async function loadResource(url) {
180
// Fetch additional resources from backend
181
const dynamicMessages = await fetch('/api/messages').then(r => r.json());
182
183
// Merge with base messages
184
return {
185
...baseMessages,
186
...dynamicMessages
187
};
188
}
189
```
190
191
### YAML Resource Processing
192
193
YAML files with support for nested structures and multi-document files.
194
195
**YAML Example:**
196
197
```yaml
198
# locales/en.yaml
199
greeting: Hello, {name}!
200
navigation:
201
home: Home
202
about: About
203
contact: Contact
204
validation:
205
required: This field is required
206
email: Please enter a valid email
207
minLength: Must be at least {min} characters
208
```
209
210
**YAML Limitations:**
211
212
```typescript { .api }
213
/**
214
* YAML processing limitations
215
*/
216
interface YAMLLimitations {
217
// Not supported:
218
multiDocument: false; // Files with multiple documents (---)
219
aliases: false; // Aliases with & and *
220
customTags: false; // Custom tags with !
221
complexKeys: false; // Non-string keys
222
223
// Supported:
224
nestedObjects: true; // Nested object structures
225
arrays: true; // Array values
226
stringInterpolation: true; // String values with placeholders
227
}
228
```
229
230
### Message Pre-compilation
231
232
Transform locale messages into optimized JavaScript functions at build time.
233
234
```typescript { .api }
235
/**
236
* Pre-compilation transforms messages into executable functions
237
*/
238
interface PreCompiledMessage {
239
// Original: "Hello, {name}!"
240
// Compiled to:
241
(ctx: MessageContext): string;
242
source: string; // Original message string
243
}
244
245
interface MessageContext {
246
normalize: (values: any[]) => string;
247
interpolate: (values: any[]) => string;
248
// Additional context methods
249
}
250
```
251
252
**Pre-compilation Example:**
253
254
```javascript
255
// Original JSON
256
{
257
"greeting": "Hello, {name}!",
258
"count": "You have {count} message | You have {count} messages"
259
}
260
261
// Pre-compiled output (development)
262
{
263
greeting: (() => {
264
const fn = (ctx) => {
265
const { normalize: _normalize, interpolate: _interpolate } = ctx;
266
return _interpolate([
267
_normalize(['Hello, ']),
268
_interpolate([_normalize(['name'])]),
269
_normalize(['!'])
270
]);
271
};
272
fn.source = 'Hello, {name}!';
273
return fn;
274
})(),
275
276
count: (() => {
277
const fn = (ctx) => {
278
const { normalize: _normalize, plural: _plural } = ctx;
279
return _plural([
280
_normalize(['You have ', ['count'], ' message']),
281
_normalize(['You have ', ['count'], ' messages'])
282
]);
283
};
284
fn.source = 'You have {count} message | You have {count} messages';
285
return fn;
286
})()
287
}
288
```
289
290
### Resource Merging Strategy
291
292
How multiple resource files are merged when using the virtual module.
293
294
```typescript { .api }
295
/**
296
* Resource merging strategy for virtual module
297
*/
298
interface ResourceMerging {
299
/**
300
* Files are grouped by locale identifier
301
* Locale is determined by filename or directory structure
302
*/
303
localeResolution: 'filename' | 'directory';
304
305
/**
306
* Merge strategy for conflicting keys
307
*/
308
conflictResolution: 'last-wins' | 'deep-merge';
309
310
/**
311
* Example file structure:
312
* - locales/en.json -> locale: 'en'
313
* - locales/en/common.json -> locale: 'en'
314
* - locales/fr/errors.yaml -> locale: 'fr'
315
*/
316
}
317
```
318
319
**File Structure Examples:**
320
321
```typescript
322
// Flat structure
323
// locales/en.json
324
// locales/fr.yaml
325
// locales/de.json5
326
// Results in: { en: {...}, fr: {...}, de: {...} }
327
328
// Nested structure
329
// locales/en/common.json
330
// locales/en/errors.json
331
// locales/fr/common.yaml
332
// Results in: { en: { ...common, ...errors }, fr: { ...common } }
333
334
// Mixed structure
335
// locales/base.json (no locale, skipped)
336
// locales/en-US.json -> locale: 'en-US'
337
// locales/zh-CN/app.yaml -> locale: 'zh-CN'
338
```
339
340
### Configuration Examples
341
342
**Basic Resource Processing:**
343
344
```typescript
345
VueI18nPlugin({
346
include: [
347
path.resolve(__dirname, './src/locales/**'),
348
]
349
});
350
```
351
352
**Advanced Resource Processing:**
353
354
```typescript
355
VueI18nPlugin({
356
include: [
357
'./locales/**/*.{json,yaml,yml,json5}',
358
'./src/components/**/*.json',
359
'./modules/**/i18n/*.js'
360
],
361
onlyLocales: ['en', 'fr', 'de', 'es'],
362
allowDynamic: true,
363
forceStringify: true
364
});
365
```
366
367
**Dynamic Resource Loading:**
368
369
```typescript
370
VueI18nPlugin({
371
include: ['./locales/**/*.js'],
372
allowDynamic: true
373
});
374
375
// In locale file
376
export default async function(url) {
377
const base = await import('./base.json');
378
const dynamic = await fetch('/api/locale-data').then(r => r.json());
379
return { ...base.default, ...dynamic };
380
}
381
```