Default Locale Messages
codetheorist opened this issue · comments
Module versions:
- Vue CLI: 4.x
vue-cli-plugin-i18n
: 2.x
To Reproduce
Steps to reproduce the behavior:
- Create e new Vue app using the CLI
- Install the Vue I18n plugin
- Enable SFC I18n
- View i18n report to see warnings about missing & unused i18n messages
- View browser console to see warning about missing i18n message
Expected behavior
The installation creates a default file in the locale directory for the default locale. A component is also created, with an i18n
block, with a translated string and a call to $t
within the template to show this translated string.
All translated string keys should match however, the key created in the default locale file is different to that in the i18n block and the template section.
Additional context
As the key/value is in the SFC i18n block, then the component shows the string correctly however, there are still warnings produced due to the mismatch in data.
Thank you for your reporting!
@pixari
Could you help this issue?
I have a project that ran vue add i18n
before (on 12 May). It works just fine. Then I run into the same issue when I create a new project and ran vue add i18n
yesterday.
Turns out that the bug was introduced by the code generated by this plugin.
(I'm just a user and not good at webpack and vue-cli. Can't tell the reason why, but provide a solution that I and my collage founded out.)
Let's compare the key piece from generated code (complete code is at the end):
// before
messages[locale] = locales(key).default
// after
messages[locale] = locales(key)
The problem is that messages
option for createI18n
was in a wrong structure. And the real message is got one level deep. So a working example will be t("default.message")
.
The comparison:
Before:
{
"en": {
"default": {}
}
}
After:
{
"en": {}
}
Complete code comparison generated by vue add i18n
Before:
import { createI18n } from 'vue-i18n'
/**
* Load locale messages
*
* The loaded `JSON` locale messages is pre-compiled by `@intlify/vue-i18n-loader`, which is integrated into `vue-cli-plugin-i18n`.
* See: https://github.com/intlify/vue-i18n-loader#rocket-i18n-resource-pre-compilation
*/
function loadLocaleMessages() {
const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i)
const messages = {}
locales.keys().forEach(key => {
const matched = key.match(/([A-Za-z0-9-_]+)\./i)
if (matched && matched.length > 1) {
const locale = matched[1]
messages[locale] = locales(key).default
}
})
return messages
}
export default createI18n({
locale: process.env.VUE_APP_I18N_LOCALE || 'en',
fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
messages: loadLocaleMessages()
})
After:
import { createI18n } from 'vue-i18n'
/**
* Load locale messages
*
* The loaded `JSON` locale messages is pre-compiled by `@intlify/vue-i18n-loader`, which is integrated into `vue-cli-plugin-i18n`.
* See: https://github.com/intlify/vue-i18n-loader#rocket-i18n-resource-pre-compilation
*/
function loadLocaleMessages() {
const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i)
const messages = {}
locales.keys().forEach(key => {
const matched = key.match(/([A-Za-z0-9-_]+)\./i)
if (matched && matched.length > 1) {
const locale = matched[1]
messages[locale] = locales(key)
}
})
return messages
}
export default createI18n({
legacy: false,
locale: process.env.VUE_APP_I18N_LOCALE || 'en',
fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
messages: loadLocaleMessages()
})