mirror of
https://gitee.com/WeBank/fes.js.git
synced 2024-11-29 18:28:09 +08:00
feat: 国际化支持模块化配置 (#217)
This commit is contained in:
parent
33b76940d8
commit
7e0d5ab991
@ -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` 中配置:
|
||||
|
@ -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",
|
||||
|
@ -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',
|
||||
|
@ -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}}};
|
||||
|
13
packages/fes-plugin-locale/src/runtime/locales.js.tpl
Normal file
13
packages/fes-plugin-locale/src/runtime/locales.js.tpl
Normal 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}}
|
||||
];
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
|
||||
export default {
|
||||
home: 'home',
|
||||
store: 'store',
|
||||
editor: 'editor',
|
||||
externalLink: 'externalLink',
|
||||
mock: 'mock'
|
||||
mock: 'mock',
|
||||
test: {
|
||||
b: 1,
|
||||
},
|
||||
};
|
||||
|
6
packages/fes-template/src/locales/home/en-US.js
Normal file
6
packages/fes-template/src/locales/home/en-US.js
Normal file
@ -0,0 +1,6 @@
|
||||
export default {
|
||||
home: 'home',
|
||||
test: {
|
||||
a: 1,
|
||||
},
|
||||
};
|
6
packages/fes-template/src/locales/home/zh-CN.js
Normal file
6
packages/fes-template/src/locales/home/zh-CN.js
Normal file
@ -0,0 +1,6 @@
|
||||
export default {
|
||||
home: '首页',
|
||||
test: {
|
||||
a: 1,
|
||||
},
|
||||
};
|
@ -1,8 +1,9 @@
|
||||
|
||||
export default {
|
||||
home: '首页',
|
||||
store: '状态管理',
|
||||
editor: '编辑器',
|
||||
externalLink: '外部链接',
|
||||
mock: '代理'
|
||||
mock: '代理',
|
||||
test: {
|
||||
b: 1,
|
||||
},
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user