Commit 8882d4e7eafabceb3c53cd5c22ad70ee166921c4
1 parent
3a651767
wip: support multilingual configuration
Showing
24 changed files
with
314 additions
and
77 deletions
build/vite/plugin/dynamicImport/index.ts renamed to build/vite/plugin/transform/dynamic-import/index.ts
1 | 1 | // Used to import all files under `src/views` |
2 | - | |
3 | 2 | // The built-in dynamic import of vite cannot meet the needs of importing all files under views |
4 | - | |
3 | +// Special usage ,Only for this project | |
5 | 4 | import glob from 'glob'; |
6 | 5 | import { Transform } from 'vite/dist/node/transform.js'; |
7 | 6 | |
... | ... | @@ -28,7 +27,6 @@ const dynamicImportTransform = function (env: any = {}): Transform { |
28 | 27 | return code; |
29 | 28 | } |
30 | 29 | |
31 | - // if (!isBuild) return code; | |
32 | 30 | // Only convert the dir |
33 | 31 | try { |
34 | 32 | const files = glob.sync('src/views/**/**.{vue,tsx}', { cwd: process.cwd() }); | ... | ... |
build/vite/plugin/context/transform.ts renamed to build/vite/plugin/transform/globby/index.ts
1 | 1 | // Modified from |
2 | 2 | // https://github.com/luxueyan/vite-transform-globby-import/blob/master/src/index.ts |
3 | 3 | |
4 | -// TODO Currently, it is not possible to monitor file addition and deletion. The content has been changed, the cache problem? | |
4 | +// TODO Deleting files requires re-running the project | |
5 | 5 | import { join } from 'path'; |
6 | 6 | import { lstatSync } from 'fs'; |
7 | 7 | import glob from 'glob'; |
8 | +import globrex from 'globrex'; | |
9 | +import dotProp from 'dot-prop'; | |
8 | 10 | import { createResolver, Resolver } from 'vite/dist/node/resolver.js'; |
9 | 11 | import { Transform } from 'vite/dist/node/transform.js'; |
10 | 12 | |
... | ... | @@ -14,6 +16,8 @@ interface SharedConfig { |
14 | 16 | root?: string; |
15 | 17 | alias?: Record<string, string>; |
16 | 18 | resolvers?: Resolver[]; |
19 | + | |
20 | + includes?: string[]; | |
17 | 21 | } |
18 | 22 | |
19 | 23 | function template(template: string) { |
... | ... | @@ -22,22 +26,78 @@ function template(template: string) { |
22 | 26 | }; |
23 | 27 | } |
24 | 28 | |
25 | -const globbyTransform = function (config: SharedConfig): Transform { | |
29 | +// TODO support hmr | |
30 | +function hmr(isBuild = false) { | |
31 | + if (isBuild) return ''; | |
32 | + return ` | |
33 | + if (import.meta.hot) { | |
34 | + import.meta.hot.accept(); | |
35 | + }`; | |
36 | +} | |
37 | + | |
38 | +// handle includes | |
39 | +function fileInclude(includes: string | string[] | undefined, filePath: string) { | |
40 | + return !includes || !Array.isArray(includes) | |
41 | + ? true | |
42 | + : includes.some((item) => filePath.startsWith(item)); | |
43 | +} | |
44 | + | |
45 | +// Bare exporter | |
46 | +function compareString(modify: any, data: string[][]) { | |
47 | + return modify ? '\n' + data.map((v) => `${v[0]}._path = ${v[1]}`).join('\n') : ''; | |
48 | +} | |
49 | + | |
50 | +function varTemplate(data: string[][], name: string) { | |
51 | + //prepare deep data (for locales) | |
52 | + let deepData: Record<string, object | string> = {}; | |
53 | + let hasDeepData = false; | |
54 | + | |
55 | + //data modify | |
56 | + data.map((v) => { | |
57 | + //check for has deep data | |
58 | + if (v[0].includes('/')) { | |
59 | + hasDeepData = true; | |
60 | + } | |
61 | + | |
62 | + // lastKey is a data | |
63 | + let pathValue = v[0].replace(/\//g, '.').split('.'); | |
64 | + let lastKey: string | undefined = pathValue.pop(); | |
65 | + | |
66 | + let deepValue: Record<any, any> = {}; | |
67 | + if (lastKey) { | |
68 | + deepValue[lastKey.replace('_' + pathValue[0], '')] = lastKey; | |
69 | + } | |
70 | + | |
71 | + // Set Deep Value | |
72 | + deepValue = Object.assign(deepValue, dotProp.get(deepData, pathValue.join('.'))); | |
73 | + dotProp.set(deepData, pathValue.join('.'), deepValue); | |
74 | + }); | |
75 | + | |
76 | + if (hasDeepData) { | |
77 | + return `const ${name} = ` + JSON.stringify(deepData).replace(/\"|\'/g, ''); | |
78 | + } | |
79 | + | |
80 | + return `const ${name} = { ${data.map((v) => v[0]).join(',')} }`; | |
81 | +} | |
82 | + | |
83 | +const globTransform = function (config: SharedConfig): Transform { | |
26 | 84 | const resolver = createResolver( |
27 | 85 | config.root || process.cwd(), |
28 | 86 | config.resolvers || [], |
29 | 87 | config.alias || {} |
30 | 88 | ); |
89 | + const { includes } = config; | |
31 | 90 | const cache = new Map(); |
32 | - | |
33 | 91 | const urlMap = new Map(); |
34 | 92 | return { |
35 | 93 | test({ path }) { |
36 | 94 | const filePath = path.replace('\u0000', ''); // why some path startsWith '\u0000'? |
95 | + | |
37 | 96 | try { |
38 | 97 | return ( |
39 | 98 | !filePath.startsWith(modulesDir) && |
40 | 99 | /\.(vue|js|jsx|ts|tsx)$/.test(filePath) && |
100 | + fileInclude(includes, filePath) && | |
41 | 101 | lstatSync(filePath).isFile() |
42 | 102 | ); |
43 | 103 | } catch { |
... | ... | @@ -47,50 +107,95 @@ const globbyTransform = function (config: SharedConfig): Transform { |
47 | 107 | transform({ code, path, isBuild }) { |
48 | 108 | let result = cache.get(path); |
49 | 109 | if (!result) { |
50 | - const reg = /import\s+([\w\s{}*]+)\s+from\s+(['"])globby(\?path)?!([^'"]+)\2/g; | |
110 | + const reg = /import\s+([\w\s{}*]+)\s+from\s+(['"])globby(\?locale)?(\?path)?!([^'"]+)\2/g; | |
51 | 111 | const match = code.match(reg); |
52 | 112 | if (!match) return code; |
53 | 113 | const lastImport = urlMap.get(path); |
54 | 114 | if (lastImport && match) { |
55 | 115 | code = code.replace(lastImport, match[0]); |
56 | 116 | } |
57 | - result = code.replace(reg, (_, g1, g2, g3, g4) => { | |
58 | - const filePath = path.replace('\u0000', ''); // why some path startsWith '\u0000'? | |
59 | - // resolve path | |
60 | - const resolvedFilePath = g4.startsWith('.') | |
61 | - ? resolver.resolveRelativeRequest(filePath, g4) | |
62 | - : { pathname: resolver.requestToFile(g4) }; | |
63 | - const files = glob.sync(resolvedFilePath.pathname, { dot: true }); | |
64 | - let templateStr = 'import #name# from #file#'; // import default | |
65 | - let name = g1; | |
66 | - const m = g1.match(/\{\s*(\w+)(\s+as\s+(\w+))?\s*\}/); // import module | |
67 | - const m2 = g1.match(/\*\s+as\s+(\w+)/); // import * as all module | |
68 | - if (m) { | |
69 | - templateStr = `import { ${m[1]} as #name# } from #file#`; | |
70 | - name = m[3] || m[1]; | |
71 | - } else if (m2) { | |
72 | - templateStr = 'import * as #name# from #file#'; | |
73 | - name = m2[1]; | |
117 | + result = code.replace( | |
118 | + reg, | |
119 | + ( | |
120 | + _, | |
121 | + // variable to export | |
122 | + exportName, | |
123 | + // bare export or not | |
124 | + bareExporter, | |
125 | + // is locale import | |
126 | + isLocale, | |
127 | + // inject _path attr | |
128 | + injectPath, | |
129 | + // path export | |
130 | + globPath | |
131 | + ) => { | |
132 | + const filePath = path.replace('\u0000', ''); // why some path startsWith '\u0000'? | |
133 | + // resolve path | |
134 | + | |
135 | + const resolvedFilePath = globPath.startsWith('.') | |
136 | + ? resolver.resolveRelativeRequest(filePath, globPath) | |
137 | + : { pathname: resolver.requestToFile(globPath) }; | |
138 | + | |
139 | + const files = glob.sync(resolvedFilePath.pathname, { dot: true }); | |
140 | + | |
141 | + let templateStr = 'import #name# from #file#'; // import default | |
142 | + let name = exportName; | |
143 | + const m = exportName.match(/\{\s*(\w+)(\s+as\s+(\w+))?\s*\}/); // import module | |
144 | + const m2 = exportName.match(/\*\s+as\s+(\w+)/); // import * as all module | |
145 | + if (m) { | |
146 | + templateStr = `import { ${m[1]} as #name# } from #file#`; | |
147 | + name = m[3] || m[1]; | |
148 | + } else if (m2) { | |
149 | + templateStr = 'import * as #name# from #file#'; | |
150 | + name = m2[1]; | |
151 | + } | |
152 | + | |
153 | + const templateRender = template(templateStr); | |
154 | + | |
155 | + const groups: Array<string>[] = []; | |
156 | + const replaceFiles = files.map((f, i) => { | |
157 | + const fileNameWithAlias = resolver.fileToRequest(f); | |
158 | + | |
159 | + const file = bareExporter + fileNameWithAlias + bareExporter; | |
160 | + | |
161 | + if (isLocale) { | |
162 | + const globrexRes = globrex(globPath, { extended: true, globstar: true }); | |
163 | + | |
164 | + // Get segments for files like an en/system ch/modules for: | |
165 | + // ['en', 'system'] ['ch', 'modules'] | |
166 | + const matchedGroups = globrexRes.regex.exec(fileNameWithAlias); | |
167 | + | |
168 | + if (matchedGroups && matchedGroups.length) { | |
169 | + const matchedSegments = matchedGroups[1]; //first everytime "Full Match" | |
170 | + const name = matchedGroups[2] + '_' + matchedSegments.split('/').shift(); | |
171 | + //send deep way like an (en/modules/system/dashboard) into groups | |
172 | + groups.push([matchedSegments + name, file]); | |
173 | + return templateRender({ | |
174 | + name, | |
175 | + file, | |
176 | + }); | |
177 | + } | |
178 | + } else { | |
179 | + groups.push([name + i, file]); | |
180 | + return templateRender({ name: name + i, file }); | |
181 | + } | |
182 | + }); | |
183 | + // save in memory used result | |
184 | + const filesJoined = replaceFiles.join('\n'); | |
185 | + | |
186 | + urlMap.set(path, filesJoined); | |
187 | + return [ | |
188 | + filesJoined, | |
189 | + compareString(injectPath, groups), | |
190 | + varTemplate(groups, name), | |
191 | + '', | |
192 | + ].join('\n'); | |
74 | 193 | } |
75 | - const temRender = template(templateStr); | |
76 | - | |
77 | - const groups: Array<string>[] = []; | |
78 | - const replaceFiles = files.map((f, i) => { | |
79 | - const file = g2 + resolver.fileToRequest(f) + g2; | |
80 | - groups.push([name + i, file]); | |
81 | - return temRender({ name: name + i, file }); | |
82 | - }); | |
83 | - urlMap.set(path, replaceFiles.join('\n')); | |
84 | - return ( | |
85 | - replaceFiles.join('\n') + | |
86 | - (g3 ? '\n' + groups.map((v) => `${v[0]}._path = ${v[1]}`).join('\n') : '') + | |
87 | - `\nconst ${name} = { ${groups.map((v) => v[0]).join(',')} }\n` | |
88 | - ); | |
89 | - }); | |
194 | + ); | |
90 | 195 | if (isBuild) cache.set(path, result); |
91 | 196 | } |
92 | - return result; | |
197 | + return `${result}${hmr(isBuild)}`; | |
93 | 198 | }, |
94 | 199 | }; |
95 | 200 | }; |
96 | -export default globbyTransform; | |
201 | +export default globTransform; | ... | ... |
package.json
... | ... | @@ -22,7 +22,7 @@ |
22 | 22 | }, |
23 | 23 | "dependencies": { |
24 | 24 | "@iconify/iconify": "^2.0.0-rc.2", |
25 | - "@vueuse/core": "4.0.0-beta.41", | |
25 | + "@vueuse/core": "4.0.0-rc.3", | |
26 | 26 | "ant-design-vue": "2.0.0-beta.15", |
27 | 27 | "apexcharts": "3.22.0", |
28 | 28 | "axios": "^0.21.0", |
... | ... | @@ -35,7 +35,7 @@ |
35 | 35 | "qrcode": "^1.4.4", |
36 | 36 | "vditor": "^3.6.2", |
37 | 37 | "vue": "^3.0.2", |
38 | - "vue-i18n": "^9.0.0-beta.7", | |
38 | + "vue-i18n": "^9.0.0-beta.8", | |
39 | 39 | "vue-router": "^4.0.0-rc.3", |
40 | 40 | "vuex": "^4.0.0-rc.1", |
41 | 41 | "vuex-module-decorators": "^1.0.1", |
... | ... | @@ -50,6 +50,7 @@ |
50 | 50 | "@purge-icons/generated": "^0.4.1", |
51 | 51 | "@types/echarts": "^4.9.1", |
52 | 52 | "@types/fs-extra": "^9.0.4", |
53 | + "@types/globrex": "^0.1.0", | |
53 | 54 | "@types/koa-static": "^4.0.1", |
54 | 55 | "@types/lodash-es": "^4.17.3", |
55 | 56 | "@types/mockjs": "^1.0.3", |
... | ... | @@ -68,6 +69,7 @@ |
68 | 69 | "conventional-changelog-cli": "^2.1.1", |
69 | 70 | "conventional-changelog-custom-config": "^0.3.1", |
70 | 71 | "cross-env": "^7.0.2", |
72 | + "dot-prop": "^6.0.0", | |
71 | 73 | "dotenv": "^8.2.0", |
72 | 74 | "eslint": "^7.13.0", |
73 | 75 | "eslint-config-prettier": "^6.15.0", |
... | ... | @@ -75,6 +77,7 @@ |
75 | 77 | "eslint-plugin-vue": "^7.1.0", |
76 | 78 | "esno": "^0.2.4", |
77 | 79 | "fs-extra": "^9.0.1", |
80 | + "globrex": "^0.1.2", | |
78 | 81 | "husky": "^4.3.0", |
79 | 82 | "koa-static": "^5.0.0", |
80 | 83 | "less": "^3.12.2", | ... | ... |
src/hooks/web/useLocale.ts
0 → 100644
1 | +import type { LocaleType } from '/@/locales/types'; | |
2 | +import { appStore } from '/@/store/modules/app'; | |
3 | + | |
4 | +export function useLocale() { | |
5 | + /** | |
6 | + * | |
7 | + */ | |
8 | + function getLocale(): string { | |
9 | + return appStore.getProjectConfig.locale; | |
10 | + } | |
11 | + | |
12 | + /** | |
13 | + * | |
14 | + * @param locale | |
15 | + */ | |
16 | + async function changeLocale(locale: LocaleType): Promise<void> { | |
17 | + appStore.commitProjectConfigState({ locale: locale }); | |
18 | + } | |
19 | + | |
20 | + return { getLocale, changeLocale }; | |
21 | +} | ... | ... |
src/locales/index.ts
0 → 100644
src/locales/lang/en/routes/menus/dashboard.ts
0 → 100644
src/locales/lang/en/system/basic.ts
0 → 100644
src/locales/lang/en/system/login.ts
0 → 100644
src/locales/lang/ru/routes/menus/dashboard.ts
0 → 100644
src/locales/lang/ru/system/basic.ts
0 → 100644
src/locales/lang/ru/system/login.ts
0 → 100644
src/locales/lang/zhCN/routes/menus/dashboard.ts
0 → 100644
src/locales/lang/zhCN/system/basic.ts
0 → 100644
src/locales/lang/zhCN/system/login.ts
0 → 100644
src/locales/types.ts
0 → 100644
1 | +export type LocaleType = 'zhCN' | 'en' | 'ru' | 'ja'; | ... | ... |
src/main.ts
... | ... | @@ -5,6 +5,7 @@ import { setupStore } from '/@/store'; |
5 | 5 | import { setupAntd } from '/@/setup/ant-design-vue'; |
6 | 6 | import { setupErrorHandle } from '/@/setup/error-handle'; |
7 | 7 | import { setupGlobDirectives } from '/@/setup/directives'; |
8 | +import { setupI18n } from '/@/setup/i18n'; | |
8 | 9 | |
9 | 10 | import { setupProdMockServer } from '../mock/_createProductionServer'; |
10 | 11 | import { setApp } from '/@/setup/App'; |
... | ... | @@ -15,11 +16,16 @@ import { isDevMode, isProdMode, isUseMock } from '/@/utils/env'; |
15 | 16 | |
16 | 17 | import '/@/design/index.less'; |
17 | 18 | |
19 | +import '/@/locales/index'; | |
20 | + | |
18 | 21 | const app = createApp(App); |
19 | 22 | |
20 | 23 | // Configure component library |
21 | 24 | setupAntd(app); |
22 | 25 | |
26 | +// Multilingual configuration | |
27 | +setupI18n(app); | |
28 | + | |
23 | 29 | // Configure routing |
24 | 30 | setupRouter(app); |
25 | 31 | ... | ... |
src/settings/projectSetting.ts
src/setup/i18n/index.ts
0 → 100644
1 | +import type { App } from 'vue'; | |
2 | +import type { I18n, Locale, I18nOptions } from 'vue-i18n'; | |
3 | + | |
4 | +import { createI18n } from 'vue-i18n'; | |
5 | +import localeMessages from '/@/locales'; | |
6 | +import { useLocale } from '/@/hooks/web/useLocale'; | |
7 | + | |
8 | +const { getLocale } = useLocale(); | |
9 | + | |
10 | +const localeData: I18nOptions = { | |
11 | + legacy: false, | |
12 | + locale: getLocale(), | |
13 | + // TODO: setting fallback inside settings | |
14 | + fallbackLocale: 'en', | |
15 | + messages: localeMessages, | |
16 | + // availableLocales: ['ru'], | |
17 | + sync: true, //If you don’t want to inherit locale from global scope, you need to set sync of i18n component option to false. | |
18 | + silentTranslationWarn: false, // true - warning off | |
19 | + silentFallbackWarn: true, | |
20 | +}; | |
21 | + | |
22 | +let i18n: I18n; | |
23 | + | |
24 | +// setup i18n instance with glob | |
25 | +export function setupI18n(app: App) { | |
26 | + i18n = createI18n(localeData) as I18n; | |
27 | + setI18nLanguage(getLocale()); | |
28 | + app.use(i18n); | |
29 | +} | |
30 | + | |
31 | +export function setI18nLanguage(locale: Locale): void { | |
32 | + // @ts-ignore | |
33 | + i18n.global.locale.value = locale; | |
34 | + // i18n.global.setLocaleMessage(locale, messages); | |
35 | +} | ... | ... |
src/store/index.ts
1 | 1 | import type { App } from 'vue'; |
2 | -import { createStore, createLogger, Plugin } from 'vuex'; | |
2 | +import { | |
3 | + createStore, | |
4 | + // createLogger, Plugin | |
5 | +} from 'vuex'; | |
3 | 6 | import { config } from 'vuex-module-decorators'; |
4 | 7 | import { isDevMode } from '/@/utils/env'; |
5 | 8 | |
6 | 9 | config.rawError = true; |
7 | 10 | const isDev = isDevMode(); |
8 | -const plugins: Plugin<any>[] = isDev ? [createLogger()] : []; | |
11 | +// const plugins: Plugin<any>[] = isDev ? [createLogger()] : []; | |
9 | 12 | |
10 | 13 | const store = createStore({ |
11 | 14 | // modules: {}, |
12 | 15 | strict: isDev, |
13 | - plugins, | |
16 | + // plugins, | |
14 | 17 | }); |
15 | 18 | |
16 | 19 | export function setupStore(app: App<Element>) { | ... | ... |
src/types/config.d.ts
1 | 1 | // 左侧菜单, 顶部菜单 |
2 | 2 | import { MenuTypeEnum, MenuModeEnum, TriggerEnum } from '/@/enums/menuEnum'; |
3 | 3 | import { ContentEnum, PermissionModeEnum, ThemeEnum, RouterTransitionEnum } from '/@/enums/appEnum'; |
4 | - | |
4 | +import type { LocaleType } from '/@/locales/types'; | |
5 | 5 | export interface MessageSetting { |
6 | 6 | title: string; |
7 | 7 | // 取消按钮的文字, |
... | ... | @@ -55,6 +55,7 @@ export interface HeaderSetting { |
55 | 55 | showNotice: boolean; |
56 | 56 | } |
57 | 57 | export interface ProjectConfig { |
58 | + locale: LocaleType; | |
58 | 59 | // header背景色 |
59 | 60 | headerBgColor: string; |
60 | 61 | // 左侧菜单背景色 | ... | ... |
src/types/module.d.ts
src/views/sys/login/Login.vue
... | ... | @@ -11,14 +11,14 @@ |
11 | 11 | |
12 | 12 | <a-form class="mx-auto mt-10" :model="formData" :rules="formRules" ref="formRef"> |
13 | 13 | <a-form-item name="account"> |
14 | - <a-input size="large" v-model:value="formData.account" placeholder="Username: vben" /> | |
14 | + <a-input size="large" v-model:value="formData.account" placeholder="username: vben" /> | |
15 | 15 | </a-form-item> |
16 | 16 | <a-form-item name="password"> |
17 | 17 | <a-input-password |
18 | 18 | size="large" |
19 | 19 | visibilityToggle |
20 | 20 | v-model:value="formData.password" |
21 | - placeholder="Password: 123456" | |
21 | + placeholder="password: 123456" | |
22 | 22 | /> |
23 | 23 | </a-form-item> |
24 | 24 | |
... | ... | @@ -28,13 +28,13 @@ |
28 | 28 | <a-row> |
29 | 29 | <a-col :span="12"> |
30 | 30 | <a-form-item> |
31 | - <!-- 未做逻辑,需要自行处理 --> | |
31 | + <!-- No logic, you need to deal with it yourself --> | |
32 | 32 | <a-checkbox v-model:checked="autoLogin" size="small">自动登录</a-checkbox> |
33 | 33 | </a-form-item> |
34 | 34 | </a-col> |
35 | 35 | <a-col :span="12"> |
36 | 36 | <a-form-item :style="{ 'text-align': 'right' }"> |
37 | - <!-- 未做逻辑,需要自行处理 --> | |
37 | + <!-- No logic, you need to deal with it yourself --> | |
38 | 38 | <a-button type="link" size="small">忘记密码</a-button> |
39 | 39 | </a-form-item> |
40 | 40 | </a-col> |
... | ... | @@ -47,7 +47,7 @@ |
47 | 47 | :block="true" |
48 | 48 | @click="login" |
49 | 49 | :loading="formState.loading" |
50 | - >登录</a-button | |
50 | + >{{ t('system.login.button') }}</a-button | |
51 | 51 | > |
52 | 52 | </a-form-item> |
53 | 53 | </a-form> |
... | ... | @@ -57,20 +57,15 @@ |
57 | 57 | </div> |
58 | 58 | </template> |
59 | 59 | <script lang="ts"> |
60 | - import { | |
61 | - defineComponent, | |
62 | - reactive, | |
63 | - ref, | |
64 | - unref, | |
65 | - toRaw, | |
66 | - // computed | |
67 | - } from 'vue'; | |
60 | + import { defineComponent, reactive, ref, unref, toRaw } from 'vue'; | |
68 | 61 | import { Checkbox } from 'ant-design-vue'; |
69 | 62 | |
70 | 63 | import Button from '/@/components/Button/index.vue'; |
71 | 64 | // import { BasicDragVerify, DragVerifyActionType } from '/@/components/Verify/index'; |
72 | 65 | |
73 | 66 | import { userStore } from '/@/store/modules/user'; |
67 | + import { useI18n } from 'vue-i18n'; | |
68 | + | |
74 | 69 | // import { appStore } from '/@/store/modules/app'; |
75 | 70 | import { useMessage } from '/@/hooks/web/useMessage'; |
76 | 71 | import { useSetting } from '/@/hooks/core/useSetting'; |
... | ... | @@ -139,7 +134,7 @@ |
139 | 134 | formState.loading = false; |
140 | 135 | } |
141 | 136 | } |
142 | - | |
137 | + const { t } = useI18n(); | |
143 | 138 | return { |
144 | 139 | formRef, |
145 | 140 | // verifyRef, |
... | ... | @@ -151,6 +146,7 @@ |
151 | 146 | // openLoginVerify: openLoginVerifyRef, |
152 | 147 | title: globSetting && globSetting.title, |
153 | 148 | logo, |
149 | + t, | |
154 | 150 | }; |
155 | 151 | }, |
156 | 152 | }); | ... | ... |
vite.config.ts
... | ... | @@ -4,8 +4,9 @@ import { resolve } from 'path'; |
4 | 4 | |
5 | 5 | import { modifyVars } from './build/config/lessModifyVars'; |
6 | 6 | import { createProxy } from './build/vite/proxy'; |
7 | -import globbyTransform from './build/vite/plugin/context/transform'; | |
8 | -import dynamicImportTransform from './build/vite/plugin/dynamicImport/index'; | |
7 | + | |
8 | +import globbyTransform from './build/vite/plugin/transform/globby'; | |
9 | +import dynamicImportTransform from './build/vite/plugin/transform/dynamic-import'; | |
9 | 10 | |
10 | 11 | import { isDevFn, loadEnv } from './build/utils'; |
11 | 12 | |
... | ... | @@ -111,6 +112,11 @@ const viteConfig: UserConfig = { |
111 | 112 | }, |
112 | 113 | define: { |
113 | 114 | __VERSION__: pkg.version, |
115 | + // use vue-i18-next | |
116 | + // Suppress warning | |
117 | + __VUE_I18N_LEGACY_API__: false, | |
118 | + __VUE_I18N_FULL_INSTALL__: false, | |
119 | + __INTLIFY_PROD_DEVTOOLS__: false, | |
114 | 120 | }, |
115 | 121 | cssPreprocessOptions: { |
116 | 122 | less: { |
... | ... | @@ -135,5 +141,13 @@ const viteConfig: UserConfig = { |
135 | 141 | |
136 | 142 | export default { |
137 | 143 | ...viteConfig, |
138 | - transforms: [globbyTransform(viteConfig), dynamicImportTransform(viteEnv)], | |
144 | + transforms: [ | |
145 | + globbyTransform({ | |
146 | + resolvers: viteConfig.resolvers, | |
147 | + root: viteConfig.root, | |
148 | + alias: viteConfig.alias, | |
149 | + includes: [resolve('src/router'), resolve('src/locales')], | |
150 | + }), | |
151 | + dynamicImportTransform(viteEnv), | |
152 | + ], | |
139 | 153 | } as UserConfig; | ... | ... |
yarn.lock
... | ... | @@ -1323,6 +1323,11 @@ |
1323 | 1323 | dependencies: |
1324 | 1324 | "@types/node" "*" |
1325 | 1325 | |
1326 | +"@types/globrex@^0.1.0": | |
1327 | + version "0.1.0" | |
1328 | + resolved "https://registry.npmjs.org/@types/globrex/-/globrex-0.1.0.tgz#baf4ac8e36947017612c01fde7c7b641dc0b6c89" | |
1329 | + integrity sha512-aBkxDgp/UbnluE+CIT3V3PoNewwOlLCzXSF3ipD86Slv8xVjwxrDAfSGbsfGgMzPo/fEMPXc+gNUJbtiugwfoA== | |
1330 | + | |
1326 | 1331 | "@types/http-assert@*": |
1327 | 1332 | version "1.5.1" |
1328 | 1333 | resolved "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.1.tgz#d775e93630c2469c2f980fc27e3143240335db3b" |
... | ... | @@ -1732,18 +1737,18 @@ |
1732 | 1737 | vscode-languageserver-textdocument "^1.0.1" |
1733 | 1738 | vscode-uri "^2.1.2" |
1734 | 1739 | |
1735 | -"@vueuse/core@4.0.0-beta.41": | |
1736 | - version "4.0.0-beta.41" | |
1737 | - resolved "https://registry.npmjs.org/@vueuse/core/-/core-4.0.0-beta.41.tgz#0058aed5ade75ae2866283498009ad5172cbae84" | |
1738 | - integrity sha512-CgUih65PzYScorm1S4F93e6XXm+qxA8GrRLOSB1kXaqtP6vXedwkBxKkNEYNACx4reL4VEHqM/BrM6FajXkQUg== | |
1740 | +"@vueuse/core@4.0.0-rc.3": | |
1741 | + version "4.0.0-rc.3" | |
1742 | + resolved "https://registry.npmjs.org/@vueuse/core/-/core-4.0.0-rc.3.tgz#5381ca657e10df596cd7027fc5c96b2d4b3a090c" | |
1743 | + integrity sha512-dQ/FZgo0z7kBFOvDWxuzaUrmuO8X1AlQk17e3PU1TVtG2Uu+mCvjPNbuvI2fjhTjl5rzPJawwoU2WZFj+nlFvw== | |
1739 | 1744 | dependencies: |
1740 | - "@vueuse/shared" "4.0.0-beta.41" | |
1745 | + "@vueuse/shared" "4.0.0-rc.3" | |
1741 | 1746 | vue-demi latest |
1742 | 1747 | |
1743 | -"@vueuse/shared@4.0.0-beta.41": | |
1744 | - version "4.0.0-beta.41" | |
1745 | - resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-4.0.0-beta.41.tgz#395782ea2e580f1fc9488d25c89bd09f70170b25" | |
1746 | - integrity sha512-dqnuEPPC3OUJ6L6rhMiOCuPWIR698DtdwOydwCZBISsG2V6gZ2QFND6xtRwLib6/lhUMYVYPwIz3hPjlx7BIzw== | |
1748 | +"@vueuse/shared@4.0.0-rc.3": | |
1749 | + version "4.0.0-rc.3" | |
1750 | + resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-4.0.0-rc.3.tgz#42fb56fed3779f3b8a17a82c16a364bad20d01b7" | |
1751 | + integrity sha512-VY0x/XxpeTMHp/0FDiv1cgUUxkJGQl7liiM2AjR/J7+Ys/2Y2dijD5cAKViq9FGUPQQsOcLptMvMvUsDMoN4DA== | |
1747 | 1752 | dependencies: |
1748 | 1753 | vue-demi latest |
1749 | 1754 | |
... | ... | @@ -3222,6 +3227,13 @@ dot-prop@^5.1.0: |
3222 | 3227 | dependencies: |
3223 | 3228 | is-obj "^2.0.0" |
3224 | 3229 | |
3230 | +dot-prop@^6.0.0: | |
3231 | + version "6.0.0" | |
3232 | + resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.0.tgz#bd579fd704d970981c4b05de591db648959f2ebb" | |
3233 | + integrity sha512-xCbB8IN3IT+tdgoEPOnJmYTNJDrygGFOmiQEiVa5eAD+JEB1vTgMNhVGRnN5Eex/6amck7cdcrixb1qN9Go+GQ== | |
3234 | + dependencies: | |
3235 | + is-obj "^2.0.0" | |
3236 | + | |
3225 | 3237 | dotenv-expand@^5.1.0: |
3226 | 3238 | version "5.1.0" |
3227 | 3239 | resolved "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" |
... | ... | @@ -4092,6 +4104,11 @@ globjoin@^0.1.4: |
4092 | 4104 | resolved "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43" |
4093 | 4105 | integrity sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM= |
4094 | 4106 | |
4107 | +globrex@^0.1.2: | |
4108 | + version "0.1.2" | |
4109 | + resolved "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098" | |
4110 | + integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg== | |
4111 | + | |
4095 | 4112 | gonzales-pe@^4.3.0: |
4096 | 4113 | version "4.3.0" |
4097 | 4114 | resolved "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz#fe9dec5f3c557eead09ff868c65826be54d067b3" |
... | ... | @@ -8167,10 +8184,10 @@ vue-eslint-parser@^7.1.1: |
8167 | 8184 | esquery "^1.0.1" |
8168 | 8185 | lodash "^4.17.15" |
8169 | 8186 | |
8170 | -vue-i18n@^9.0.0-beta.7: | |
8171 | - version "9.0.0-beta.7" | |
8172 | - resolved "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.0.0-beta.7.tgz#f6fad5b4be218018aab4797f80dd2a95ee5236f9" | |
8173 | - integrity sha512-hFl0XnV91P/4UyWvHYvdYxuk3GRnKIW9zXAm6hrUU4mOIwpqchi7jVQva2TJLr52Mpsu4zYXmzL1h5pgrKmCfQ== | |
8187 | +vue-i18n@^9.0.0-beta.8: | |
8188 | + version "9.0.0-beta.8" | |
8189 | + resolved "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.0.0-beta.8.tgz#92282d5b5e0e6f15cc04943ce11bf49db610468f" | |
8190 | + integrity sha512-tViSN96jLi0AKvAVi4twcYYN5Ld++SqN1/140ua+YWm/iRbO2M0rAcsZ7e6/4LTm6Pd1ldSwWihSuv2bSQmlnw== | |
8174 | 8191 | dependencies: |
8175 | 8192 | source-map "0.6.1" |
8176 | 8193 | ... | ... |