Skip to content
This repository was archived by the owner on Jul 4, 2021. It is now read-only.

Commit 8ee092b

Browse files
authored
feat: add default lang and global scope plugin options for SFC i18n custom block (#109)
* feat: add `defaultSFCLang` and `globalSFCScope` configuration options * chore: exclude intellij/webstorm stuff from `.gitignore` * chore: add logic to use new configuration options only on SFC custom blocks * chore: remove extra comma * chore: add `defaultSFCLang` and `globalSFCScope` options on `test/utils.ts` on build function * test: add `defaultSFCLang` and `globalSFCScope` tests on custom blocks test: add `default-lang.vue` for `defaultSFCLang` and `globalSFCScope` tests * test: add `defaultSFCLang` and `globalSFCScope` snapshots tests * test: add `globalSFCScope and import` test * test: add `globalSFCScope and import` snapshot test * docs: correct some small errata and wording docs: add docs for `defaultSFCLang` and `globalSFCScope` * docs: add hint for `defaultSFCLang` and warning for `globalSFCScope`
1 parent cd1ba32 commit 8ee092b

File tree

9 files changed

+191
-7
lines changed

9 files changed

+191
-7
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ lib
66
*.swp
77
*~
88
examples/**/dist
9-
.env
9+
.env
10+
# intellij/webstorm stuff
11+
.idea/

README.md

Lines changed: 87 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ Also, if you do a production build with vite, Vue I18n will automatically bundle
9090

9191
### i18n resources pre-compilation
9292

93-
Since vue-i18n@v9.0, The locale messages are handled with message compiler, which converts them to javascript functions after compiling. After compiling, message compiler converts them into javascript functions, which can improve the performance of the application.
93+
Since vue-i18n@v9.0, the locale messages are handled with message compiler, which converts them to javascript functions after compiling. After compiling, message compiler converts them into javascript functions, which can improve the performance of the application.
9494

9595
However, with the message compiler, the javascript function conversion will not work in some environments (e.g. CSP). For this reason, vue-i18n@v9.0 and later offer a full version that includes compiler and runtime, and a runtime only version.
9696

@@ -122,7 +122,7 @@ export default defineConfig({
122122

123123
### i18n custom block
124124

125-
the below example that `examples/composition/App.vue` have i18n custom block:
125+
The below example that `examples/composition/App.vue` have `i18n` custom block:
126126

127127
```vue
128128
<template>
@@ -171,9 +171,10 @@ You can be used by specifying the following format in the `lang` attribute:
171171

172172
- json (default)
173173
- yaml
174+
- yml
174175
- json5
175176

176-
example `yaml` foramt:
177+
example `yaml` format:
177178

178179
```vue
179180
<i18n lang="yaml">
@@ -322,7 +323,7 @@ About details, See the below section
322323

323324
Whether pre-compile number and boolean values as message functions that return the string value.
324325

325-
for example, the following json resources:
326+
For example, the following json resources:
326327

327328
```json
328329
{
@@ -372,6 +373,88 @@ About details, See the below section
372373
}
373374
```
374375

376+
### `defaultSFCLang`
377+
378+
- **Type:** `string`
379+
- **Default:** `undefined`
380+
381+
Specify the content for all your inlined `i18n` custom blocks on your `SFC`.
382+
383+
`defaultSFCLang` must have one of the following values:
384+
385+
```
386+
- json
387+
- json5
388+
- yaml
389+
- yml
390+
```
391+
392+
On inlined `i18n` custom blocks that have specified the `lang` attribute, the `defaultSFCLang` is not applied.
393+
394+
For example, with `defaultSFCLang: "yaml"` or `defaultSFCLang: "yml"`, this custom block:
395+
```html
396+
<i18n lang="yaml">
397+
en:
398+
hello: Hello
399+
es:
400+
hello: Hola
401+
</i18n>
402+
```
403+
404+
and this another one, are equivalent:
405+
```html
406+
<i18n>
407+
en:
408+
hello: Hello
409+
es:
410+
hello: Hola
411+
</i18n>
412+
```
413+
414+
### `globalSFCScope`
415+
416+
- **Type:** `boolean`
417+
- **Default:** `undefined`
418+
419+
Whether to include all `i18n` custom blocks on your `SFC` on `global` scope.
420+
421+
If `true`, it will be applied to all inlined `i18n` or `imported` custom blocks.
422+
423+
**Warning**: beware enabling `globalSFCScope: true`, all `i18n` custom blocks in all your `SFC` will be on `global` scope.
424+
425+
For example, with `globalSFCScope: true`, this custom block:
426+
427+
```html
428+
<i18n lang="yaml" global>
429+
en:
430+
hello: Hello
431+
es:
432+
hello: Hola
433+
</i18n>
434+
```
435+
436+
and this another one, are equivalent:
437+
438+
```html
439+
<i18n lang="yaml">
440+
en:
441+
hello: Hello
442+
es:
443+
hello: Hola
444+
</i18n>
445+
```
446+
447+
You can also use `defaultSFCLang: "yaml"`, following with previous example, this another is also equivalent to previous ones:
448+
449+
```html
450+
<i18n>
451+
en:
452+
hello: Hello
453+
es:
454+
hello: Hola
455+
</i18n>
456+
```
457+
375458
## :scroll: Changelog
376459

377460
Details changes for each release are documented in the [CHANGELOG.md](https://github.com/intlify/vite-plugin-vue-i18n/blob/master/CHANGELOG.md).

src/index.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ function pluginI18n(
5151
const fullIinstall = isBoolean(options.fullInstall)
5252
? options.fullInstall
5353
: true
54+
const defaultSFCLang = isString(options.defaultSFCLang)
55+
? options.defaultSFCLang
56+
: undefined
57+
const globalSFCScope = isBoolean(options.globalSFCScope)
58+
? options.globalSFCScope
59+
: false
5460
let config: ResolvedConfig | null = null
5561

5662
return {
@@ -187,12 +193,19 @@ function pluginI18n(
187193
if ('src' in query) {
188194
if (isString(query.lang)) {
189195
langInfo = query.lang === 'i18n' ? 'json' : query.lang
196+
} else if (defaultSFCLang) {
197+
langInfo = defaultSFCLang
190198
}
191199
} else {
192200
if (isString(query.lang)) {
193201
langInfo = query.lang
202+
} else if (defaultSFCLang) {
203+
langInfo = defaultSFCLang
194204
}
195205
}
206+
if (!parseOptions.isGlobal && globalSFCScope) {
207+
parseOptions.isGlobal = true
208+
}
196209
const generate = /\.?json5?/.test(langInfo)
197210
? generateJSON
198211
: generateYAML

src/options.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@ export type VitePluginVueI18nOptions = {
44
compositionOnly?: boolean
55
fullInstall?: boolean
66
include?: string | string[]
7+
defaultSFCLang?: 'json' | 'json5' | 'yml' | 'yaml'
8+
globalSFCScope?: boolean
79
}

test/__snapshots__/custom-block.test.ts.snap

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,32 @@ Array [
1313
]
1414
`;
1515

16+
exports[`default lang 1`] = `
17+
Array [
18+
Object {
19+
"locale": "",
20+
"resource": Object {
21+
"en": Object {
22+
"hello": [Function],
23+
},
24+
},
25+
},
26+
]
27+
`;
28+
29+
exports[`default lang and global scope 1`] = `
30+
Array [
31+
Object {
32+
"locale": "",
33+
"resource": Object {
34+
"en": Object {
35+
"hello": [Function],
36+
},
37+
},
38+
},
39+
]
40+
`;
41+
1642
exports[`global 1`] = `
1743
Array [
1844
Object {
@@ -37,6 +63,19 @@ Array [
3763
]
3864
`;
3965

66+
exports[`global scope and import 1`] = `
67+
Array [
68+
Object {
69+
"locale": "",
70+
"resource": Object {
71+
"en": Object {
72+
"hello": [Function],
73+
},
74+
},
75+
},
76+
]
77+
`;
78+
4079
exports[`import 1`] = `
4180
Array [
4281
Object {

test/custom-block.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,35 @@ test('global', async () => {
104104
expect(g.locale).toEqual('')
105105
expect(g.resource.en.hello(createMessageContext())).toEqual('hello global!')
106106
})
107+
108+
test('default lang', async () => {
109+
const { module } = await bundleAndRun('default-lang.vue', {
110+
defaultSFCLang: 'yml'
111+
})
112+
expect(module.__i18n).toMatchSnapshot()
113+
const l = module.__i18n.pop()
114+
expect(l.resource.en.hello(createMessageContext())).toEqual(
115+
'hello from defaults!'
116+
)
117+
})
118+
119+
test('default lang and global scope', async () => {
120+
const { module } = await bundleAndRun('default-lang.vue', {
121+
defaultSFCLang: 'yml',
122+
globalSFCScope: true
123+
})
124+
expect(module.__i18nGlobal).toMatchSnapshot()
125+
const g = module.__i18nGlobal.pop()
126+
expect(g.resource.en.hello(createMessageContext())).toEqual(
127+
'hello from defaults!'
128+
)
129+
})
130+
131+
test('global scope and import', async () => {
132+
const { module } = await bundleAndRun('global-scope-import.vue', {
133+
globalSFCScope: true
134+
})
135+
expect(module.__i18nGlobal).toMatchSnapshot()
136+
const g = module.__i18nGlobal.pop()
137+
expect(g.resource.en.hello(createMessageContext())).toEqual('hello world!')
138+
})

test/fixtures/default-lang.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<i18n>
2+
en:
3+
hello: hello from defaults!
4+
</i18n>

test/fixtures/global-scope-import.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<i18n src="./message.json">
2+
</i18n>

test/utils.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isBoolean } from '@intlify/shared'
1+
import { isBoolean, isString } from '@intlify/shared'
22
import path from 'path'
33
import { build } from 'vite'
44
import vue from '@vitejs/plugin-vue'
@@ -18,6 +18,12 @@ async function bundle(fixture: string, options: Record<string, unknown> = {}) {
1818
? 'info'
1919
: 'silent'
2020
: 'silent'
21+
const defaultSFCLang = isString(options.defaultSFCLang)
22+
? options.defaultSFCLang
23+
: undefined
24+
const globalSFCScope = isBoolean(options.globalSFCScope)
25+
? options.globalSFCScope
26+
: undefined
2127

2228
const alias: Record<string, string> = {
2329
vue: 'vue/dist/vue.runtime.esm-browser.js'
@@ -26,7 +32,8 @@ async function bundle(fixture: string, options: Record<string, unknown> = {}) {
2632
alias['~target'] = path.resolve(__dirname, target, fixture)
2733
}
2834

29-
const plugins = [vue(), vueI18n({ include })]
35+
// @ts-ignore
36+
const plugins = [vue(), vueI18n({ include, defaultSFCLang, globalSFCScope })]
3037
if (options.intlify) {
3138
const intlifyVue = (await import('../src/injection')).default
3239
plugins.push(intlifyVue(options.intlify as InjectionValues))

0 commit comments

Comments
 (0)