i18n业务辅助Node脚本工具
背景
如今前端项目都会涉及国际化功能,项目初始会集成i18n
功能,但在开发初期重点也是以功能为主导,直到项目处于一定的稳步迭代的阶段才会着手进行语言包翻译工作,此时往往要求开发人员提供一份完整的待翻译的数据以及后续每个迭代同步待翻译的数据。而实际开发中语言包大多以json
、js
、 y(a)ml
存放于项目中,而翻译的人员大概率不会是开发人员,这个时候往往提供一份Excel
给相关人员翻译更具普遍性。由此背景而编写用于辅助此过程的Node
脚本便诞生了,主要为了节省开发人员处理国际化数据的时间。
功能说明
此脚本工具用于优化处理国际化文件的过程,其功能主要包括:
- 指定语言国际化
json
数据转Excel
- 已翻译
Excel
生成指定语言国际化json
- 每次迭代新增指定语言的国际化转
Excel
- 每次迭代最新翻译的 `Excel 对比上一版本国际化数据生成最新国际化数据
- 合并对照两种语言
json
文件至Excel
,用于翻译校验
文件结构
├── i18n-tool-script
├── config # 配置
│ ├── config.yaml
├── docs # 文档
│ ├── xxx
├── lib # 脚本源码
│ ├── xxx
├── source # 运行结果输出目录(可自定义配置)
│ ├── xxx
├── utils 工具集合
│ ├── xxx
| index.js # 入口(命令式交互)
| ...
运行
- 安装项目所需依赖,推荐使用
pnpm
或yarn
安装依赖
pnpm install || yarn install
- 在
config/config.yaml
中配置相关功能的数据
- 项目根目录在执行命令
node index.js
或者在lib
目录下直接运行相关脚本(eg:node jsonToExcel.js --auto=true
)
结果
如选择对比json
生成全量的excel
数据
- 对比数据
- 脚本执行输出
生成的Excel
数据,生成module
和key
是为了后续再次方便生成对应的json
数据
代码
脚本工具代码地址i18n-tool-script。
以下为主要公用逻辑代码: 写入至excel
、读取excel
数据、读取json
数据、写入至json
/*
* @Date: 2022-05-22 09:45:38
* @LastEditors: 93eryi@gmail.com
* @LastEditTime: 2023-03-16 22:19:36
* @Description:
*/
const fs = require("fs-extra");
const xlsx = require("node-xlsx").default;
// const json2xls = require("json2xls");
const ExcelJS = require('exceljs')
const colors = require("picocolors");
const utils = require("../utils/index");
const consola = require('consola')
// exit process
const exit = (code=0) => {
process.exit(code)
}
// 判断是否存在文件
const existsFile = (filePath) => {
const allPath = utils.filePathAll(filePath)
if(!filePath || !fs.pathExistsSync(allPath)){
consola.error(colors.red(`[Error] File path ${filePath} does not exist!`));
exit()
return false
}
return true;
}
// 写入excel
function writeToExcel(data, outPath){
if(!outPath){
consola.error(colors.red(`[Error] File path cannot be empty!`));
return;
}
// 处理为完整绝对路径
outPath = utils.filePathAll(outPath)
const fileName = utils.getFileName(outPath)
// ----------- excelJs -----
const startTime = +new Date()
const workbook = new ExcelJS.Workbook()
// 添加工作表
const workSheet = workbook.addWorksheet('Sheet');
const columns = ['module', 'key', 'zh-cn', 'en'];
workSheet.columns = columns.map(col => ({header: col, key: col}))
workSheet.addRows(data, 'n')
const cellBorderStyle = {
style:'thin',
color: {
argb: 'FFC3CBDD'
}
}
workSheet.getColumn(4).eachCell( function(cell){
if(!cell.value){
cell.fill = {
type: 'pattern',
pattern: 'solid',
fgColor: { argb: 'FFFFFF00'}
}
}
cell.font = {
name: 'SimSun',
color: {
argb: 'FF000000'
},
family: 3,
size: 11,
bold: false,
outline: false,
italic: false,
}
cell.border = {
top: cellBorderStyle,
right: cellBorderStyle,
bottom: cellBorderStyle,
left: cellBorderStyle
}
})
workbook.xlsx.writeFile(outPath)
consola.info(colors.blue(`[Info] Data writing to excel execution time: ${+new Date() - startTime}ms.`))
consola.success(colors.green(`[Success] Convert json to excel successfully! Output file name is [${fileName}]`));
// -----------json2xls ------
// TODO json2xls也可生成excel数据 但是暂未找到定义单元格样式操作
// const xls = json2xls(data)
// fs.outputFileSync(outPath, xls, "binary");
// console.log(colors.green(`[Success] Convert json to excel successfully! Output file name is [${fileName}]`));
}
// 获取Json文件数据
function readJsonFile(path){
if(!existsFile(path)) return;
path = utils.filePathAll(path)
return fs.readJsonSync(path)
}
// 获取excel文件数据
function readExcelFile(path, sheetName='Sheet'){
if(!existsFile(path)) return;
path = utils.filePathAll(path)
const workSheetsFromFile = xlsx.parse(`${path}`);
const sheetInfo = workSheetsFromFile.find(item => item.name === sheetName)
if(!sheetInfo){
consola.error(colors.red(`[Error] Not found sheet name is [${sheetName}]!`));
}
const { data } = sheetInfo;
if (!data || !data.length) {
consola.warning(colors.yellow("[Error] Excel is empty!"));
exit()
return;
}
return data
}
// write to json
function writeToJson(path, lang, data) {
if(!path){
consola.error(colors.red(`[Error] File path cannot be empty!`));
return;
}
path = utils.filePathAll(path)
fs.outputFileSync(
path,
JSON.stringify(data),
"utf-8"
);
const fileName = utils.getFileName(path)
consola.success(
colors.green(
`[Success] Convert Excel to language [${lang ? lang : 'unknown'}] version json successfully! Output file name is [${fileName}]`
)
);
}
// excel数据转为目标json数据
function convertExcelToJson(path, lang='zh-cn', langMap){
const data = readExcelFile(path);
if(!data) return
// 英文转化数据结
const resJson = {};
function fmtTargeKeyValue(data) {
const tmpDeepObj = {};
for (let j = 0; j < data.length; j++) {
// 生成对应语言excel的数据对应index
const langValIndex = langMap[lang] + 2;
tmpDeepObj[data[1]] = utils.strToUpperCase(data[langValIndex]);
}
return tmpDeepObj;
}
for (let i = 1; i < data.length; i++) {
const tmpVal = data[i];
const key = tmpVal[0];
if (!resJson[key]) {
resJson[key] = {};
}
const tmpObj = fmtTargeKeyValue(tmpVal);
resJson[key] = { ...resJson[key], ...tmpObj };
}
return resJson;
}
module.exports = {
exit,
writeToExcel,
writeToJson,
readJsonFile,
readExcelFile,
existsFile,
convertExcelToJson
}
转载自:https://juejin.cn/post/7220375870228643898