更新使用文档

This commit is contained in:
wxzhang 2022-03-04 22:17:05 +08:00
parent feb72c01a2
commit afa4f1a184
4 changed files with 272 additions and 85 deletions

View File

@ -2,7 +2,7 @@
"name": "@voerkai18n/demo", "name": "@voerkai18n/demo",
"version": "1.0.0", "version": "1.0.0",
"description": "", "description": "",
"main": "babel.plugin.demo.js", "main": "babel.plugin.demo.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },

View File

@ -36,7 +36,7 @@ function normalizeCompileOptions(opts={}) {
let options = Object.assign({ let options = Object.assign({
input:null, // 指定要编译的文件夹即extract输出的语言文件夹 input:null, // 指定要编译的文件夹即extract输出的语言文件夹
output:null, // 指定编译后的语言文件夹,如果没有指定则使用input目录 output:null, // 指定编译后的语言文件夹,如果没有指定则使用input目录
moduleType:"esm" // 指定编译后的语言文件的模块类型取值common,cjs,esm,es moduleType:"auto" // 指定编译后的语言文件的模块类型取值common,cjs,esm,es
}, opts) }, opts)
if(options.moduleType==="es") options.moduleType = "esm" if(options.moduleType==="es") options.moduleType = "esm"
if(options.moduleType==="cjs") options.moduleType = "commonjs" if(options.moduleType==="cjs") options.moduleType = "commonjs"
@ -44,10 +44,34 @@ function normalizeCompileOptions(opts={}) {
return options; return options;
} }
/**
* 从当前文件夹开始向上查找package.json文件并解析出语言包的类型
* @param {*} folder
*/
function findModuleType(folder){
try{
let pkgPath = path.join(folder, "package.json")
if(fs.existsSync(pkgPath)){
let pkg = readJson.sync(pkgPath)
return pkg.type || "commonjs"
}
let parent = path.dirname(folder)
if(parent===folder) return null
return findModuleType(parent)
}catch{
return "esm"
}
}
module.exports =async function compile(langFolder,opts={}){ module.exports =async function compile(langFolder,opts={}){
const options = normalizeCompileOptions(opts); const options = normalizeCompileOptions(opts);
const { output,moduleType } = options; const { output,moduleType } = options;
if(moduleType==="auto"){
moduleType = findModuleType(langFolder)
}
// 加载多语言配置文件 // 加载多语言配置文件
const settingsFile = path.join(langFolder,"settings.js") const settingsFile = path.join(langFolder,"settings.js")
try{ try{

165
pnpm-lock.yaml generated
View File

@ -47,16 +47,6 @@ importers:
gulp: 4.0.2 gulp: 4.0.2
vinyl: 2.2.1 vinyl: 2.2.1
packages/demo/apps/app/languages:
specifiers:
deepmerge: ^4.2.2
gulp: ^4.0.2
vinyl: ^2.2.1
devDependencies:
deepmerge: 4.2.2
gulp: 4.0.2
vinyl: 2.2.1
packages/formatters: packages/formatters:
specifiers: specifiers:
deepmerge: ^4.2.2 deepmerge: ^4.2.2
@ -145,8 +135,8 @@ packages:
slash: 2.0.0 slash: 2.0.0
source-map: 0.5.7 source-map: 0.5.7
optionalDependencies: optionalDependencies:
'@nicolo-ribaudo/chokidar-2': 2.1.8-no-fsevents.3 '@nicolo-ribaudo/chokidar-2': registry.npmmirror.com/@nicolo-ribaudo/chokidar-2/2.1.8-no-fsevents.3
chokidar: 3.5.3 chokidar: registry.npmmirror.com/chokidar/3.5.3
dev: false dev: false
/@babel/code-frame/7.16.7: /@babel/code-frame/7.16.7:
@ -1522,12 +1512,6 @@ packages:
'@jridgewell/resolve-uri': 3.0.5 '@jridgewell/resolve-uri': 3.0.5
'@jridgewell/sourcemap-codec': 1.4.11 '@jridgewell/sourcemap-codec': 1.4.11
/@nicolo-ribaudo/chokidar-2/2.1.8-no-fsevents.3:
resolution: {integrity: sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==}
requiresBuild: true
dev: false
optional: true
/@rollup/plugin-babel/5.3.1_@babel+core@7.17.5+rollup@2.69.0: /@rollup/plugin-babel/5.3.1_@babel+core@7.17.5+rollup@2.69.0:
resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
@ -2074,14 +2058,6 @@ packages:
dev: false dev: false
optional: true optional: true
/bindings/1.5.0:
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
requiresBuild: true
dependencies:
file-uri-to-path: 1.0.0
dev: true
optional: true
/brace-expansion/1.1.11: /brace-expansion/1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
dependencies: dependencies:
@ -2229,26 +2205,9 @@ packages:
readdirp: 2.2.1 readdirp: 2.2.1
upath: 1.2.0 upath: 1.2.0
optionalDependencies: optionalDependencies:
fsevents: 1.2.13 fsevents: registry.npmmirror.com/fsevents/1.2.13
dev: true dev: true
/chokidar/3.5.3:
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
engines: {node: '>= 8.10.0'}
requiresBuild: true
dependencies:
anymatch: 3.1.2
braces: 3.0.2
glob-parent: 5.1.2
is-binary-path: 2.1.0
is-glob: 4.0.3
normalize-path: 3.0.0
readdirp: 3.6.0
optionalDependencies:
fsevents: 2.3.2
dev: false
optional: true
/ci-info/3.3.0: /ci-info/3.3.0:
resolution: {integrity: sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==} resolution: {integrity: sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==}
dev: true dev: true
@ -2689,7 +2648,7 @@ packages:
esutils: 2.0.3 esutils: 2.0.3
optionator: 0.8.3 optionator: 0.8.3
optionalDependencies: optionalDependencies:
source-map: 0.6.1 source-map: registry.npmmirror.com/source-map/0.6.1
dev: false dev: false
/escodegen/2.0.0: /escodegen/2.0.0:
@ -2702,7 +2661,7 @@ packages:
esutils: 2.0.3 esutils: 2.0.3
optionator: 0.8.3 optionator: 0.8.3
optionalDependencies: optionalDependencies:
source-map: 0.6.1 source-map: registry.npmmirror.com/source-map/0.6.1
dev: true dev: true
/esprima/4.0.1: /esprima/4.0.1:
@ -2848,12 +2807,6 @@ packages:
bser: 2.1.1 bser: 2.1.1
dev: true dev: true
/file-uri-to-path/1.0.0:
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
requiresBuild: true
dev: true
optional: true
/fill-range/4.0.0: /fill-range/4.0.0:
resolution: {integrity: sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=} resolution: {integrity: sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -2972,25 +2925,6 @@ packages:
/fs.realpath/1.0.0: /fs.realpath/1.0.0:
resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=} resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=}
/fsevents/1.2.13:
resolution: {integrity: sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==}
engines: {node: '>= 4.0'}
os: [darwin]
deprecated: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.
requiresBuild: true
dependencies:
bindings: 1.5.0
nan: 2.15.0
dev: true
optional: true
/fsevents/2.3.2:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
requiresBuild: true
optional: true
/function-bind/1.1.1: /function-bind/1.1.1:
resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
dev: true dev: true
@ -3792,7 +3726,7 @@ packages:
micromatch: 4.0.4 micromatch: 4.0.4
walker: 1.0.8 walker: 1.0.8
optionalDependencies: optionalDependencies:
fsevents: 2.3.2 fsevents: registry.npmmirror.com/fsevents/2.3.2
dev: true dev: true
/jest-jasmine2/27.5.1: /jest-jasmine2/27.5.1:
@ -4442,12 +4376,6 @@ packages:
engines: {node: '>= 0.10'} engines: {node: '>= 0.10'}
dev: true dev: true
/nan/2.15.0:
resolution: {integrity: sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==}
requiresBuild: true
dev: true
optional: true
/nanomatch/1.2.13: /nanomatch/1.2.13:
resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -5122,7 +5050,7 @@ packages:
engines: {node: '>=10.0.0'} engines: {node: '>=10.0.0'}
hasBin: true hasBin: true
optionalDependencies: optionalDependencies:
fsevents: 2.3.2 fsevents: registry.npmmirror.com/fsevents/2.3.2
dev: true dev: true
/safe-buffer/5.1.2: /safe-buffer/5.1.2:
@ -5639,7 +5567,7 @@ packages:
hasBin: true hasBin: true
dependencies: dependencies:
commander: 2.19.0 commander: 2.19.0
source-map: 0.6.1 source-map: registry.npmmirror.com/source-map/0.6.1
/unc-path-regex/0.1.2: /unc-path-regex/0.1.2:
resolution: {integrity: sha1-5z3T17DXxe2G+6xrCufYxqadUPo=} resolution: {integrity: sha1-5z3T17DXxe2G+6xrCufYxqadUPo=}
@ -6010,12 +5938,49 @@ packages:
regenerator-runtime: registry.npmmirror.com/regenerator-runtime/0.13.9 regenerator-runtime: registry.npmmirror.com/regenerator-runtime/0.13.9
dev: false dev: false
registry.npmmirror.com/@nicolo-ribaudo/chokidar-2/2.1.8-no-fsevents.3:
resolution: {integrity: sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz}
name: '@nicolo-ribaudo/chokidar-2'
version: 2.1.8-no-fsevents.3
requiresBuild: true
dev: false
optional: true
registry.npmmirror.com/ansicolor/1.1.100: registry.npmmirror.com/ansicolor/1.1.100:
resolution: {integrity: sha512-Jl0pxRfa9WaQVUX57AB8/V2my6FJxrOR1Pp2qqFbig20QB4HzUoQ48THTKAgHlUCJeQm/s2WoOPcoIDhyCL/kw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ansicolor/-/ansicolor-1.1.100.tgz} resolution: {integrity: sha512-Jl0pxRfa9WaQVUX57AB8/V2my6FJxrOR1Pp2qqFbig20QB4HzUoQ48THTKAgHlUCJeQm/s2WoOPcoIDhyCL/kw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ansicolor/-/ansicolor-1.1.100.tgz}
name: ansicolor name: ansicolor
version: 1.1.100 version: 1.1.100
dev: false dev: false
registry.npmmirror.com/bindings/1.5.0:
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/bindings/-/bindings-1.5.0.tgz}
name: bindings
version: 1.5.0
requiresBuild: true
dependencies:
file-uri-to-path: registry.npmmirror.com/file-uri-to-path/1.0.0
dev: true
optional: true
registry.npmmirror.com/chokidar/3.5.3:
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz}
name: chokidar
version: 3.5.3
engines: {node: '>= 8.10.0'}
requiresBuild: true
dependencies:
anymatch: 3.1.2
braces: 3.0.2
glob-parent: 5.1.2
is-binary-path: 2.1.0
is-glob: 4.0.3
normalize-path: 3.0.0
readdirp: 3.6.0
optionalDependencies:
fsevents: registry.npmmirror.com/fsevents/2.3.2
dev: false
optional: true
registry.npmmirror.com/core-js-pure/3.21.1: registry.npmmirror.com/core-js-pure/3.21.1:
resolution: {integrity: sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/core-js-pure/-/core-js-pure-3.21.1.tgz} resolution: {integrity: sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/core-js-pure/-/core-js-pure-3.21.1.tgz}
name: core-js-pure name: core-js-pure
@ -6030,6 +5995,45 @@ packages:
requiresBuild: true requiresBuild: true
dev: false dev: false
registry.npmmirror.com/file-uri-to-path/1.0.0:
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz}
name: file-uri-to-path
version: 1.0.0
requiresBuild: true
dev: true
optional: true
registry.npmmirror.com/fsevents/1.2.13:
resolution: {integrity: sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/fsevents/-/fsevents-1.2.13.tgz}
name: fsevents
version: 1.2.13
engines: {node: '>= 4.0'}
os: [darwin]
deprecated: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.
requiresBuild: true
dependencies:
bindings: registry.npmmirror.com/bindings/1.5.0
nan: registry.npmmirror.com/nan/2.15.0
dev: true
optional: true
registry.npmmirror.com/fsevents/2.3.2:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz}
name: fsevents
version: 2.3.2
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
requiresBuild: true
optional: true
registry.npmmirror.com/nan/2.15.0:
resolution: {integrity: sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/nan/-/nan-2.15.0.tgz}
name: nan
version: 2.15.0
requiresBuild: true
dev: true
optional: true
registry.npmmirror.com/regenerator-runtime/0.13.9: registry.npmmirror.com/regenerator-runtime/0.13.9:
resolution: {integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz} resolution: {integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz}
name: regenerator-runtime name: regenerator-runtime
@ -6041,4 +6045,3 @@ packages:
name: source-map name: source-map
version: 0.6.1 version: 0.6.1
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: false

