vue-i18n-loader - another webpack loader i18n solution for Vue (Nuxt) with auto generated keys.
Currently under development, pull requests and suggestions are welcome.
-
We need auto generated keys for texts to be translated
There are only two hard things in Computer Science: cache invalidation and naming things. -- Phil Karlton
Most i18n solutions ask developers to name each text with a unique key, like
$t("message.hello")
, naming is so annoying, it's not reasonable to waste time doing this job -
Text translations should be put just beside source codes
Some solutions extract all texts to a single json file, it's not conform to modularization
- Find automatically texts to translate by two means: regex string or 'delimiter'(Refer to usage below).
- Keep first 8 characters of every matched text as key (and append 4 characters md5 hash to the key if the text is longer than 8)
- Replace texts by translator markups using regex
- Create or update
filename.messages.json
to store translations, import this file infilename.vue
-
Since
this
at the top level of es6 module bind toundefined
, but not the vue instance.All target texts in script part should be put in functions(not fat arrow functions refer to this doc)
Config example based on Nuxt.js.
Given regString
, the loader will match all texts/attributes/string templates by new RegExp(regString)
Given delimiter
, the loader will ignore regString
, The loader will match all texts between delimiter
, for example ##text##
.
{
test: /\.vue$/,
exclude: [/node_modules/],
loader: 'vue-i18n-loader',
enforce: 'pre',
options: {
updateMessagesFile: ctx.isClient && ctx.isDev, // only update messages file when it's dev and client(when using ssr)
cacheTime: 3000,
// regString to match simplified chinese characters
regString: '[\u4e00-\u9fa5\u3002\uff1b\uff0c\uff1a\u2018\u2019\u201c\u201d\uff08\uff09\u3001\uff1f\uff01\ufe15\u300a\u300b]+',
// delimiter: '##', // match texts surrounded by '##', like '##text##'
// Loader will use existing translations, if there is not, will use text generated by translator
languages: [{
key: 'zh_Hans_CN',
translator: (matched) => {
// Delete repeat mark R, sometimes we need a text to be translated differentlyz`
return matched.replace(/^\[R\]+/, '')
}
}, {
key: 'zh_Hant_HK',
translator: (matched) => {
// example to auto translate simplified chinese to traditional
return chineseS2T.s2t(matched.replace(/^\[R\]+/, ''))
}
}, {
key: 'en_US',
// if translator is not given, the loader will use the default translator(translator of the first language, zh_Hans_CN here)
}],
}
}
An example of plugin can be:
import Vue from 'vue';
import {mapGetters} from 'vuex';
// !!! the key must be $lang, which will be referenced by the helper !!!
Vue.mixin({
computed: {
...mapGetters({'$lang': 'currentLang'}),
}
});
The helper will insert code automatically to refer this $lang
variable like this:
methods:{
$t(key){
if(!this.$lang && !messages["${defaultLang}"]) return key;
const trans = messages[this.$lang]||messages["${defaultLang}"]||{};
return trans[key];
},
}
defaultLang
is the first language key set in config, zh_Hans_CN
here in the example.
check the example directory:
- This example is based on Nuxt.js
- Download this example and start by
npm install
thennpm run dev
- Try changing texts and add some translations
We provide a cli tool to group all *.messages.json
and serve a web page for human translators
Please refer to the github repo of viai18n-cli
- Support JSX
- Add tests