feat: 国际化支持模块化配置 (#217)

This commit is contained in:
听海 2023-09-15 14:33:42 +08:00 committed by GitHub
parent 33b76940d8
commit 7e0d5ab991
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 101 additions and 34 deletions

View File

@ -69,6 +69,25 @@ export default {
想了解更多语言信息配置、匹配规则,请参考 [Vue I18n](https://vue-i18n.intlify.dev/guide/essentials/syntax.html) 文档。
### 多层配置
如果国际化内容较多,希望模块化配置,则可以这样:
```
src
├── locales
│ ├── zh-CN.js
│ └── en-US.js
| └── system
| ├── zh-CN.js
│ └── en-US.js
└── pages
│ └── index.vue
└── app.js
```
插件会把相同语言的配置合并在一起!
### 编译时配置
在执行 `fes dev` 或者 `fes build` 时,通过此配置生成运行时的代码,在配置文件`.fes.js` 中配置:

View File

@ -29,7 +29,8 @@
},
"dependencies": {
"@fesjs/utils": "^3.0.0",
"vue-i18n": "^9.0.0"
"vue-i18n": "^9.0.0",
"lodash-es": "^4.17.21"
},
"peerDependencies": {
"@fesjs/fes": "^3.0.1",

View File

@ -47,14 +47,24 @@ export default (api) => {
const localeConfigFileBasePath = getLocaleFileBasePath();
const locales = getLocales(localeConfigFileBasePath);
const { files, locales } = getLocales(localeConfigFileBasePath);
const { baseNavigator, ...otherConfig } = userConfig;
api.writeTmpFile({
path: join(namespace, 'locales.js'),
content: Mustache.render(readFileSync(join(__dirname, 'runtime/locales.js.tpl'), 'utf-8'), {
REPLACE_IMPORTS: files,
REPLACE_LOCALES: locales.map((item) => ({
locale: item.locale,
importNames: item.importNames.join(', '),
})),
}),
});
api.writeTmpFile({
path: absoluteFilePath,
content: Mustache.render(readFileSync(join(__dirname, 'runtime/core.tpl'), 'utf-8'), {
REPLACE_LOCALES: locales,
content: Mustache.render(readFileSync(join(__dirname, 'runtime/core.js.tpl'), 'utf-8'), {
REPLACE_DEFAULT_OPTIONS: JSON.stringify(otherConfig, null, 2),
BASE_NAVIGATOR: baseNavigator,
VUE_I18N_PATH: 'vue-i18n',

View File

@ -7,20 +7,8 @@
// 所有插件使用一个语言和配置
import { isRef, unref } from 'vue';
import { createI18n, useI18n } from '{{{ VUE_I18N_PATH }}}';
import { plugin, ApplyPluginsType } from "@@/core/coreExports";
import locales from './locales'
{{#REPLACE_LOCALES}}
import {{importName}} from "{{{path}}}";
{{/REPLACE_LOCALES}}
const locales = [
{{#REPLACE_LOCALES}}
{
locale: "{{locale}}",
message: {{importName}}
},
{{/REPLACE_LOCALES}}
];
const defaultOptions = {{{REPLACE_DEFAULT_OPTIONS}}};

View File

@ -0,0 +1,13 @@
import { merge } from 'lodash-es'
{{#REPLACE_IMPORTS}}
import {{importName}} from "{{{path}}}";
{{/REPLACE_IMPORTS}}
export default [
{{#REPLACE_LOCALES}}
{
locale: "{{locale}}",
message: merge({}, {{importNames}})
},
{{/REPLACE_LOCALES}}
];

View File

@ -1,22 +1,44 @@
import { glob, winPath } from '@fesjs/utils';
import { join, basename } from 'path';
import { glob, winPath } from '@fesjs/utils';
const ignore = /\.(d\.ts|\.test\.(js|ts))$/;
const getRouteName = function (path) {
const routeName = winPath(path);
return routeName
.replace(/\//g, '_')
.replace(/@/g, '_')
.replace(/:/g, '_')
.replace(/-/g, '_')
.replace(/\*/g, 'ALL')
.replace(/\[([a-zA-Z]+)\]/, '_$1')
.replace(/\[...([a-zA-Z]*)\]/, 'FUZZYMATCH-$1');
};
export function getLocales(cwd) {
const files = glob
.sync('*.js', {
cwd,
})
.filter((file) => !file.endsWith('.d.ts') && !file.endsWith('.test.js') && !file.endsWith('.test.jsx'))
.map((fileName) => {
const map = {};
const files = [];
glob.sync('**/*.js', {
cwd,
})
.filter((file) => !ignore.test(file))
.forEach((fileName) => {
const locale = basename(fileName, '.js');
const importName = locale.replace('-', '');
return {
const importName = getRouteName(fileName).replace('.js', '');
const result = {
importName,
locale,
// import语法的路径必须处理win
path: winPath(join(cwd, fileName)),
};
files.push(result);
if (!map[locale]) {
map[locale] = [];
}
map[locale].push(importName);
});
return files;
return {
locales: Object.keys(map).map((key) => ({ locale: key, importNames: map[key] })),
files,
};
}

View File

@ -1,8 +1,9 @@
export default {
home: 'home',
store: 'store',
editor: 'editor',
externalLink: 'externalLink',
mock: 'mock'
mock: 'mock',
test: {
b: 1,
},
};

View File

@ -0,0 +1,6 @@
export default {
home: 'home',
test: {
a: 1,
},
};

View File

@ -0,0 +1,6 @@
export default {
home: '首页',
test: {
a: 1,
},
};

View File

@ -1,8 +1,9 @@
export default {
home: '首页',
store: '状态管理',
editor: '编辑器',
externalLink: '外部链接',
mock: '代理'
mock: '代理',
test: {
b: 1,
},
};