Skip to content

Commit

Permalink
feat: 国际化支持模块化配置 (#217)
Browse files Browse the repository at this point in the history
  • Loading branch information
wanchun authored Sep 15, 2023
1 parent 33b7694 commit 7e0d5ab
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 34 deletions.
19 changes: 19 additions & 0 deletions docs/reference/plugin/plugins/locale.md
Original file line number Diff line number Diff line change
Expand Up @@ -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` 中配置:
Expand Down
3 changes: 2 additions & 1 deletion packages/fes-plugin-locale/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
16 changes: 13 additions & 3 deletions packages/fes-plugin-locale/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}}};

Expand Down
13 changes: 13 additions & 0 deletions packages/fes-plugin-locale/src/runtime/locales.js.tpl
Original file line number Diff line number Diff line change
@@ -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}}
];
44 changes: 33 additions & 11 deletions packages/fes-plugin-locale/src/utils/index.js
Original file line number Diff line number Diff line change
@@ -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,
};
}
7 changes: 4 additions & 3 deletions packages/fes-template/src/locales/en-US.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@

export default {
home: 'home',
store: 'store',
editor: 'editor',
externalLink: 'externalLink',
mock: 'mock'
mock: 'mock',
test: {
b: 1,
},
};
6 changes: 6 additions & 0 deletions packages/fes-template/src/locales/home/en-US.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
home: 'home',
test: {
a: 1,
},
};
6 changes: 6 additions & 0 deletions packages/fes-template/src/locales/home/zh-CN.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
home: '首页',
test: {
a: 1,
},
};
7 changes: 4 additions & 3 deletions packages/fes-template/src/locales/zh-CN.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@

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

0 comments on commit 7e0d5ab

Please sign in to comment.