diff --git a/src/pages/i18n.js b/src/pages/i18n.js new file mode 100644 index 000000000..c2555a230 --- /dev/null +++ b/src/pages/i18n.js @@ -0,0 +1,52 @@ +const { resolve } = require('path'); +const fs = require('fs'); +const { extractI18NReport, readVueFiles, extractI18NItemsFromVueFiles, readLanguageFiles } = require('vue-i18n-extract'); +const Dot = require('dot-object'); + +const dot = new Dot('.'); +const config = { + filePath: './src/**/*.?(js|vue|ts|tsx|jsx|html)', + i18nPath: './src/language/**/*.?(json)' +} + +const vueFiles = readVueFiles(resolve(process.cwd(), config.filePath)); +const I18NItems = extractI18NItemsFromVueFiles(vueFiles); + +const languageFiles = readLanguageFiles(resolve(process.cwd(), config.i18nPath)); +const I18NLanguage = languageFiles.reduce((pre, item) => { + const content = JSON.parse(item.content) + const flatContent = dot.dot(content); + // const lang = item.fileName.replace(/^.*[\\\/]/, '') + pre[item.fileName] = Object.keys(flatContent).map(key => ({ + file: item.fileName, + path: key + })) + return pre +}, {}); + +const report = extractI18NReport(I18NItems, I18NLanguage); + +// 添加未翻译文案 +languageFiles.forEach(languageFile => { + const content = JSON.parse(languageFile.content); + report.missingKeys.forEach(item => { + if (item.language !== languageFile.fileName) return + + const defaultValue = languageFile.fileName.indexOf('zh') > -1 ? item.path : '' + dot.str(item.path, defaultValue, content) + }) + languageFile.content = JSON.stringify(content) // 保留结果 + + fs.writeFileSync(languageFile.path, JSON.stringify(content, null, 2)) +}); +// 删除未使用文案 +languageFiles.forEach(languageFile => { + const content = JSON.parse(languageFile.content); + report.unusedKeys.forEach(item => { + if (item.language !== languageFile.fileName) return + + dot.delete(item.path, content) + }) + languageFile.content = JSON.stringify(content) // 保留结果 + fs.writeFileSync(languageFile.path, JSON.stringify(content, null, 2)) +}); \ No newline at end of file diff --git a/src/pages/package.json b/src/pages/package.json index b858b2899..275b7e830 100644 --- a/src/pages/package.json +++ b/src/pages/package.json @@ -8,7 +8,8 @@ "server": "node ./paas-server/index.js", "lint": "eslint --ext .js,.vue,.ts ./src", "lint:fix": "eslint --fix --ext .js,.vue,.ts ./src", - "lint:style": "stylelint \"./**/*.{css,less,vue,html}\" --fix" + "lint:style": "stylelint \"./**/*.{css,less,vue,html}\" --fix", + "i18n": "node ./i18n.js" }, "keywords": [ "bk-ci", @@ -33,6 +34,7 @@ "cookie": "^0.5.0", "cookie-parser": "^1.4.5", "dayjs": "^1.11.2", + "dot-object": "^2.1.5", "express": "^4.18.2", "express-art-template": "^1.0.1", "intl-tel-input": "^18.2.1", @@ -50,6 +52,7 @@ "vite-plugin-monaco-editor": "^1.1.0", "vue": "^3.2.41", "vue-i18n": "^9.9.0", + "vue-i18n-extract": "^2.0.7", "vue-router": "^4.1.6" }, "devDependencies": { diff --git a/src/pages/src/components/SyncRecords.vue b/src/pages/src/components/SyncRecords.vue index e10520182..3b09ab35c 100644 --- a/src/pages/src/components/SyncRecords.vue +++ b/src/pages/src/components/SyncRecords.vue @@ -15,7 +15,7 @@ diff --git a/src/pages/src/components/layouts/LabelContent.vue b/src/pages/src/components/layouts/LabelContent.vue index 9f738c516..54f3d2ae8 100644 --- a/src/pages/src/components/layouts/LabelContent.vue +++ b/src/pages/src/components/layouts/LabelContent.vue @@ -1,6 +1,8 @@