162
readme.md
View File

@ -1,5 +1,165 @@
# 前言
基于`javascript`的国际化方案很多,比较有名的有`fbt``i18next``react-i18next``vue-i18n``react-intl`等等,每一种解决方案均有大量的用户。为什么还要再造一个轮子?好吧,再造轮子的理由不外乎不满足于现有方案,总想着现有方案的种种不足之处,然后就撸起袖子想造一个轮子,也不想想自己什么水平。
哪么到底是对现有解决方案有什么不满?最主要有三点:
- 大部份均为要翻译的文本信息指定一个`key`,然后在源码文件中使用形如`$t("message.login")`之类的方式,然后在翻译时将之转换成最终的文本信息。此方式最大的问题是,在源码中必须人为地指定每一个`key`,在中文语境中,想为每一句中文均配套想一句符合语义的`英文key`是比较麻烦的,也很不直观。我希望在源文件中就直接使用中文,如`t("中华人民共和国万岁")`,然后国际化框架应该能自动处理后续的一系列麻烦。
- 要能够比较友好地支持多包`monorepo`场景下的国际化协作,当主程序切换语言时,其他包或库也可以自动切换,并且在开发上每个包或库均可以独立地进行开发,集成到主程序时能无缝集成。这点在现有方案上没有找到比较理想的解决方案。
- 大部份国际化框架均将中文视为二等公民,大部份情况下您应该采用英文作为第一语言,虽然这不是太大的问题,但是既然要再造一个轮子,为什么不将中文提升到一等公民呢。
当然,在使用方式上要尽可能简洁,便
基于此
# 安装
`VoerkaI18n`国际化框架是一个开源多包工程,主要由以下几个包组成:
- **@voerkai18/runtime**
必须的运行时,安装到运行依赖`dependencies`
```javascript
npm install --save @voerkai18/runtime
yarn add @voerkai18/runtime
pnpm add @voerkai18/runtime
```
- **@voerkai18/tools**
包含文本提取/编译等命行工具,应该安装到开发依赖`devDependencies`
```javascript
npm install --save-dev @voerkai18/tools
yarn add -D @voerkai18/tools
pnpm add -D @voerkai18/tools
```
- **@voerkai18/formatters**
可选的,一些额外的格式化器,可以按需进行安装到`dependencies`
# 快速入门
本节以标准的`Nodejs`应用程序为例,简要介绍`VoerkaI18n`国际化框架的基本使用。其他`vue``react`应用的使用也基本相同。
```shell
myapp
|--package.json
|--index.js
```
## 第一步:使用翻译函数
在源码文件中直接使用`t`翻译函数对要翻译文本信息进行封装,简单而粗暴。
```javascript
// index.js
console.log(t("中华人民共和国万岁"))
console.log(t("中华人民共和国成立于{}",1949))
```
`t`翻译函数是在哪里声明的?先卖个关子,后续揭晓。
## 第二步:提取要翻译的内容
接下来我们使用`voerkai18n extract`命令来自动扫描工程源码文件中的需要的翻译的文本信息。
```shell
myapp>voerkai18n extract --languages cn,en,de,jp --default cn --active cn
```
以上命令代表:
- 扫描当前文件夹下所有源码文件
- 计划支持`cn``en``de``jp`四种语言
- 默认语言是中文。(指在源码文件中我们直接使用中文,好象其他方案大部份均要求采用英文)
- 激活语言是中文(即默认切换到中文)
执行`voerkai18n extract`命令后,就会在`myapp/languages`通过生成`translates/default.json`文件,该文件就是需要进行翻译的文本信息,形式如下:
```json
{
"中华人民共和国万岁":{
"en":"<在此编写对应的英文翻译内容>",
"de":"<在此编写对应的德文翻译内容>"
"jp":"<在此编写对应的日文翻译内容>",
"$files":["index.js"] // 记录了该信息是从哪几个文件中提取的
},
"中华人民共和国成立于{}":{
"en":"<在此编写对应的英文翻译内容>",
"de":"<在此编写对应的德文翻译内容>"
"jp":"<在此编写对应的日文翻译内容>",
"$files":["index.js"]
}
}
```
最后文件结构如下:
```shell
myapp
|-- languages
|-- settings.js // 语言配置文件
|-- translates // 此文件夹是所有需要翻译的内容
|-- default.json
|-- package.json
|-- index.js
```
> **注:**当我们修改了源文件后,可以多次执行`voerkai18n extract`命令,该命令会自动同步合并已翻译的内容,不会导致进行了一半的翻译内容丢失,可以放心执行。
## 第三步:编码语言包
当我们完成`myapp/languages/translates`下的所有`JSON语言文件`的翻译后(如果配置了名称空间后,每一个名称空间会对应生成一个文件,详见后续`名称空间`介绍),接下来需要对翻译后的文件进行编译。
```shell
myapp> voerkai18n compile
```
`compile`命令根据`myapp/languages/translates/*.json``myapp/languages/settings.js`文件编译生成以下文件:
```javascript
|-- languages
|-- settings.js // 语言配置文件
|-- idMap.js // 文本信息id映射表
|-- index.js // 包含该应用作用域下的翻译函数等
|-- cn.js // 语言包
|-- en.js
|-- jp.js
|-- de.js
|-- translates // 此文件夹是所有需要翻译的内容
|-- default.json
|-- package.json
|-- index.js
```
## 第四步:导入翻译函数
第一步中我们在源文件中直接使用了`t`翻译函数包装要翻译的文本信息,该`t`翻译函数就是在编译环节自动生成并声明在`myapp/languages/index.js`中的。
import { t } from "./languages"
`myapp/languages/index.js`文件导出的翻译函数,但是现在`myapp/languages`还不存在,后续会使用工具自动生成。
# 指南 # 指南
## 翻译函数 ## 翻译函数
@ -72,7 +232,7 @@ t("中华人民共和国成立于{date | year}年",{date:new Date('')})
启用复数处理机制后,在`t`函数按如下方式进行处理。 启用复数处理机制后,在`t`函数按如下方式进行处理。
- **不存在插值变量且t函数的第2个参数是数字** - **不存在插值变量且t函数的第2个参数是数字**