i18next-scanner
i18next-scanner copied to clipboard
How to scan Vue i18next strings
Hi, I'm trying to activate scanner in Vue files using Vue i18next but I've not been able to achieve it.
Translations with Vue are treated like this:
- {{ $t('text') }} in .html files.
- this.$t('text') in .vue files.
Config:
module.exports = {
input: [
'frontend/templates/*.{htm,html,js,jsx}',
'assets/components/*.{htm,html,js,jsx,vue}',
// Use ! to filter out files or directories
'!app/**/*.spec.{js,jsx}',
'!app/i18n/**',
'!**/node_modules/**',
],
output: './',
options: {
debug: true,
func: {
list: ['i18next.t', 'i18n.t', 'this.$t', '$t'],
extensions: ['.js', '.jsx', '.vue']
},
trans: {
component: 'Trans',
i18nKey: 'i18nKey',
defaultsKey: 'defaults',
extensions: ['.vue','.js', '.jsx'],
fallbackKey: function(ns, value) {
return value;
},
acorn: {
ecmaVersion: 10, // defaults to 10
sourceType: 'module', // defaults to 'module'
// Check out https://github.com/acornjs/acorn/tree/master/acorn#interface for additional options
}
},
lngs: ['en','es'],
ns: [
'locale'
],
defaultLng: 'en',
defaultNs: 'locale',
defaultValue: '__STRING_NOT_TRANSLATED__',
resource: {
loadPath: 'assets/locales/{{lng}}/{{ns}}.json',
savePath: 'assets/locales/{{lng}}/{{ns}}.json',
jsonIndent: 4,
lineEnding: '\n'
},
nsSeparator: false, // namespace separator
keySeparator: false, // key separator
interpolation: {
prefix: '{{',
suffix: '}}'
}
},
transform: function customTransform(file, enc, done) {
"use strict";
const parser = this.parser;
const content = fs.readFileSync(file.path, enc);
let count = 0;
parser.parseFuncFromString(content, { list: ['i18next._', 'i18next.__', '$t', 'this.$t'] }, (key, options) => {
parser.set(key, Object.assign({}, options, {
nsSeparator: false,
keySeparator: false
}));
++count;
});
if (count > 0) {
console.log(`i18next-scanner: count=${chalk.cyan(count)}, file=${chalk.yellow(JSON.stringify(file.relative))}`);
}
done();
}
};
Thanks a lot for your help.
Hello! Try this config, I think you don't need trans and transform options.
module.exports = {
input: [
'frontend/templates/*.{htm,html,js,jsx}',
'assets/components/*.{htm,html,js,jsx,vue}',
// Use ! to filter out files or directories
'!app/**/*.spec.{js,jsx}',
'!app/i18n/**',
'!**/node_modules/**',
],
output: './',
options: {
debug: true,
func: {
list: ['$t'],
extensions: ['.js', '.jsx', '.vue', '.html', '.htm'],
},
trans: {
component: 'Trans',
extensions: [],
},
lngs: ['en', 'es'],
ns: ['locale'],
defaultLng: 'en',
defaultNs: 'locale',
defaultValue: '__STRING_NOT_TRANSLATED__',
resource: {
loadPath: 'assets/locales/{{lng}}/{{ns}}.json',
savePath: 'assets/locales/{{lng}}/{{ns}}.json',
jsonIndent: 4,
lineEnding: '\n',
},
nsSeparator: false, // namespace separator
keySeparator: false, // key separator
interpolation: {
prefix: '{{',
suffix: '}}',
},
},
};
If it shows errors, please send it to us.
I think the element '$t' in the func list should be double escaped. It worked for me:
func: {
list: ['\\$t'],
extensions: ['.js', '.jsx', '.vue', '.html', '.htm'],
},
Thanks Mr. @aeusse . It worked.
Would love it if the scanner supported extracting the namespace (if any) from the component part. I'm using vue-i18next (panter). And I do have some components that specify a default namespace so I don't have to do it over and over again in the template.
i18nOptions: {
defaultNS: 'network',
//keyPrefix: '' use this if all the keys in this component
},
...```
(also keyPrefix)
I'm having these error messages when I try to scan a Vue 3 project migrated from Vue 2:
i18next-scanner: Unable to parse Trans component from "/Users/xxx/src/app/App.vue"
SyntaxError: Unexpected token (8:9)
I've this error message for every Vue file of my project.
Here is my configuration :
const fs = require('fs')
const chalk = require('chalk')
module.exports = {
options: {
debug: true,
func: {
list: ['\\$t'],
extensions: ['.js', '.vue']
},
trans: {
extensions: ['.js', '.vue'],
fallbackKey: (ns, value) => {
return value
}
},
lngs: ['de'],
ns: ['translation'],
defaultNs: 'translation',
defaultValue: '',
resource: {
loadPath: 'src/i18n/{lng}/{ns}.json',
savePath: 'src/i18n/{lng}/{ns}.json'
},
nsSeparator: false, // namespace separator
keySeparator: false, // key separator
interpolation: {
prefix: '{',
suffix: '}'
}
},
transform: function customTransform (file, enc, done) {
'use strict'
const parser = this.parser
const content = fs.readFileSync(file.path, enc)
let count = 0
parser.parseFuncFromString(content, { list: ['i18next._', 'i18next.__'] }, (key, options) => {
parser.set(key, Object.assign({}, options, {
nsSeparator: false,
keySeparator: false
}))
++count
})
if (count > 0) {
console.log(`i18next-scanner: count=${chalk.cyan(count)}, file=${chalk.yellow(JSON.stringify(file.relative))}`)
}
done()
}
}