From 0f7158f5dee6156c6f3f89e8e4bbd7fc254550ab Mon Sep 17 00:00:00 2001 From: wxzhang Date: Sun, 7 Aug 2022 11:14:28 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=87=E6=8D=A2=E6=96=87=E6=A1=A3=E7=BD=91?= =?UTF-8?q?=E7=AB=99=E5=88=B0dumi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy-docs.yml | 28 +- .gitignore | 10 +- docs.md | 1620 ----- docs/.vuepress/config.ts | 55 - docs/.vuepress/dist/404.html | 40 - .../assets/KaTeX_AMS-Regular.0cdd387c.woff2 | Bin 28076 -> 0 bytes .../assets/KaTeX_AMS-Regular.30da91e8.woff | Bin 33516 -> 0 bytes .../assets/KaTeX_AMS-Regular.68534840.ttf | Bin 63632 -> 0 bytes .../KaTeX_Caligraphic-Bold.07d8e303.ttf | Bin 12368 -> 0 bytes .../KaTeX_Caligraphic-Bold.1ae6bd74.woff | Bin 7716 -> 0 bytes .../KaTeX_Caligraphic-Bold.de7701e4.woff2 | Bin 6912 -> 0 bytes .../KaTeX_Caligraphic-Regular.3398dd02.woff | Bin 7656 -> 0 bytes .../KaTeX_Caligraphic-Regular.5d53e70a.woff2 | Bin 6908 -> 0 bytes .../KaTeX_Caligraphic-Regular.ed0b7437.ttf | Bin 12344 -> 0 bytes .../assets/KaTeX_Fraktur-Bold.74444efd.woff2 | Bin 11348 -> 0 bytes .../assets/KaTeX_Fraktur-Bold.9163df9c.ttf | Bin 19584 -> 0 bytes .../assets/KaTeX_Fraktur-Bold.9be7ceb8.woff | Bin 13296 -> 0 bytes .../assets/KaTeX_Fraktur-Regular.1e6f9579.ttf | Bin 19572 -> 0 bytes .../KaTeX_Fraktur-Regular.51814d27.woff2 | Bin 11316 -> 0 bytes .../KaTeX_Fraktur-Regular.5e28753b.woff | Bin 13208 -> 0 bytes .../assets/KaTeX_Main-Bold.0f60d1b8.woff2 | Bin 25324 -> 0 bytes .../dist/assets/KaTeX_Main-Bold.138ac28d.ttf | Bin 51336 -> 0 bytes .../dist/assets/KaTeX_Main-Bold.c76c5d69.woff | Bin 29912 -> 0 bytes .../assets/KaTeX_Main-BoldItalic.70ee1f64.ttf | Bin 32968 -> 0 bytes .../KaTeX_Main-BoldItalic.99cd42a3.woff2 | Bin 16780 -> 0 bytes .../KaTeX_Main-BoldItalic.a6f7ec0d.woff | Bin 19412 -> 0 bytes .../assets/KaTeX_Main-Italic.0d85ae7c.ttf | Bin 33580 -> 0 bytes .../assets/KaTeX_Main-Italic.97479ca6.woff2 | Bin 16988 -> 0 bytes .../assets/KaTeX_Main-Italic.f1d6ef86.woff | Bin 19676 -> 0 bytes .../assets/KaTeX_Main-Regular.c2342cd8.woff2 | Bin 26272 -> 0 bytes .../assets/KaTeX_Main-Regular.c6368d87.woff | Bin 30772 -> 0 bytes .../assets/KaTeX_Main-Regular.d0332f52.ttf | Bin 53580 -> 0 bytes .../KaTeX_Math-BoldItalic.850c0af5.woff | Bin 18668 -> 0 bytes .../KaTeX_Math-BoldItalic.dc47344d.woff2 | Bin 16400 -> 0 bytes .../assets/KaTeX_Math-BoldItalic.f9377ab0.ttf | Bin 31196 -> 0 bytes .../assets/KaTeX_Math-Italic.08ce98e5.ttf | Bin 31308 -> 0 bytes .../assets/KaTeX_Math-Italic.7af58c5e.woff2 | Bin 16440 -> 0 bytes .../assets/KaTeX_Math-Italic.8a8d2445.woff | Bin 18748 -> 0 bytes .../assets/KaTeX_SansSerif-Bold.1ece03f7.ttf | Bin 24504 -> 0 bytes .../KaTeX_SansSerif-Bold.e99ae511.woff2 | Bin 12216 -> 0 bytes .../assets/KaTeX_SansSerif-Bold.ece03cfd.woff | Bin 14408 -> 0 bytes .../KaTeX_SansSerif-Italic.00b26ac8.woff2 | Bin 12028 -> 0 bytes .../KaTeX_SansSerif-Italic.3931dd81.ttf | Bin 22364 -> 0 bytes .../KaTeX_SansSerif-Italic.91ee6750.woff | Bin 14112 -> 0 bytes .../KaTeX_SansSerif-Regular.11e4dc8a.woff | Bin 12316 -> 0 bytes .../KaTeX_SansSerif-Regular.68e8c73e.woff2 | Bin 10344 -> 0 bytes .../KaTeX_SansSerif-Regular.f36ea897.ttf | Bin 19436 -> 0 bytes .../KaTeX_Script-Regular.036d4e95.woff2 | Bin 9644 -> 0 bytes .../assets/KaTeX_Script-Regular.1c67f068.ttf | Bin 16648 -> 0 bytes .../assets/KaTeX_Script-Regular.d96cdf2b.woff | Bin 10588 -> 0 bytes .../assets/KaTeX_Size1-Regular.6b47c401.woff2 | Bin 5468 -> 0 bytes .../assets/KaTeX_Size1-Regular.95b6d2f1.ttf | Bin 12228 -> 0 bytes .../assets/KaTeX_Size1-Regular.c943cc98.woff | Bin 6496 -> 0 bytes .../assets/KaTeX_Size2-Regular.2014c523.woff | Bin 6188 -> 0 bytes .../assets/KaTeX_Size2-Regular.a6b2099f.ttf | Bin 11508 -> 0 bytes .../assets/KaTeX_Size2-Regular.d04c5421.woff2 | Bin 5208 -> 0 bytes .../assets/KaTeX_Size3-Regular.500e04d5.ttf | Bin 7588 -> 0 bytes .../assets/KaTeX_Size3-Regular.6ab6b62e.woff | Bin 4420 -> 0 bytes .../assets/KaTeX_Size4-Regular.99f9c675.woff | Bin 5980 -> 0 bytes .../assets/KaTeX_Size4-Regular.a4af7d41.woff2 | Bin 4928 -> 0 bytes .../assets/KaTeX_Size4-Regular.c647367d.ttf | Bin 10364 -> 0 bytes .../KaTeX_Typewriter-Regular.71d517d6.woff2 | Bin 13568 -> 0 bytes .../KaTeX_Typewriter-Regular.e14fed02.woff | Bin 16028 -> 0 bytes .../KaTeX_Typewriter-Regular.f01f3e87.ttf | Bin 27556 -> 0 bytes .../dist/assets/league-gothic.38fcc721.ttf | Bin 64256 -> 0 bytes .../dist/assets/league-gothic.5eef6df8.woff | Bin 30764 -> 0 bytes .../dist/assets/league-gothic.8802c66a.eot | Bin 25696 -> 0 bytes .../plugin-vue_export-helper.21dcd24c.js | 1 - .../source-sans-pro-italic.05d3615f.woff | Bin 98556 -> 0 bytes .../source-sans-pro-italic.ad4b0799.eot | Bin 75720 -> 0 bytes .../source-sans-pro-italic.d13268af.ttf | Bin 238084 -> 0 bytes .../source-sans-pro-regular.c1865d89.ttf | Bin 288008 -> 0 bytes .../source-sans-pro-regular.d4eaa48b.woff | Bin 114324 -> 0 bytes .../source-sans-pro-regular.dce8869d.eot | Bin 88070 -> 0 bytes .../source-sans-pro-semibold.a53e2723.ttf | Bin 284640 -> 0 bytes .../source-sans-pro-semibold.b0abd273.woff | Bin 115648 -> 0 bytes .../source-sans-pro-semibold.ebb8918d.eot | Bin 89897 -> 0 bytes ...urce-sans-pro-semibolditalic.7225cacc.woff | Bin 98816 -> 0 bytes ...ource-sans-pro-semibolditalic.dfe0b47a.eot | Bin 75706 -> 0 bytes ...ource-sans-pro-semibolditalic.e8ec22b6.ttf | Bin 240944 -> 0 bytes docs/.vuepress/dist/en/guide/disable.html | 40 - docs/.vuepress/dist/en/guide/encrypt.html | 40 - docs/.vuepress/dist/en/guide/index.html | 40 - docs/.vuepress/dist/en/guide/install.html | 40 - docs/.vuepress/dist/en/guide/markdown.html | 40 - docs/.vuepress/dist/en/guide/page.html | 40 - docs/.vuepress/dist/favicon.ico | Bin 67646 -> 0 bytes docs/.vuepress/dist/images/arch.png | Bin 27785 -> 0 bytes docs/.vuepress/dist/index.html | 40 - docs/.vuepress/dist/logo.png | Bin 94186 -> 0 bytes docs/.vuepress/dist/logo.svg | 1 - docs/.vuepress/dist/robots.txt | 5 - docs/.vuepress/dist/sitemap.xml | 1 - docs/.vuepress/dist/zh/contribute/index.html | 40 - .../dist/zh/guide/advanced/autoimport.html | 40 - .../dist/zh/guide/advanced/autotranslate.html | 40 - .../zh/guide/advanced/customformatter.html | 40 - .../dist/zh/guide/advanced/framework.html | 40 - .../dist/zh/guide/advanced/langpack.html | 40 - .../dist/zh/guide/advanced/multi-libs.html | 40 - .../dist/zh/guide/advanced/runtime.html | 40 - .../dist/zh/guide/advanced/textMap.html | 40 - .../dist/zh/guide/intro/get-started.html | 40 - .../dist/zh/guide/intro/history.html | 40 - docs/.vuepress/dist/zh/guide/intro/index.html | 40 - .../dist/zh/guide/intro/install.html | 40 - .../dist/zh/guide/intro/question.html | 40 - docs/.vuepress/dist/zh/guide/tools/babel.html | 40 - docs/.vuepress/dist/zh/guide/tools/cli.html | 40 - docs/.vuepress/dist/zh/guide/tools/vite.html | 40 - docs/.vuepress/dist/zh/guide/tools/vue.html | 40 - .../dist/zh/guide/use/change-langeuage.html | 40 - .../.vuepress/dist/zh/guide/use/currency.html | 40 - .../.vuepress/dist/zh/guide/use/datetime.html | 40 - .../dist/zh/guide/use/interpolation.html | 40 - .../dist/zh/guide/use/namespace.html | 40 - docs/.vuepress/dist/zh/guide/use/plural.html | 40 - docs/.vuepress/dist/zh/guide/use/react.html | 40 - docs/.vuepress/dist/zh/guide/use/t.html | 40 - docs/.vuepress/dist/zh/guide/use/vue.html | 40 - docs/.vuepress/dist/zh/home.html | 40 - .../dist/zh/reference/formatters.html | 40 - .../dist/zh/reference/i18nscope.html | 40 - docs/.vuepress/dist/zh/reference/index.html | 40 - .../dist/zh/reference/lang-code.html | 40 - .../dist/zh/reference/voerkaI18n.html | 40 - docs/.vuepress/navbar/en.ts | 6 - docs/.vuepress/navbar/index.ts | 2 - docs/.vuepress/navbar/zh.ts | 20 - docs/.vuepress/public/favicon.ico | Bin 67646 -> 0 bytes .../public/images/VoerkaI18n群二维码.png | Bin 14893 -> 0 bytes docs/.vuepress/public/images/arch.png | Bin 27785 -> 0 bytes docs/.vuepress/public/logo.png | Bin 94186 -> 0 bytes docs/.vuepress/public/logo.svg | 1 - docs/.vuepress/sidebar/en.ts | 14 - docs/.vuepress/sidebar/index.ts | 2 - docs/.vuepress/sidebar/zh.ts | 66 - docs/.vuepress/styles/index.scss | 5 - docs/.vuepress/styles/palette.scss | 1 - docs/en/guide/disable.md | 42 - docs/en/guide/encrypt.md | 15 - docs/en/guide/install.md | 40 - docs/en/guide/markdown.md | 341 - docs/en/guide/page.md | 66 - docs/en/guide/readme.md | 82 - docs/package.json | 23 - docs/readme.md | 79 - docs/yarn.lock | 4749 ------------- docs/zh/contribute/readme.md | 73 - docs/zh/guide/advanced/autoimport.md | 25 - docs/zh/guide/advanced/autotranslate.md | 9 - docs/zh/guide/advanced/customformatter.md | 197 - docs/zh/guide/advanced/framework.md | 68 - docs/zh/guide/advanced/langedit.md | 16 - docs/zh/guide/advanced/langpack.md | 22 - docs/zh/guide/advanced/lngpatch.md | 8 - docs/zh/guide/advanced/multi-libs.md | 14 - docs/zh/guide/advanced/remoteLoad.md | 246 - docs/zh/guide/advanced/runtime.md | 37 - docs/zh/guide/advanced/textMap.md | 45 - docs/zh/guide/intro/get-started.md | 251 - docs/zh/guide/intro/history.md | 9 - docs/zh/guide/intro/install.md | 47 - docs/zh/guide/intro/question.md | 3 - docs/zh/guide/intro/readme.md | 38 - docs/zh/guide/intro/support.md | 4 - docs/zh/guide/intro/versions.md | 11 - docs/zh/guide/tools/babel.md | 73 - docs/zh/guide/tools/cli.md | 251 - docs/zh/guide/tools/vite.md | 97 - docs/zh/guide/tools/vue.md | 92 - docs/zh/guide/use/change-langeuage.md | 32 - docs/zh/guide/use/currency.md | 5 - docs/zh/guide/use/datetime.md | 19 - docs/zh/guide/use/interpolation.md | 84 - docs/zh/guide/use/namespace.md | 47 - docs/zh/guide/use/plural.md | 112 - docs/zh/guide/use/react.md | 74 - docs/zh/guide/use/t.md | 39 - docs/zh/guide/use/vue.md | 135 - docs/zh/home.md | 82 - docs/zh/reference/formatters.md | 3 - docs/zh/reference/i18nscope.md | 33 - docs/zh/reference/lang-code.md | 35 - docs/zh/reference/readme.md | 8 - docs/zh/reference/voerkaI18n.md | 26 - images/arch.png | Bin 27785 -> 0 bytes package.json | 15 +- pnpm-lock.yaml | 6199 +++++++++++------ 189 files changed, 4210 insertions(+), 13289 deletions(-) delete mode 100644 docs.md delete mode 100644 docs/.vuepress/config.ts delete mode 100644 docs/.vuepress/dist/404.html delete mode 100644 docs/.vuepress/dist/assets/KaTeX_AMS-Regular.0cdd387c.woff2 delete mode 100644 docs/.vuepress/dist/assets/KaTeX_AMS-Regular.30da91e8.woff delete mode 100644 docs/.vuepress/dist/assets/KaTeX_AMS-Regular.68534840.ttf delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Caligraphic-Bold.07d8e303.ttf delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Caligraphic-Bold.1ae6bd74.woff delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Caligraphic-Bold.de7701e4.woff2 delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Caligraphic-Regular.3398dd02.woff delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Caligraphic-Regular.5d53e70a.woff2 delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Caligraphic-Regular.ed0b7437.ttf delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Fraktur-Bold.74444efd.woff2 delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Fraktur-Bold.9163df9c.ttf delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Fraktur-Bold.9be7ceb8.woff delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Fraktur-Regular.1e6f9579.ttf delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Fraktur-Regular.51814d27.woff2 delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Fraktur-Regular.5e28753b.woff delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Main-Bold.0f60d1b8.woff2 delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Main-Bold.138ac28d.ttf delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Main-Bold.c76c5d69.woff delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Main-BoldItalic.70ee1f64.ttf delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Main-BoldItalic.99cd42a3.woff2 delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Main-BoldItalic.a6f7ec0d.woff delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Main-Italic.0d85ae7c.ttf delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Main-Italic.97479ca6.woff2 delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Main-Italic.f1d6ef86.woff delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Main-Regular.c2342cd8.woff2 delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Main-Regular.c6368d87.woff delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Main-Regular.d0332f52.ttf delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Math-BoldItalic.850c0af5.woff delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Math-BoldItalic.dc47344d.woff2 delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Math-BoldItalic.f9377ab0.ttf delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Math-Italic.08ce98e5.ttf delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Math-Italic.7af58c5e.woff2 delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Math-Italic.8a8d2445.woff delete mode 100644 docs/.vuepress/dist/assets/KaTeX_SansSerif-Bold.1ece03f7.ttf delete mode 100644 docs/.vuepress/dist/assets/KaTeX_SansSerif-Bold.e99ae511.woff2 delete mode 100644 docs/.vuepress/dist/assets/KaTeX_SansSerif-Bold.ece03cfd.woff delete mode 100644 docs/.vuepress/dist/assets/KaTeX_SansSerif-Italic.00b26ac8.woff2 delete mode 100644 docs/.vuepress/dist/assets/KaTeX_SansSerif-Italic.3931dd81.ttf delete mode 100644 docs/.vuepress/dist/assets/KaTeX_SansSerif-Italic.91ee6750.woff delete mode 100644 docs/.vuepress/dist/assets/KaTeX_SansSerif-Regular.11e4dc8a.woff delete mode 100644 docs/.vuepress/dist/assets/KaTeX_SansSerif-Regular.68e8c73e.woff2 delete mode 100644 docs/.vuepress/dist/assets/KaTeX_SansSerif-Regular.f36ea897.ttf delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Script-Regular.036d4e95.woff2 delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Script-Regular.1c67f068.ttf delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Script-Regular.d96cdf2b.woff delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Size1-Regular.6b47c401.woff2 delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Size1-Regular.95b6d2f1.ttf delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Size1-Regular.c943cc98.woff delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Size2-Regular.2014c523.woff delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Size2-Regular.a6b2099f.ttf delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Size2-Regular.d04c5421.woff2 delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Size3-Regular.500e04d5.ttf delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Size3-Regular.6ab6b62e.woff delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Size4-Regular.99f9c675.woff delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Size4-Regular.a4af7d41.woff2 delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Size4-Regular.c647367d.ttf delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Typewriter-Regular.71d517d6.woff2 delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Typewriter-Regular.e14fed02.woff delete mode 100644 docs/.vuepress/dist/assets/KaTeX_Typewriter-Regular.f01f3e87.ttf delete mode 100644 docs/.vuepress/dist/assets/league-gothic.38fcc721.ttf delete mode 100644 docs/.vuepress/dist/assets/league-gothic.5eef6df8.woff delete mode 100644 docs/.vuepress/dist/assets/league-gothic.8802c66a.eot delete mode 100644 docs/.vuepress/dist/assets/plugin-vue_export-helper.21dcd24c.js delete mode 100644 docs/.vuepress/dist/assets/source-sans-pro-italic.05d3615f.woff delete mode 100644 docs/.vuepress/dist/assets/source-sans-pro-italic.ad4b0799.eot delete mode 100644 docs/.vuepress/dist/assets/source-sans-pro-italic.d13268af.ttf delete mode 100644 docs/.vuepress/dist/assets/source-sans-pro-regular.c1865d89.ttf delete mode 100644 docs/.vuepress/dist/assets/source-sans-pro-regular.d4eaa48b.woff delete mode 100644 docs/.vuepress/dist/assets/source-sans-pro-regular.dce8869d.eot delete mode 100644 docs/.vuepress/dist/assets/source-sans-pro-semibold.a53e2723.ttf delete mode 100644 docs/.vuepress/dist/assets/source-sans-pro-semibold.b0abd273.woff delete mode 100644 docs/.vuepress/dist/assets/source-sans-pro-semibold.ebb8918d.eot delete mode 100644 docs/.vuepress/dist/assets/source-sans-pro-semibolditalic.7225cacc.woff delete mode 100644 docs/.vuepress/dist/assets/source-sans-pro-semibolditalic.dfe0b47a.eot delete mode 100644 docs/.vuepress/dist/assets/source-sans-pro-semibolditalic.e8ec22b6.ttf delete mode 100644 docs/.vuepress/dist/en/guide/disable.html delete mode 100644 docs/.vuepress/dist/en/guide/encrypt.html delete mode 100644 docs/.vuepress/dist/en/guide/index.html delete mode 100644 docs/.vuepress/dist/en/guide/install.html delete mode 100644 docs/.vuepress/dist/en/guide/markdown.html delete mode 100644 docs/.vuepress/dist/en/guide/page.html delete mode 100644 docs/.vuepress/dist/favicon.ico delete mode 100644 docs/.vuepress/dist/images/arch.png delete mode 100644 docs/.vuepress/dist/index.html delete mode 100644 docs/.vuepress/dist/logo.png delete mode 100644 docs/.vuepress/dist/logo.svg delete mode 100644 docs/.vuepress/dist/robots.txt delete mode 100644 docs/.vuepress/dist/sitemap.xml delete mode 100644 docs/.vuepress/dist/zh/contribute/index.html delete mode 100644 docs/.vuepress/dist/zh/guide/advanced/autoimport.html delete mode 100644 docs/.vuepress/dist/zh/guide/advanced/autotranslate.html delete mode 100644 docs/.vuepress/dist/zh/guide/advanced/customformatter.html delete mode 100644 docs/.vuepress/dist/zh/guide/advanced/framework.html delete mode 100644 docs/.vuepress/dist/zh/guide/advanced/langpack.html delete mode 100644 docs/.vuepress/dist/zh/guide/advanced/multi-libs.html delete mode 100644 docs/.vuepress/dist/zh/guide/advanced/runtime.html delete mode 100644 docs/.vuepress/dist/zh/guide/advanced/textMap.html delete mode 100644 docs/.vuepress/dist/zh/guide/intro/get-started.html delete mode 100644 docs/.vuepress/dist/zh/guide/intro/history.html delete mode 100644 docs/.vuepress/dist/zh/guide/intro/index.html delete mode 100644 docs/.vuepress/dist/zh/guide/intro/install.html delete mode 100644 docs/.vuepress/dist/zh/guide/intro/question.html delete mode 100644 docs/.vuepress/dist/zh/guide/tools/babel.html delete mode 100644 docs/.vuepress/dist/zh/guide/tools/cli.html delete mode 100644 docs/.vuepress/dist/zh/guide/tools/vite.html delete mode 100644 docs/.vuepress/dist/zh/guide/tools/vue.html delete mode 100644 docs/.vuepress/dist/zh/guide/use/change-langeuage.html delete mode 100644 docs/.vuepress/dist/zh/guide/use/currency.html delete mode 100644 docs/.vuepress/dist/zh/guide/use/datetime.html delete mode 100644 docs/.vuepress/dist/zh/guide/use/interpolation.html delete mode 100644 docs/.vuepress/dist/zh/guide/use/namespace.html delete mode 100644 docs/.vuepress/dist/zh/guide/use/plural.html delete mode 100644 docs/.vuepress/dist/zh/guide/use/react.html delete mode 100644 docs/.vuepress/dist/zh/guide/use/t.html delete mode 100644 docs/.vuepress/dist/zh/guide/use/vue.html delete mode 100644 docs/.vuepress/dist/zh/home.html delete mode 100644 docs/.vuepress/dist/zh/reference/formatters.html delete mode 100644 docs/.vuepress/dist/zh/reference/i18nscope.html delete mode 100644 docs/.vuepress/dist/zh/reference/index.html delete mode 100644 docs/.vuepress/dist/zh/reference/lang-code.html delete mode 100644 docs/.vuepress/dist/zh/reference/voerkaI18n.html delete mode 100644 docs/.vuepress/navbar/en.ts delete mode 100644 docs/.vuepress/navbar/index.ts delete mode 100644 docs/.vuepress/navbar/zh.ts delete mode 100644 docs/.vuepress/public/favicon.ico delete mode 100644 docs/.vuepress/public/images/VoerkaI18n群二维码.png delete mode 100644 docs/.vuepress/public/images/arch.png delete mode 100644 docs/.vuepress/public/logo.png delete mode 100644 docs/.vuepress/public/logo.svg delete mode 100644 docs/.vuepress/sidebar/en.ts delete mode 100644 docs/.vuepress/sidebar/index.ts delete mode 100644 docs/.vuepress/sidebar/zh.ts delete mode 100644 docs/.vuepress/styles/index.scss delete mode 100644 docs/.vuepress/styles/palette.scss delete mode 100644 docs/en/guide/disable.md delete mode 100644 docs/en/guide/encrypt.md delete mode 100644 docs/en/guide/install.md delete mode 100644 docs/en/guide/markdown.md delete mode 100644 docs/en/guide/page.md delete mode 100644 docs/en/guide/readme.md delete mode 100644 docs/package.json delete mode 100644 docs/readme.md delete mode 100644 docs/yarn.lock delete mode 100644 docs/zh/contribute/readme.md delete mode 100644 docs/zh/guide/advanced/autoimport.md delete mode 100644 docs/zh/guide/advanced/autotranslate.md delete mode 100644 docs/zh/guide/advanced/customformatter.md delete mode 100644 docs/zh/guide/advanced/framework.md delete mode 100644 docs/zh/guide/advanced/langedit.md delete mode 100644 docs/zh/guide/advanced/langpack.md delete mode 100644 docs/zh/guide/advanced/lngpatch.md delete mode 100644 docs/zh/guide/advanced/multi-libs.md delete mode 100644 docs/zh/guide/advanced/remoteLoad.md delete mode 100644 docs/zh/guide/advanced/runtime.md delete mode 100644 docs/zh/guide/advanced/textMap.md delete mode 100644 docs/zh/guide/intro/get-started.md delete mode 100644 docs/zh/guide/intro/history.md delete mode 100644 docs/zh/guide/intro/install.md delete mode 100644 docs/zh/guide/intro/question.md delete mode 100644 docs/zh/guide/intro/readme.md delete mode 100644 docs/zh/guide/intro/support.md delete mode 100644 docs/zh/guide/intro/versions.md delete mode 100644 docs/zh/guide/tools/babel.md delete mode 100644 docs/zh/guide/tools/cli.md delete mode 100644 docs/zh/guide/tools/vite.md delete mode 100644 docs/zh/guide/tools/vue.md delete mode 100644 docs/zh/guide/use/change-langeuage.md delete mode 100644 docs/zh/guide/use/currency.md delete mode 100644 docs/zh/guide/use/datetime.md delete mode 100644 docs/zh/guide/use/interpolation.md delete mode 100644 docs/zh/guide/use/namespace.md delete mode 100644 docs/zh/guide/use/plural.md delete mode 100644 docs/zh/guide/use/react.md delete mode 100644 docs/zh/guide/use/t.md delete mode 100644 docs/zh/guide/use/vue.md delete mode 100644 docs/zh/home.md delete mode 100644 docs/zh/reference/formatters.md delete mode 100644 docs/zh/reference/i18nscope.md delete mode 100644 docs/zh/reference/lang-code.md delete mode 100644 docs/zh/reference/readme.md delete mode 100644 docs/zh/reference/voerkaI18n.md delete mode 100644 images/arch.png diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 2bf7637..946e7d6 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -1,44 +1,32 @@ - -name: 部署文档 +name: 部署文档网站 on: push: branches: - # 确保这是你正在使用的分支名称 - - master + - master # default branch jobs: - deploy-gh-pages: + deploy: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 with: fetch-depth: 0 - # 如果你文档需要 Git 子模块,取消注释下一行 - # submodules: true - - uses: actions/cache@v3 id: node-modules with: path: node_modules/ key: ${{ runner.os }}-node-modules-${{ hashFiles('yarn.lock') }} restore-keys: | - ${{ runner.os }}-node-modules- - + ${{ runner.os }}-node-modules- - name: 安装依赖 if: steps.node-modules.outputs.cache-hit != 'true' run: yarn install --frozen-lockfile - - - name: 构建文档 - env: - NODE_OPTIONS: --max_old_space_size=4096 - run: yarn run docs:build2 - - - name: 部署文档 + - name: 构建网站 + run: yarn run docs:build + - name: 发布网站 uses: JamesIves/github-pages-deploy-action@v4 with: - # 这是文档部署到的分支名称gh-pages branch: website - folder: docs/.vuepress/dist - + folder: docs/dist \ No newline at end of file diff --git a/.gitignore b/.gitignore index 40393ac..4e94a47 100644 --- a/.gitignore +++ b/.gitignore @@ -6,10 +6,10 @@ node_modules /packages/apps/vueapp/src/languages /packages/apps/app/languages /packages/apps/test -node_modules/ -docs/.vuepress/.cache/ -docs/.vuepress/.temp/ +node_modules/ /packages/cli/baidu.api.txt node_modules/ -/.github/access key.txt -/docs/.vuepress/dist \ No newline at end of file +/.github/access key.txt +.umi +.umi-production +/docs/dist diff --git a/docs.md b/docs.md deleted file mode 100644 index dac6c95..0000000 --- a/docs.md +++ /dev/null @@ -1,1620 +0,0 @@ - -适用于`Javascript/Vue/React/ReactNative`的国际化解决方案 - - -[官方网站](zhangfisher.github.io/voerka-i18n/) - - -基于`javascript`的国际化方案很多,比较有名的有`fbt`、`i18next`、`react-i18next`、`vue-i18n`、`react-intl`等等,每一种解决方案均有大量的用户。为什么还要再造一个轮子?好吧,再造轮子的理由不外乎不满足于现有方案,总想着现有方案的种种不足之处,然后就撸起袖子想造一个轮子,也不想想自己什么水平。 - -哪么到底是对现有解决方案有什么不满?最主要有三点: - -- 大部份均为要翻译的文本信息指定一个`key`,然后在源码文件中使用形如`$t("message.login")`之类的方式,然后在翻译时将之转换成最终的文本信息。此方式最大的问题是,在源码中必须人为地指定每一个`key`,在中文语境中,想为每一句中文均配套想一句符合语义的`英文key`是比较麻烦的,也很不直观不符合直觉。我希望在源文件中就直接使用中文,如`t("中华人民共和国万岁")`,然后国际化框架应该能自动处理后续的一系列麻烦。 - -- 要能够比较友好地支持多库多包`monorepo`场景下的国际化协作,当主程序切换语言时,其他包或库也可以自动切换,并且在开发上每个包或库均可以独立地进行开发,集成到主程序时能无缝集成。这点在现有方案上没有找到比较理想的解决方案。 - -- 大部份国际化框架均将中文视为二等公民,大部份情况下您应该采用英文作为第一语言,虽然这不是太大的问题,但是既然要再造一个轮子,为什么不将中文提升到一等公民呢。 - - - - 基于此就开始造出`VoerkaI18n`这个**全新的国际化多语言解决方案**,主要特性包括: - - - -- 全面工程化解决方案,提供初始化、提取文本、自动翻译、编译等工具链支持。 - -- 符合直觉,不需要手动定义文本`Key`映射。 - -- 强大的插值变量`格式化器`机制,可以扩展出强大的多语言特性。 - -- 支持`babel`插件自动导入`t`翻译函数。 - -- 支持`nodejs`、浏览器(`vue`/`react`)前端环境。 - -- 采用`工具链`与`运行时`分开设计,发布时只需要集成很小的运行时。 - -- 高度可扩展的`复数`、`货币`、`数字`等常用的多语言处理机制。 - -- 翻译过程内,提取文本可以自动进行同步,并保留已翻译的内容。 - -- 可以随时添加支持的语言 - -- 支持调用在线自动翻译对提取文本进行翻译。 - - - -# 安装 - -`VoerkaI18n`国际化框架是一个开源多包工程,主要由以下几个包组成: - -- **@voerkai18/cli** - - 包含文本提取/编译等命令行工具,一般应该安装到全局。 - - ```javascript - npm install --g @voerkai18/cli - yarn global add @voerkai18/cli - pnpm add -g @voerkai18/cli - ``` - -- **@voerkai18/runtime** - - **可选的**,运行时,`@voerkai18/cli`的依赖。大部分情况下不需要手动安装,一般仅在开发库项目时采用独立的运行时依赖。 - - ```javascript - npm install --save @voerkai18/runtime - yarn add @voerkai18/runtime - pnpm add @voerkai18/runtime - ``` - -- **@voerkai18/formatters** - - **可选的**,一些额外的格式化器,可以按需进行安装到`dependencies`中,用来扩展翻译时对插值变量的额外处理。 - -- **@voerkai18/babel** - - 可选的`babel`插件,用来实现自动导入翻译函数和翻译文本映射自动替换。 - -- **@voerkai18/vue** - - 可选的`vue`插件,用来为Vue应用提供语言动态切换功能。 - -- **@voerkai18/vite** - - 可选的`vite`插件,用来为`vite`应用提供自动导入翻译函数和翻译文本映射自动替换。 - - -# 快速入门 - -本节以标准的`Nodejs`应用程序为例,简要介绍`VoerkaI18n`国际化框架的基本使用。其他`vue`或`react`应用的使用也基本相同。 - -```shell -myapp - |--package.json - |--index.js -``` - -在本项目的所有支持的源码文件中均可以使用`t`函数对要翻译的文本进行包装,简单而粗暴。 - -```javascript -// index.js -console.log(t("中华人民共和国万岁")) -console.log(t("中华人民共和国成立于{}",1949)) -``` - -`t`翻译函数是从`myapp/languages/index.js`文件导出的翻译函数,但是现在`myapp/languages`还不存在,后续会使用工具自动生成。`voerkai18n`后续会使用正则表达式对提取要翻译的文本。 - -## 第一步:安装命令行工具 - -```shell -> npm install -g @voerkai18n/cli -> yarn global add @voerkai18n/cli ->pnpm add -g @voerkai18/cli -``` - -## 第二步:初始化工程 - -在工程目录中运行`voerkai18n init`命令进行初始化。 - -```javascript -> voerkai18n init -``` - -上述命令会在当前工程目录下创建`languages/settings.json`文件。如果您的源代码在`src`子文件夹中,则会创建在`src/languages/settings.json` - -`settings.json`内容如下: - -```json -{ - "languages": [ - { - "name": "zh", - "title": "zh" - }, - { - "name": "en", - "title": "en" - } - ], - "defaultLanguage": "zh", - "activeLanguage": "zh", - "namespaces": {} -} -``` - -上述命令代表了: - -- 本项目拟支持`中文`和`英文`两种语言。 -- 默认语言是`中文`(即在源代码中直接使用中文) -- 激活语言是`中文` - -**注意:** - -- `voerkai18n init`是可选的,`voerkai18n extract`也可以实现相同的功能。 -- 一般情况下,您可以手工修改`settings.json`,如定义名称空间。 - -## 第三步:提取文本 - -接下来我们使用`voerkai18n extract`命令来自动扫描工程源码文件中的需要的翻译的文本信息。 - -```shell -myapp>voerkai18n extract -``` - -执行`voerkai18n extract`命令后,就会在`myapp/languages`通过生成`translates/default.json`、`settings.json`等相关文件。 - -- **translates/default.json** : 该文件就是需要进行翻译的文本信息。 - -- **settings.json**: 语言环境的基本配置信息,可以进行修改。 - -最后文件结构如下: - -```shell -myapp - |-- languages - |-- settings.json // 语言配置文件 - |-- translates // 此文件夹是所有需要翻译的内容 - |-- default.json // 默认名称空间内容 - |-- package.json - |-- index.js - -``` - -**如果略过第一步中的`voerkai18n init`,也可以使用以下命令来为创建和更新`settinbgs.json`** - -```javascript -myapp>voerkai18n extract -D -lngs zh en de jp -d zh -a zh -``` - -以上命令代表: - -- 扫描当前文件夹下所有源码文件,默认是`js`、`jsx`、`html`、`vue`文件类型。 -- 计划支持`zh`、`en`、`de`、`jp`四种语言 -- 默认语言是中文。(指在源码文件中我们直接使用中文即可) -- 激活语言是中文(即默认切换到中文) -- `-D`代表显示扫描调试信息 - -## 第四步:翻译文本 - -接下来就可以分别对`language/translates`文件夹下的所有`JSON`文件进行翻译了。每个`JSON`文件大概如下: - -```json -{ - "中华人民共和国万岁":{ - "en":"<在此编写对应的英文翻译内容>", - "de":"<在此编写对应的德文翻译内容>" - "jp":"<在此编写对应的日文翻译内容>", - "$files":["index.js"] // 记录了该信息是从哪几个文件中提取的 - }, - "中华人民共和国成立于{}":{ - "en":"<在此编写对应的英文翻译内容>", - "de":"<在此编写对应的德文翻译内容>" - "jp":"<在此编写对应的日文翻译内容>", - "$files":["index.js"] - } -} -``` - -我们只需要修改该文件翻译对应的语言即可。 - -**重点:如果翻译期间对源文件进行了修改,则只需要重新执行一下`voerkai18n extract`命令,该命令会进行以下操作:** - -- 如果文本内容在源代码中已经删除了,则会自动从翻译清单中删除。 -- 如果文本内容在源代码中已修改了,则会视为新增加的内容。 -- 如果文本内容已经翻译了一部份了,则会保留已翻译的内容。 - -因此,反复执行`voerkai18n extract`命令是安全的,不会导致进行了一半的翻译内容丢失,可以放心执行。 - -大部分国际化解决方案至此就需要交给人工进行翻译了,但是`voerkai18n`除了手动翻译外,通过`voerkai18n translate`命令来实现**调用在线翻译服务**进行自动翻译。 - -```javascript ->voerkai18n translate --provider baidu --appkey <在百度翻译上申请的密钥> --appid <在百度翻译上申请的appid> -``` - - 在项目文件夹下执行上面的语句,将会自动调用百度的在线翻译API进行翻译,以现在的翻译水平而言,您只需要进行少量的微调即可。关于`voerkai18n translate`命令的使用请查阅后续介绍。 - -## 第五步:编译语言包 - -当我们完成`myapp/languages/translates`下的所有`JSON语言文件`的翻译后(如果配置了名称空间后,每一个名称空间会对应生成一个文件,详见后续`名称空间`介绍),接下来需要对翻译后的文件进行编译。 - -```shell -myapp> voerkai18n compile -``` - -`compile`命令根据`myapp/languages/translates/*.json`和`myapp/languages/settings.json`文件编译生成以下文件: - -```javascript - |-- languages - |-- settings.json // 语言配置文件 - |-- idMap.js // 文本信息id映射表 - |-- runtime.js // 运行时源码 - |-- index.js // 包含该应用作用域下的翻译函数等 - |-- zh.js // 语言包 - |-- en.js - |-- jp.js - |-- de.js - |-- translates // 此文件夹包含了所有需要翻译的内容 - |-- default.json - |-- package.json - |-- index.js - -``` - -## 第六步:导入翻译函数 - -第一步中我们在源文件中直接使用了`t`翻译函数包装要翻译的文本信息,该`t`翻译函数就是在编译环节自动生成并声明在`myapp/languages/index.js`中的。 - -```javascript -import { t } from "./languages" -``` - -因此,我们需要在需要进行翻译时导入该函数即可。 - -但是如果源码文件很多,重次重复导入`t`函数也是比较麻烦的,所以我们也提供了一个`babel/vite`等插件来自动导入`t`函数。 - -## 第六步:切换语言 - -当需要切换语言时,可以通过调用`change`方法来切换语言。 - -```javascript -import { i18nScope } from "./languages" - -// 切换到英文 -await i18nScope.change("en") -// VoerkaI18n是一个全局单例,可以直接访问 -await VoerkaI18n.change("en") -``` - -`i18nScope.change`与`VoerkaI18n.change`两者是等价的。 - -一般可能也需要在语言切换后进行界面更新渲染,可以订阅事件来响应语言切换。 - -```javascript -import { i18nScope } from "./languages" - -// 切换到英文 -i18nScope.on((newLanguage)=>{ - ... -}) -// -VoerkaI18n.on((newLanguage)=>{ - ... -}) -``` - -# 指南 - -## 翻译函数 - -默认提供翻译函数`t`用来进行翻译。一般情况下,`t`函数在执行`voerkai18n compile`命令生成在工程目录下的`languages`文件夹中。 -```javascript - -// 从当前语言包文件夹index.js中导入翻译函数 -import { t } from "/languages" - -// 不含插值变量 -t("中华人民共和国") - -// 位置插值变量 -t("中华人民共和国{}","万岁") -t("中华人民共和国成立于{}年,首都{}",1949,"北京") - -// 当仅有两个参数且第2个参数是[]类型时,自动展开第一个参数进行位置插值 -t("中华人民共和国成立于{year}年,首都{capital}",[1949,"北京"]) - -// 当仅有两个参数且第2个参数是{}类型时,启用字典插值变量 -t("中华人民共和国成立于{year}年,首都{capital}",{year:1949,capital:"北京"}) - -// 插值变量可以是同步函数,在进行插值时自动调用。 -t("中华人民共和国成立于{year}年,首都{capital}",()=>1949,"北京") - -// 对插值变量启用格式化器 -t("中华人民共和国成立于{birthday | year}年",{birthday:new Date()}) - -``` - -**注意:** - -- `voerkai18n`使用正则表达式来提取要翻译的内容,因此`t()`可以使用在任意地方。 - -## 插值变量 - -`voerkai18n`的`t`函数支持使用**插值变量**,用来传入一个可变内容。 - -插值变量有`命名插值变量`和`位置插值变量`。 - -### **命名插值变量** - -可以在t函数中使用`{变量名称}`表示一个命名插值变量。 - -```javascript -t("我姓名叫{name},我今年{age}岁",{name:"tom",age:12}) -// 如果值是函数会自动调用 -t("我姓名叫{name},我今年{age}岁",{name:"tom",age:()=>12}) -``` - -仅当`t`函数仅有两个参数且第2个参数是`{}`类型时,启用字典插值变量,翻译时会自动进行插值。 - -### 位置插值变量 - -可以在t函数中使用一个空的`{}`表示一个位置插值变量。 - -```javascript -t("我姓名叫{},我今年{}岁","tom",12) -// 如果值是函数会自动调用 -t("我姓名叫{},我今年{}岁","tom",()=>12}) -// 如果只有两个参数,且第2个参数是一个数组,会自动展开 -t("我姓名叫{},我今年{}岁",["tom",12]) -//如果第2个参数不是{}时就启用位置插值。 -t("我姓名叫{name},我今年{age}岁","tom",()=>12) -``` - - -## 插值变量格式化 - -`voerka-i18n`支持强大的插值变量格式化机制,可以在插值变量中使用`{变量名称 | 格式化器名称 | 格式化器名称(...参数) | ... }`类似管道操作符的语法,将上一个输出作为下一个输入,从而实现对变量值的转换。此机制是`voerka-i18n`实现复数、货币、数字等多语言支持的基础。 - -我们假设定义以下格式化器(如果定义格式化器,详见后续)来进行示例。 - -- **UpperCase**:将字符转换为大写 -- **division**:对数字按每n位一个逗号分割,支持一个可选参数分割位数,如`division(123456)===123,456`,`division(123456,4)===12,3456` -- **mr** : 自动添加一个先生称呼 - -```javascript -// My name is TOM -t("My name is { name | UpperCase }",{name:"tom"}) - -// 我国2021年的GDP是¥14,722,730,697,890 -t("我国2021年的GDP是¥{ gdp | division}",{gdp:14722730697890}) - -// 支持为格式化器提供参数,按4位一逗号分割 -// 我国2021年的GDP是¥14,7227,3069,7890 -t("我国2021年的GDP是¥{ gdp | division(4)}",{gdp:14722730697890}) - -// 支持连续使用多个格式化器 -// My name is Mr.TOM -t("My name is { name | UpperCase | mr }",{name:"tom"}) - - -``` - -每个格式化器本质上是一个`(value)=>{...}`的函数,并且能**将上一个格式化器的输出作为下一个格式化器的输入**,格式化器具有如下特性: - -- **无参数格式化器** - - 使用无参数格式化器时只需传入名称即可。例如:`My name is { name | UpperCase }` - -- **有参数格式化器** - - 格式化器支持传入参数,如`{ gdp | division(4)}`、`{ date | format('yyyy/MM/DD')}` - - 特别需要注意的是,格式化器的参数只能支持简单的类型的参数,如`数字`、`布尔型`、`字符串`。 - - **不支持数组、对象和函数参数,也不支持复杂的表达式参数。** - -- **支持连续使用多个格式化器** - - 就如您预期的一样,**将上一个格式化器的输出作为下一个格式化器的输入**。 - - `{data | f1 | f2 | f3(1)}`等效于` f3(f2(f1(data)),1)` - -## 日期时间 - -`@voerkai18n/runtime`内置了对日期时间进行处理的格式化器,可以直接使用,不需要额外的安装。 - -```javascript -// 切换到中文 -t("现在是{d | date}",new Date()) // == 现在是2022年3月12日 -t("现在是{d | time}",new Date()) // == 现在是18点28分12秒 -t("现在是{d | shorttime}",new Date()) // == 现在是18:28:12 -t("现在是{}",new Date()) // == 现在是2022年3月12日 18点28分12秒 - -// 切换到英文 -t("现在是{d | date}",new Date()) // == Now is 2022/3/12 -t("现在是{d | time}",new Date()) // == Now is 18:28:12 -t("现在是{}",new Date()) // == Now is 2022/3/20 19:17:24' -``` -## 复数 - -当翻译文本内容是一个`数组`时启用复数处理机制。即在`langauges/tranclates/*.json`中的文本翻译项是一个数据。 - -### 启用复数处理机制 -假设在`index.html`文件中具有一个翻译内容 -```javascript - t("我{}一辆车") -``` -经过`extract`命令提取为翻译文件后,如下: -```json -// languages/translates/default.json -{ - "我有{}辆车":{ - "en":"", - "de":"...." - } -} -``` -现在我们要求引入复数处理机制,为不同数量采用不同的翻译,只需要将上述翻译文本更改为数组形式。 -```json -{ - "我有{}辆车":{ - "en":["I don't have car","I have a car","I have two cars","I have {} cars"], - "en":["I don't have car","I have a car","I have {} cars"], - "en":["I don't have car","I have {} cars"], - "de":"...." - } -} -``` -上例中,只需要在翻译文件中将上述的`en:""`更改为`[<0对应的复数文本>,<1对应的复数文本>,...,]`形式代表启动复数机制. -- 可以灵活地为每一个数字(`0、1、2、...、n`)对应的复数形式进行翻译 -- 数量数字大于数组长度,则总是取最后一个复数形式 -- 复数形式的文本同样支持位置插值和变量插值。 - - -### 对应的翻译函数 - - -启用复数处理机制后,在`t`函数根据变量值来决定采用单数还是复数,按如下规则进行处理。 - - -- **不存在插值变量且t函数的第2个参数是数字** - -```javascript - -t("我有一辆车",0) // == "I don't have a car" -t("我有一辆车",1) // == "I have a car" -t("我有一辆车",2) // == "I have two cars" -t("我有一辆车",100) // == "I have 100 cars" -``` - -- **存在插值变量且t函数的第2个参数是数字** - -就中文而言,上述没有指定插值变量是比较别扭的,一般可以引入一个位置插值变量更加友好。 -```javascript - -t("我有{}辆车",0) // == "I don't have a car" -t("我有{}辆车",1) // == "I have a car" -t("我有{}辆车",2) // == "I have two cars" -t("我有{}辆车",100) // == "I have 100 cars" -``` - -- **复数命名插值变量** - -当启用复数功能时,`t`函数需要知道根据哪个变量来决定采用何种复数形式。 - -**当采用位置变量插值时,`t`函数取第一个数字类型参数作为位置插值复数。** - - -```javascript -t("{}有{}辆车","张三",0) -``` - -**当采用命名变量插值时,`t`函数约定当插值字典中存在以`$字符开头`的变量时,并且值是`数字`时,根据该变量来引用复数。** - -下例中,`t`函数根据`$count`值来处理复数。 - -```javascript -t("{name}有{$count}辆车",{name:"张三",$count:1}) -``` - -- **示例** - -```javascript -// languages/translates/default.json -{ - "第{}章":{ - en:[ - "Chapter Zero","Chapter One", "Chapter Two", "Chapter Three","Chapter Four", - "Chapter Five","Chapter Six","Chapter Seven","Chapter Eight","Chapter Nine", - "Chapter {}" - ], - zh:["起始","第一章", "第二章", "第三章","第四章","第五章","第六章","第七章","第八章","第九章",“第{}章”] - } -} -// 翻译函数 -t("第{}章",0) // == Chapter Zero -t("第{}章",1) // == Chapter One -t("第{}章",2) // == Chapter Two -t("第{}章",3) // == Chapter Three -t("第{}章",4) // == Chapter Four -t("第{}章",5) // == Chapter Five -t("第{}章",6) // == Chapter Six -t("第{}章",7) // == Chapter Seven -... -// 超过取最后一项 -t("第{}章",100) // == Chapter 100 -``` - - -## 字典 - -`voerkiai18n`内置一个`dict`格式化器,可以直接使用。 - -```javascript -// 假设网络状态取值:0=初始化,1=正在连接,2=已连接,3=正在断开.4=已断开,>4=未知 - -t("当前状态:{status | dict(0,'初始化',1,'正在连接',2,'已连接',3,'正在断开',4,'已断开','未知') }",status) -``` - -## 货币 - - - -## 名称空间 - -`voerkai18n `的名称空间是为了解决当源码文件非常多时,通过名称空间对翻译内容进行分类翻译的。 - -假设一个大型项目,其中源代码文件有上千个。默认情况下,`voerkai18n extract`会扫描所有源码文件将需要翻译的文本提取到`languages/translates/default.json`文件中。由于文件太多会导致以下问题: - -- 内容太多导致`default.json`文件太大,有利于管理 -- 有些翻译往往需要联系上下文才可以作出更准确的翻译,没有适当分类,不容易联系上下文。 - -因此,引入`名称空间`就是目的就是为了解决此问题。 - -配置名称空间,需要配置`languages/settings.json`文件。 - -```javascript -// 工程目录:d:/code/myapp -// languages/settings.json -module.exports = { - namespaces:{ - //"名称":"相对路径", - “routes”:“routes”, - "auth":"core/auth", - "admin":"views/admin" - } -} -``` - -以上例子代表: - -- 将`d:\code\myapp\routes`中扫描到的文本提取到`routes.json`中。 -- 将`d:\code\myapp\auth`中扫描到的文本提取到`auth.json`中。 -- 将`d:\code\myapp\views/admin`中扫描到的文本提取到`admin.json`中。 - -最终在` languages/translates`中会包括: - -```shell -languages - |-- translates - |-- default.json - |-- routes.sjon - |-- auth.json - |-- admin.json -``` - -然后,`voerkai18n compile`在编译时会自动合并这些文件,后续就不再需要名称空间的概念了。 - -`名称空间`仅仅是为了解决当翻译内容太多时的分类问题。 - - - -## 切换语言 - -可以通过全局单例或当前作用域实例切换语言。 - -```javascript -import { i18nScope } from "./languages" - -// 切换到英文 -await i18nScope.change("en") -// VoerkaI18n是一个全局单例,可以直接访问 -VoerkaI18n.change("en") -``` - -侦听语言切换事件: - -```javascript -import { i18nScope } from "./languages" - -// 切换到英文 -i18nScope.on((newLanguage)=>{ - ... -}) -// -VoerkaI18n.on((newLanguage)=>{ - ... -}) -``` - -## Vue应用 - -在`Vue3`应用中引入`voerkai18n`来添加国际化应用需要由两个插件来简化应用。 - -- **@voerkai18n/vue** - - **Vue插件**,在初始化`Vue`应用时引入,提供访问`当前语言`、`切换语言`、`自动更新`等功能。 - -- **@voerkai18n/vite** - - **Vite插件**,在`vite.config.js`中配置,用来实现`自动文本映射`、`自动导入t函数`等功能。 - - - -`@voerkai18n/vue`和`@voerkai18n/vite`两件插件相互配合,安装配置好这两个插件后,就可以在`Vue`文件使用多语言`t`函数。 - -**重点:`t`函数会在使用`@voerkai18n/vite`插件后自动注入,因此在`Vue`文件中可以直接使用。** - -```Vue - - - -``` - -**说明:** - -- 事实上,就算没有`@voerkai18n/vue`和`@voerkai18n/vite`两件插件相互配合,只需要导入`t`函数也就可以直接使用。这两个插件只是很简单的封装而已。 -- 如果要在应用中进行`语言动态切换`,则需要在应用中引入`@voerkai18n/vue`,请参阅`@voerkai18n/vue`插件使用说明。 -- `@voerkai18n/vite`的使用请参阅后续说明。 - -## React应用 - - - -# 高级特性 - -## 运行时 - -`@voerkai18n/runtime`是`voerkai18n`的运行时依赖,支持两种依赖方式。 - -- **源码依赖** - - 默认情况下,运行`voerkai18n compile`时会在`languages`文件下生成运行时文件`runtime.js`,该文件被`languages/index.js`引入,里面是核心运行时`ES6`源代码(`@voerkai18n/runtime`源码),也就是在您的工程中是直接引入的运行时代码,因此就不需要额外安装`@voerkai18n/runtime`了。 - - 此时,`@voerkai18n/runtime`源码就成为您工程是一部分。 - -- **库依赖** - - 当运行`voerkai18n compile --no-inline-runtime`时,就不会生成运行时文件`runtime.js`,而是采用`import "@voerkai18n/runtime`的方式导入运行时,此时会自动/手动安装`@voerkai18n/runtime`到运行依赖中。 - - - -**那么应该选择`源码依赖`还是`库依赖`呢?** - -问题的重点在于,在`monorepo`工程或者`开发库`时,`源码依赖`会导致存在重复的运行时源码。而采用`库依赖`,则不存在此问题。因此: - -- 普通应用采用`源码依赖`方式,运行`voerkai18n compile `来编译语言包。 -- `monorepo`工程或者`开发库`采用`库依赖`,`voerkai18n compile --no-inline-runtime`来编译语言包。 - - - -**注意:** - -- `@voerkai18n/runtime`发布了`commonjs`和`esm`两个经过`babel/rollup`转码后的`ES5`版本。 - -- 每次运行`voerkai18n compile`时均会重新生成`runtime.js`源码文件,为了确保最新的运行时,请及时更新`@voerkai18n/cli` - -- 当升级了`@voerkai18n/runtime`后,需要重新运行`voerkai18n compile`以重新生成`runtime.js`文件。 - - - -## 文本映射 - -虽然`VoerkaI18n`推荐采用`t("中华人民共和国万岁")`形式的符合直觉的翻译形式,而不是采用`t("xxxx.xxx")`这样不符合直觉的形式,但是为什么大部份的国际化方案均采用`t("xxxx.xxx")`形式? - -在我们的方案中,t("中华人民共和国万岁")形式相当于采用原始文本进行查表,语言名形式如下: - -```javascript -// en.js -{ - "中华人民共和国":"the people's Republic of China" -} -// jp.js -{ - "中华人民共和国":"中華人民共和国" -} -``` - -很显然,直接使用文本内容作为`key`,虽然符合直觉,但是会造成大量的冗余信息。因此,`voerkai18n compile`会将之编译成如下: - -```javascript -//idMap.js -{ - "1":"中华人民共和国万岁" -} -// en.js -{ - "1":"Long live the people's Republic of China" -} -// jp.js -{ - "2":"中華人民共和国" -} -``` - -如此,就消除了在`en.js`、`jp.js`文件中的冗余。但是在源代码文件中还存在`t("中华人民共和国万岁")`,整个运行环境中存在两份副本,一份在源代码文件中,一份在`idMap.js`中。 - -为了进一步减少重复内容,因此,我们需要将源代码文件中的`t("中华人民共和国万岁")`更改为`t("1")`,这样就能确保无重复冗余。但是,很显然,我们不可能手动来更改源代码文件,这就需要由`voerkai18n`提供的一个编译区插件来做这一件事了。 - -以`babel-plugin-voerkai18n`插件为例,该插件同时还完成一份任务,就是自动读取`voerkai18n compile`生成的`idMap.js`文件,然后将`t("中华人民共和国万岁")`自动更改为`t("1")`,这样就完全消除了重复冗余信息。 - -所以,在最终形成的代码中,实际上每一个t函数均是`t("1")`、`t("2")`、`t("3")`、`...`、`t("n")`的形式,最终代码还是采用了用`key`来进行转换,只不过这个过程是自动完成的而已。 - -**注意:** - -- 如果没有启用`babel-plugin-voerkai18n`或`vite`等编译区插件,还是可以正常工作,但是会有一份默认语言的冗余信息存在。 - -## 多库联动 - -`voerkai18n `支持多个库国际化的联动和协作,即**当主程序切换语言时,所有引用依赖库也会跟随主程序进行语言切换**,整个切换过程对所有库开发都是透明的。 - -![结构图](./images/arch.png) - -当我们在开发一个应用或者库并`import "./languages"`时,在`langauges/index.js`进行了如下处理: - -- 创建一个`i18nScope`作用域实例 -- 检测当前应用环境下是否具有全局单例`VoerkaI18n` - - 如果存在`VoerkaI18n`全局单例,则会将当前`i18nScope`实例注册到`VoerkaI18n.scopes`中 - - 如果不存在`VoerkaI18n`全局单例,则使用当前`i18nScope`实例的参数来创建一个`VoerkaI18n`全局单例。 -- 在每个应用与库中均可以使用`import { t } from ".langauges`导入本工程的`t`翻译函数,该`t`翻译函数被绑定当前`i18nScope`作用域实例,因此翻译时就只会使用到本工程的文本。这样就割离了不同工程和库之间的翻译。 -- 由于所有引用的`i18nScope`均注册到了全局单例`VoerkaI18n`,当切换语言时,`VoerkaI18n`会刷新切换所有注册的`i18nScope`,这样就实现了各个`i18nScope`即独立,又可以联动语言切换。 - -## 自动导入翻译函数 - -使用`voerkai18 compile`后,要进行翻译时需要从`./languages`导入`t`翻译函数。 - -```javascript -import { t } from "./languages" -``` - -由于默认情况下,`voerkai18 compile`命令会在当前工程的`/languages`文件夹下,这样我们为了导入`t`翻译函数不得不使用各种相对引用,这即容易出错,又不美观,如下: - -```javascript -import { t } from "./languages" -import { t } from "../languages" -import { t } from "../../languages" -import { t } from "../../../languages" -``` - -作为国际化解决方案,一般工程的大部份源码中均会使用到翻译函数,这种使用体验比较差。 - -为此,我们提供了一个`babel`插件来自动完成翻译函数的自动引入,详见后续`bable`插件、`vite`插件等介绍。 - -## 自定义格式化器 - -当我们使用`voerkai18n compile`编译后,会生成`languages/formatters.js`文件,可以在该文件中自定义您自己的格式化器。 - -`formatters.js`文件内容如下: - -```javascript -module.exports = { - // 在所有语言下生效的格式化器 - "*":{ - //[格式化名称]:(value)=>{...}, - //[格式化名称]:(value,arg)=>{...}, - }, - // 在所有语言下只作用于特定数据类型的格式化器 - $types:{ - // [数据类型名称]:(value)=>{...}, - // [数据类型名称]:(value)=>{...}, - }, - zh:{ - $types:{ - // 所有类型的默认格式化器 - "*":{ - }, - Date:{}, - Number:{}, - Boolean:{ }, - String:{}, - Array:{ - - }, - Object:{ - - } - }, - [格式化名称]:(value)=>{.....}, - //..... - }, - en:{ - $types:{ - // [数据类型名称]:(value)=>{...}, - }, - [格式化名称]:(value)=>{.....}, - //.....更多的格式化器..... - } -} -``` - -### 格式化器函数 - -**每一个格式化器就是一个普通的同步函数**,不支持异步函数,格式化器函数可以支持无参数或有参数。 - -- 无参数的格式化器:`(value)=>{....返回格式化的结果...}`。 - -- 带参数的格式化器:`(value,arg1,...)=>{....返回格式化的结果...}`,其中`value`是上一个格式化器的输出结果。 - -### 类型格式化器 - -可以为每一种数据类型指定一个默认的格式化器,支持对`String`、`Date`、`Error`、`Object`、`Array`、`Boolean`、`Number`等数据类型的格式化。 - -当插值变量传入时,如果有定义了对应的的类型格式化器,会默认调用该格式化器对数据进行转换。 - -比如我们定义对`Boolean`类型格式化器, - -```javascript -//formatters.js - -module.exports = { - // 在所有语言下只作用于特定数据类型的格式化器 - $types:{ - Boolean:(value)=> value ? "ON" : "OFF" - } -} -t("灯状态:{status}",true) // === 灯状态:ON -t("灯状态:{status}",false) // === 灯状态:OFF -``` - -在上例中,如果我们想在不同的语言环境下,翻译为不同的显示文本,则可以为不同的语言指定类型格式化器 - -```javascript -//formatters.js -module.exports = { - zh:{ - $types:{ - Boolean:(value)=> value ? "开" : "关" - } - }, - en:{ - $types:{ - Boolean:(value)=> value ? "ON" : "OFF" - } - } -} -// 当切换到中文时 -t("灯状态:{status}",true) // === 灯状态:开 -t("灯状态:{status}",false) // === 灯状态:关 -// 当切换到英文时 -t("灯状态:{status}",true) // === 灯状态:ON -t("灯状态:{status}",false) // === 灯状态:OFF -``` - -**说明:** - -- 完整的类型格式化器定义形式 - - ```javascript - module.exports = { - "*":{ - $types:{...} - }, - zh:{ - $types:{...} - }, - en:{ - $types:{....} - } - } - ``` - - 在匹配应用格式化时会先在当前语言的`$types`中查找匹配的格式化器,如果找不到再上`*.$types`中查找。 - -- `*.$types`代表当所有语言中均没有定义时才匹配的类型格式化。 - -- 类型格式化器是**默认执行的,不需要指定名称**。 - -- 当前作用域的格式化器优先于全局的格式化器。 - -### 通用的格式化器 - -类型格式化器只针对特定数据类型,并且会默认调用。而通用的格式化器需要使用`|`管道符进行显式调用。 - -同样的,通用的格式化器定义在`languages/formatters.js`中。 - -```javascript -module.exports = { - "*":{ - $types:{...}, - [格式化名称]:(value)=>{.....}, - }, - zh:{ - $types:{...}, - [格式化名称]:(value)=>{.....}, - }, - en:{ - $types:{....}, - [格式化名称]:(value)=>{.....}, - [格式化名称]:(value,arg)=>{.....}, - } -} -``` - -每一个格式化器均需要指定一个名称,在进行插值替换时会优先依据当前语言来匹配查找格式化器,如果找不到,再到键名为`*`中查找。 - -```javascript -module.exports = { - "*":{ - uppercase:(value)=>value - }, - zh:{ - uppercase:(value)=>["一","二","三","四","五","六","七","八","九","十"][value-1] - }, - en:{ - uppercase:(value)=>["One","Two","Three","Four","Five","Six","seven","eight","nine","ten"][value-1] - }, - jp:{ - - } -} -// 当切换到中文时 -t("{value | uppercase}",1) // == 一 -t("{value | uppercase}",2) // == 二 -t("{value | uppercase}",3) // == 三 -// 当切换到英文时 -t("{value | uppercase}",1) // == One -t("{value | uppercase}",2) // == Two -t("{value | uppercase}",3) // == Three -// 当切换到日文时,由于在该语言下没有定义uppercase格式式,因此到*中查找 -t("{value | uppercase}",1) // == 1 -t("{value | uppercase}",2) // == 2 -t("{value | uppercase}",3) // == 3 -``` - -### 作用域格式化器 - -定义在`languages/formatters.js`里面的格式化器仅在当前工程生效,也就是仅在当前作用域生效。一般由应用开发者自行扩展。 - -### 全局格式化器 - -定义在`@voerkai18n/runtime`里面的格式化器则全局有效,在所有场合均可以使用,但是其优先级低于作用域内的同名格式化器。目前内置的格式化器有: - -| 名称 | | 说明 | -| ---- | ---- | ---- | -| | | | -| | | | -| | | | - -### 扩展格式化器 - -除了可以在当前项目`languages/formatters.js`自定义格式化器和`@voerkai18n/runtime`里面的全局格式化器外,单列了`@voerkai18n/formatters`项目用来包含了更多的格式化器。 - -作为开源项目,欢迎大家提交贡献更多的格式化器。 - -## 语言包 - -当使用`webpack`、`rollup`、`esbuild`进行项目打包时,默认语言包采用静态加载,会被打包进行源码中,而其他语言则采用异步打包方式。在`languages/index.js`中。 - -```javascript -const defaultMessages = require("./zh.js") -const activeMessages = defaultMessages - -// 语言作用域 -const scope = new i18nScope({ - default: defaultMessages, // 默认语言包 - messages : activeMessages, // 当前语言包 - .... - // 以下为每一种语言生成一个异步打包语句 - loaders:{ - "en" : ()=>import("./en.js") - "de" : ()=>import("./de.js") - "jp" : ()=>import("./jp.js") - }) -``` - -## 自动翻译 - -内置的`voerkai18n translate`命令能调用在线翻译服务完成对提取的文本的自动翻译。 - -目前支持访问百度在线API进行自动翻译。百度提供了免费的在线API,虽然只支持`QPS=1`,即每秒调用一次。但是`voerkai18n translate`命令会对要翻译的文本进行合并后再调用,因此大部分情况下,均足够使用了。 - -执行`voerkai18n translate`命令后,将大大提高您国际化的效率。 - -## 语言代码 - -请参阅https://fanyi-api.baidu.com/doc/21。 - -# 扩展工具 - -## babel插件 - -全局安装`@voerkai18n/babel`插件用来进行自动导入`t`函数和自动文本映射。 - -```javascript -> npm install -g @voerkai18n/babel -> yarn global add @voerkai18n/babel -> pnpm add -g @voerkai18n/babel -``` - -使用方法如下: - -- 在`babel.config.js`中配置插件 - -```javascript -const i18nPlugin = require("@voerkai18n/babel") -module.expors = { - plugins: [ - [ - i18nPlugin, - { - // 可选,指定语言文件存放的目录,即保存编译后的语言文件的文件夹 - // 可以指定相对路径,也可以指定绝对路径 - // location:"", - autoImport:"#/languages" - } - ] - ] -} -``` - -这样,当在进行`babel`转码时,就会自动在`js`源码文件中导入`t`翻译函数。 - -`babel-plugin-voerkai18n`插件支持以下参数: - -- **location** - - 配置`langauges`文件夹位置,默认会使用当前文件夹下的`languages`文件。 - - 因此,如果你的`babel.config.js`在项目根文件夹,而`languages`文件夹位于`src/languages`,则可以将`location="src/languages"`,这样插件会自动从该文件夹读取需要的数据。 - -- **autoImport** - - 用来配置导入的路径。比如 `autoImport="#/languages" `,则当在babel转码时,如果插件检测到t函数的存在并没有导入,就会自动在该源码中自动导入`import { t } from "#/languages"` - - 配置`autoImport`时需要注意的是,为了提供一致的导入路径,视所使用的打包工具或转码插件,如`webpack`、`rollup`等。比如使用`babel-plugin-module-resolver` - - ```javascript - module.expors = { - plugins: [ - [ - "module-resolver", - { - root:"./", - alias:{ - "languages":"./src/languages" - } - } - ] - ] - } - ``` - - 这样配置`autoImport="languages"`,则自动导入`import { t } from "languages"`。 - - 如`webpack`、`rollup`等打包工具也有类似的插件可以实现别名等转换,其目的就是让`babel-plugin-voerkai18n`插件能自动导入固定路径,而不是各种复杂的相对路径。 - -## Vue插件 - -在`vue3`项目中可以安装`@voerkai18n/vue`来实现`枚举语言`、`语言切换`等功能。 - -### **安装** - -将`@voerkai18n/vue`安装为运行时依赖 - -```javascript -npm install @voerkai18n/vue -pnpm add @voerkai18n/vue -yarn add @voerkai18n/vue -``` - -### 启用插件 - -```javascript - import { createApp } from 'vue' - import Root from './App.vue' - import i18nPlugin from '@voerkai18n/vue' - import { i18nScope } from './languages' - const app = createApp(Root) - app.use(i18nPlugin,{ i18nScope }) // 重点,需要引入i18nScope - app.mount('#app') -``` - -插件安装成功后,在当前`Vue App`实例上`provide`一个`i18n`响应式实例。 - -### 注入`i18n`实例 - -接下来在组件中按需注入`i18n`实例,可以用来访问当前的`激活语言`、`默认语言`、`切换语言`等。 - -```javascript - -``` - -声明`inject: ['i18n']`后在当前组件实例中就可以访问`this.i18n`,该实例是一个经过`reactive`封闭的响应式对象,其内容是: - -```javascript -this.i18n = { - activeLanguage, // 当前激活语言,可以通过直接赋值来切换语言 - defaultLanguage, // 默认语言名称 - languages // 支持的语言列表=[{name,title},...] -} -``` - -### 应用示例 - -注入`i18n`实例后就可以在此基础上实现`激活语言`、`默认语言`、`切换语言`等功能。 - -```vue - -