Skip to content

Commit

Permalink
feat(unplugin-vue-i18n): support compatibility i18n custom blocks for…
Browse files Browse the repository at this point in the history
… legacy vue-i18n v8.x (#332)

* feat(unplugin-vue-i18n): support compatibility i18n custom blocks for legacy vue-i18n v8.x

* fix: remove debug console
  • Loading branch information
kazupon committed Dec 13, 2023
1 parent eb59b1e commit 1c95f68
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 10 deletions.
38 changes: 28 additions & 10 deletions packages/unplugin-vue-i18n/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,13 +281,13 @@ This plugin will automatically select and bundle `petite-vue-i18n` build accordi

If nothing is specified for this option, i.e. `undefined`, nothing is done to the resource in the above format.

> ⚠️ NOTE:
> ⚠️ NOTE:
`json` resources matches this option, it will be handled **before the internal json plugin of bundler, and will not be processed afterwards**, else the option doesn't match, the bundler side will handle.

> ⚠️ NOTE:
> ⚠️ NOTE:
`yaml` resources don't support multi documentation with `|`, alias with `&` and `*`, tags with `! `, `@`, etc. Only simple data structures.

> ⚠️ NOTE:
> ⚠️ NOTE:
`js` and `ts` resources are set **simple export (`export default`) as locale messages object, as default**.

```js
Expand All @@ -299,7 +299,7 @@ This plugin will automatically select and bundle `petite-vue-i18n` build accordi

If you need to use programmatically dynamic resource construction, you would be enable `allowDynamic` option. about details, see the section.

> ⚠️ NOTE:
> ⚠️ NOTE:
If you use the `js` and `ts` resources formats, set the paths, so your application code is not targeted. We recommend that resources be isolated from the application code.


Expand Down Expand Up @@ -354,12 +354,12 @@ This plugin will automatically select and bundle `petite-vue-i18n` build accordi

Whether locale mesages should be compiled by JIT (Just in Time) compilation with vue-i18n's message compiler.

> ⚠️ NOTE:
> ⚠️ NOTE:
This option works with vue-i18n v9.3 and later.

JIT compilation has been supported since vue-i18n v9.3. This means that since v9 was released until now, the message compiler compiles to executable JavaScript code, however it did not work in the CSP environment. Also, since this was an AOT (Ahead of Time) compilation, it was not possible to dynamically retrieve locale messages from the back-end Database and compose locale mesages with programatic.

> ⚠️ NOTE:
> ⚠️ NOTE:
Enabling JIT compilation causes the message compiler to generate AST objects for locale mesages instead of JavaScript code. If you pre-compile locale messages with a tool such as the [Intlify CLI](https://github.com/intlify/cli) and import them dynamically, you need to rebuild that resource.

About JIT compilation, See [here](https://vue-i18n.intlify.dev/guide/advanced/optimization.html#jit-compilation)
Expand All @@ -373,10 +373,10 @@ Whether to tree-shake message compiler when we will be bundling.

If do you will use this option, you need to enable `jitCompilation` option.

> ⚠️ NOTE:
> ⚠️ NOTE:
This option works with vue-i18n v9.3 and later.

> ⚠️ NOTE:
> ⚠️ NOTE:
If you enable this option, **you should check resources in your application are pre-compiled with this plugin.** If you will be loading resources dynamically from the back-end via the API, enabling this option do not work because there is not message compiler.

### `ssr`
Expand All @@ -386,7 +386,7 @@ If you enable this option, **you should check resources in your application are

Whether to bundle vue-i18n module for SSR at build time

> ⚠️ NOTE:
> ⚠️ NOTE:
This option works with vue-i18n v9.4 and later.

### `runtimeOnly`
Expand All @@ -395,7 +395,7 @@ If you enable this option, **you should check resources in your application are
- **Default:** `true`

Whether or not to automatically use Vue I18n **runtime-only** in production build, set `vue-i18n.runtime.esm-bundler.js` in the `vue-i18n` field of bundler config, the below:

```
- vite config: `resolve.alias`
- webpack config: `resolve.alias`
Expand Down Expand Up @@ -547,6 +547,24 @@ If you enable this option, **you should check resources in your application are

> ⚠️ Note that if you set `bridge: true`, the bundle size will increase. It is recommended to disable this mode after the migration from [email protected] to [email protected] is completed.
### `legacy`

- **Type:** `boolean`
- **Default:** `false`

This option supports Vue I18n v8.x compatibility for resources in i18n custom blocks.

> ⚠️ To work for Vue 2.7, the value of `vueVersion` must be set to `'v2.7'`.
### `vueVersion`

- **Type:** `string`
- **Default:** `undefined`

The version of Vue that will be used by Vue I18n. This option is enabled when the `legacy` option is `true`.

Available values are `'v2.6'` and `'v2.7'`.

### `esm`

- **Type:** `boolean`
Expand Down
17 changes: 17 additions & 0 deletions packages/unplugin-vue-i18n/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ export const unplugin = createUnplugin<PluginOptions>((options = {}, meta) => {
const bridge = !!options.bridge
debug('bridge', bridge)

const legacy = !!options.legacy
debug('legacy', legacy)

const vueVersion = isString(options.vueVersion)
? options.vueVersion
: undefined

const runtimeOnly = isBoolean(options.runtimeOnly)
? options.runtimeOnly
: true
Expand Down Expand Up @@ -354,6 +361,8 @@ export const unplugin = createUnplugin<PluginOptions>((options = {}, meta) => {
strictMessage,
escapeHtml,
bridge,
legacy,
vueVersion,
jit: jitCompilation,
onlyLocales,
exportESM: esm,
Expand Down Expand Up @@ -636,6 +645,8 @@ export const unplugin = createUnplugin<PluginOptions>((options = {}, meta) => {
isGlobal: globalSFCScope,
useClassComponent,
bridge,
legacy,
vueVersion,
jit: jitCompilation,
strictMessage,
escapeHtml,
Expand Down Expand Up @@ -863,6 +874,8 @@ function getOptions(
forceStringify = false,
isGlobal = false,
bridge = false,
legacy = false,
vueVersion = 'v2.6',
onlyLocales = [],
exportESM = true,
useClassComponent = false,
Expand All @@ -875,6 +888,8 @@ function getOptions(
forceStringify?: boolean
isGlobal?: boolean
bridge?: boolean
legacy?: boolean
vueVersion?: CodeGenOptions['vueVersion']
onlyLocales?: string[]
exportESM?: boolean
useClassComponent?: boolean
Expand All @@ -896,6 +911,8 @@ function getOptions(
strictMessage,
escapeHtml,
bridge,
legacy,
vueVersion,
jit,
onlyLocales,
exportESM,
Expand Down
4 changes: 4 additions & 0 deletions packages/unplugin-vue-i18n/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { CodeGenOptions } from '@intlify/bundle-utils'

export type SFCLangFormat = 'json' | 'json5' | 'yml' | 'yaml'
export interface PluginOptions {
include?: string | string[]
Expand All @@ -14,6 +16,8 @@ export interface PluginOptions {
defaultSFCLang?: SFCLangFormat
globalSFCScope?: boolean
bridge?: boolean
legacy?: boolean
vueVersion?: CodeGenOptions['vueVersion']
useClassComponent?: boolean
useVueI18nImportName?: boolean
strictMessage?: boolean
Expand Down
4 changes: 4 additions & 0 deletions packages/unplugin-vue-i18n/test/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ export async function bundleAndRun(
options.sourcemap = isBoolean(options.sourcemap) || false
options.useClassComponent = isBoolean(options.useClassComponent) || false
options.bridge = isBoolean(options.bridge) || false
options.legacy = isBoolean(options.legacy) || false
options.vueVersion = isString(options.vueVersion)
? options.vueVersion
: 'v2.6'
options.allowDynamic = isBoolean(options.allowDynamic) || false
options.strictMessage = isBoolean(options.strictMessage)
? options.strictMessage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,26 @@ exports[`json5: exclude locales 1`] = `
]
`;

exports[`legacy for Vue 2.6 and before 1`] = `
"function block0(Component) {
Component.options.__i18n = Component.options.__i18n || [];
Component.options.__i18n.push('{\\"en\\":{\\"hello\\":\\"hello world!\\"}}');
delete Component.options._Ctor;
}
const _sfc_main = {};
if (typeof block0 === \\"function\\")
block0(_sfc_main);
const exports = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
default: _sfc_main
}, Symbol.toStringTag, { value: \\"Module\\" }));
if (typeof window !== \\"undefined\\") {
window.module = _sfc_main;
window.exports = exports;
}
"
`;

exports[`locale attr 1`] = `
[
{
Expand Down
17 changes: 17 additions & 0 deletions packages/unplugin-vue-i18n/test/vite/custom-block.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,23 @@ test('global scope and import', async () => {
expect(g.resource.en.hello(createMessageContext())).toEqual('hello world!')
})

test('legacy for Vue 2.6 and before', async () => {
const { code } = await bundleAndRun('basic.vue', bundleVite, {
legacy: true
})
expect(code).toMatchSnapshot()
expect(code).toMatch('Component.options.__i18n =')
})

test('legacy for Vue 2.7', async () => {
const { module } = await bundleAndRun('basic.vue', bundleVite, {
legacy: true,
vueVersion: 'v2.7'
})
const i18n = JSON.parse(module.__i18n.pop())
expect(i18n.en.hello).toEqual('hello world!')
})

test('array', async () => {
const { module } = await bundleAndRun('array.vue', bundleVite)
expect(module.__i18n).toMatchSnapshot()
Expand Down

0 comments on commit 1c95f68

Please sign in to comment.