diff --git a/packages/unplugin-vue-i18n/README.md b/packages/unplugin-vue-i18n/README.md index fd422090..dba61a21 100644 --- a/packages/unplugin-vue-i18n/README.md +++ b/packages/unplugin-vue-i18n/README.md @@ -227,6 +227,8 @@ export default defineConfig({ ], }) ``` +unplugin-vue-i18n will automatically merge locale files into `@intlify/unplugin-vue-i18n/messages`. This allows locales to be split across multiple files, for example `src/locales/fruits/en.json` and `src/locales/vegetables/en.json`. + ### Types If you want type definition of `@intlify/unplugin-vue-i18n/messages`, add `unplugin-vue-i18n/messages` to `compilerOptions.types` of your tsconfig: diff --git a/packages/unplugin-vue-i18n/examples/vite/src/locales/en.yaml b/packages/unplugin-vue-i18n/examples/vite/src/locales/en.yaml index 85d055d8..137f0d40 100644 --- a/packages/unplugin-vue-i18n/examples/vite/src/locales/en.yaml +++ b/packages/unplugin-vue-i18n/examples/vite/src/locales/en.yaml @@ -1,3 +1 @@ select: Do you want banana? -fruits: - banana: 'no bananas | {n} banana | {n} bananas' diff --git a/packages/unplugin-vue-i18n/examples/vite/src/locales/fruits/en.yaml b/packages/unplugin-vue-i18n/examples/vite/src/locales/fruits/en.yaml new file mode 100644 index 00000000..3232466c --- /dev/null +++ b/packages/unplugin-vue-i18n/examples/vite/src/locales/fruits/en.yaml @@ -0,0 +1,2 @@ +fruits: + banana: 'no bananas | {n} banana | {n} bananas' diff --git a/packages/unplugin-vue-i18n/examples/vite/src/locales/fruits/ja.json5 b/packages/unplugin-vue-i18n/examples/vite/src/locales/fruits/ja.json5 new file mode 100644 index 00000000..48a7d903 --- /dev/null +++ b/packages/unplugin-vue-i18n/examples/vite/src/locales/fruits/ja.json5 @@ -0,0 +1,5 @@ +{ + fruits: { + banana: 'バナナがない | バナナ {n} 個' + } +} diff --git a/packages/unplugin-vue-i18n/examples/vite/src/locales/ja.json5 b/packages/unplugin-vue-i18n/examples/vite/src/locales/ja.json5 index 5dd49f4d..a19a9d4a 100644 --- a/packages/unplugin-vue-i18n/examples/vite/src/locales/ja.json5 +++ b/packages/unplugin-vue-i18n/examples/vite/src/locales/ja.json5 @@ -1,6 +1,3 @@ { - select: "バナナが欲しい?", - fruits: { - banana: "バナナがない | バナナ {n} 個" - } + select: 'バナナが欲しい?' } diff --git a/packages/unplugin-vue-i18n/examples/vite/src/main.ts b/packages/unplugin-vue-i18n/examples/vite/src/main.ts index 22f35749..2d4d83ce 100644 --- a/packages/unplugin-vue-i18n/examples/vite/src/main.ts +++ b/packages/unplugin-vue-i18n/examples/vite/src/main.ts @@ -1,17 +1,12 @@ import { createApp } from 'vue' import { createI18n } from 'vue-i18n' import App from './App.vue' -import ja from './locales/ja.json5' -import en from './locales/en.yaml' -// import messages from '@intlify/vite-plugin-vue-i18n/messages' +import messages from '@intlify/unplugin-vue-i18n/messages' const i18n = createI18n({ legacy: false, locale: 'ja', - messages: { - ja, - en - } + messages }) const app = createApp(App) diff --git a/packages/unplugin-vue-i18n/src/index.ts b/packages/unplugin-vue-i18n/src/index.ts index 0a03893a..3693d7fd 100644 --- a/packages/unplugin-vue-i18n/src/index.ts +++ b/packages/unplugin-vue-i18n/src/index.ts @@ -703,9 +703,29 @@ async function generateBundleResources( } } - return `export default { - ${codes.join(`,\n`)} -}` + return `const isObject = (item) => item && typeof item === 'object' && !Array.isArray(item); + +const mergeDeep = (target, ...sources) => { + if (!sources.length) return target; + const source = sources.shift(); + + if (isObject(target) && isObject(source)) { + for (const key in source) { + if (isObject(source[key])) { + if (!target[key]) Object.assign(target, { [key]: {} }); + mergeDeep(target[key], source[key]); + } else { + Object.assign(target, { [key]: source[key] }); + } + } + } + + return mergeDeep(target, ...sources); +} + +export default mergeDeep({}, + ${codes.map(code => `{${code}}`).join(',\n')} +);` } async function getCode(