需求: 最近有几个项目需要配置多语言 但是项目开发过程中是按设计图写的英文 而且感觉开发中每次碰到文字都要配置一下 感觉特别麻烦 所以放到最后来做
实现思路:用正则将页面中的文字都匹配出来 整理到配置文件 然后使用node脚本 将页面中符合的文字替换成多语言的格式
代码:
1.获取页面中的文字内容 页面加载后将文字打印出来(本来想直接正则匹配出来 发现不是那么好做 没想出来更好的方法)
export default function getContent() {
const obj:any = {}
// 我的根结点是root
const root = document.getElementById("root")
// for(let i=0,len=root.childNodes.length;i<len;i++){
// console.log(root.childNodes[i].nodeType)
// }
getNodesText(root)
console.log(obj)
// 遍历root下边的子节点 匹配出文字节点
function getNodesText(ele: any) {
if(!ele) return
if(ele.nodeType === Node.TEXT_NODE){
const str = ele.data
const reg = /\s/g
const matchRes = str.match(reg)
// 匹配中文 中文标点 英文 英文标点
const areg = /^[a-zA-Z\u4e00-\u9fa5\x21-\x2f\x3a-\x40\x5b-\x60\x7B-\x7F\u3002|\uff1f|\uff01|\uff0c|\u3001|\uff1b|\uff1a|\u201c|\u201d|\u2018|\u2019|\uff08|\uff09|\u300a|\u300b|\u3008|\u3009|\u3010|\u3011|\u300e|\u300f|\u300c|\u300d|\ufe43|\ufe44|\u3014|\u3015|\u2026|\u2014|\uff5e|\ufe4f|\uffe5]/
if(areg.test(str)){
// 对key值的处理
if(matchRes && matchRes.length>=3){
let first = str.indexOf(" ")
let second = str.indexOf(" ",first+1)
let third = str.indexOf(" ",second+1)
const key = str.slice(0,third)
obj[key] = str
}else {
obj[str] = str
}
}
}
for(let i=0,len=ele.childNodes.length;i<len;i++){
getNodesText(ele.childNodes[i])
}
}
}
2.使用node 遍历相应目录下的文件 进行文字替换
// @ts-ignore
const fs = require('fs');
const path = 'src/pages/'
let files = fs.readdirSync(path);
// console.log(files)
// 我这里是react项目 使用的tsx
function isTsx(filename:string):boolean {
return ["tsx"].includes(filename.slice(-3))
}
resetFileContent(path,files)
function resetFileContent(path:string,files:any){
for (let i=0,len=files.length;i<len;i++){
const data = files[i]
if(fs.statSync(path+data).isDirectory()){
resetFileContent(path+data+'/',fs.readdirSync(path+data+'/'))
}else if(isTsx(data)){
// console.log(path+data)
const enJson = fs.readFileSync("public/locales/en.json").toString()
// console.log(enJson)
const enData = JSON.parse(enJson)
const enKeys = Object.keys(enData)
let content = fs.readFileSync(path+data).toString()
for(let i=0,len=enKeys.length;i<len;i++){
// 正则需要适配多种情况 防止二次替换 以及某些格式替换不到的
content = content.replace(new RegExp(`(\n|\r|\r\n|↵|\s{2,}|>|\s>)(${enData[enKeys[i]]})(\n|\r|\r\n|↵|\s{2,}|<|\s<)`,"g"),`$1{t("${enKeys[i]}")}$3`)
}
// console.log(content)
fs.writeFileSync(path+data,content)
console.log(path+data)
}
}
}
console.log(`执行language命令完成✅`)