初次用bable遍历vue项目下的中文
// vite-plugin-babel-transform.js
const parser = require('@babel/parser')
const traverse = require('@babel/traverse').default
// const types = require('@babel/types')
// const generate = require('@babel/generator').default
const fs = require('fs-extra')
const path = require('path')
let textArr = []
let jsonData = {}
let repeatList = []
// 判断文件是否存在
if (!fs.existsSync('./src/lang/zh.json')) {
fs.createFileSync('./src/lang/zh.json')
} else {
fs.outputJSONSync('./src/lang/zh.json', jsonData, {
spaces: 2
})
}
export default function vitePluginBabelTransform() {
return {
name: 'vite-plugin-babel-transform',
async transform(code, id) {
if (
!id.endsWith('.js') &&
!id.endsWith('.ts') &&
!id.endsWith('.json') &&
!id.endsWith('.vue')
)
return null // 只处理该后缀文件
// console.log('id', id)
const ast = parser.parse(code, {
sourceType: 'module',
plugins: ['jsx', 'decorators-legacy'] // 如果你的代码中有 JSX 语法,也需要添加这个插件
// 'decorators' 'decorators-legacy'
})
/**
* 分类-js文件 json文件 vue目录分类 public-公共资源,中文出现过两次以上的
*/
let prefix = ''
if (id.endsWith('.js') || id.endsWith('.ts')) {
prefix = 'js'
} else if (id.endsWith('.json')) {
prefix = 'json'
} else if (id.endsWith('.vue')) {
if (
id.indexOf('src/views/') > -1 &&
id.split('src/views/')[1].split('/').length > 1
) {
prefix = id.split('src/views/')[1].split('/')[0]
} else if (id.indexOf('src/components/') > -1) {
prefix = 'components'
} else if (id.indexOf('src/layout/') > -1) {
prefix = 'layout'
} else {
prefix = path.parse(id).name
}
}
// console.log('prefix', prefix)
textArr = []
traverse(ast, pluginReplaceConsoleLog(prefix))
writeTextFile(prefix)
// 生成新的代码
// const output = generate(ast)
// return {
// code: output.code,
// map: output.map // 如果需要source map
// }
return code
}
}
}
function pluginReplaceConsoleLog(prefix) {
return {
FunctionDeclaration(path) {
// console.log('FunctionDeclaration', path.node.id.name)
},
StringLiteral(path) {
// console.log('StringLiteral', path.node.value)
// 获取父节点,检查它是否为一个调用表达式
const parent = path.parent
if (
parent.type === 'CallExpression' &&
parent.callee.type === 'Identifier' &&
parent.callee.name === 'alert'
) {
// 如果字符串在 alert 中,则不做任何操作
return
}
if (
parent.type === 'CallExpression' &&
parent.callee.type === 'MemberExpression' &&
parent.callee.object.name === 'console'
) {
// 如果字符串在 console 中,则不做任何操作
return
}
if (!path.node.value.includes('iotchannel-console-4G')) {
let match = path.node.value.match(/(\S*[\u4e00-\u9fa5]+\S*)/g)
if (match) {
textArr = textArr.concat(match)
}
}
},
IfStatement(path) {
// console.log('IfStatement', path.node)
},
CallExpression(path) {
// console.log('CallExpression', path.node)
}
}
}
function getAllValues(obj, prefix) {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
if (key !== prefix) {
let value = obj[key]
if (
typeof value === 'object' &&
value !== null &&
!Array.isArray(value)
) {
// 如果值是对象(但不是数组),则递归调用
getAllValues(value, prefix)
} else {
// 如果值既不是对象也不是数组,直接添加值
// 添加重复的数据
if (textArr.includes(value)) {
delete obj[key]
repeatList.push(value)
}
}
}
}
}
}
function writeTextFile(prefix) {
// 读取原数据
jsonData = fs.readJSONSync('./src/lang/zh.json')
// 获取重复的数据放到public下
getAllValues(jsonData, prefix)
if (jsonData['public']) {
repeatList = repeatList.concat(Object.values(jsonData['public']))
}
// 重复数据去重并添加到对象中
jsonData['public'] = [...new Set(repeatList)]
.sort()
.reduce((prev, cur, index, arr) => {
prev[index] = cur
return prev
}, {})
// 将新的数据添加到对象中
textArr = textArr.filter(item => {
return !repeatList.includes(item)
})
if (jsonData[prefix]) {
textArr = textArr.concat(Object.values(jsonData[prefix]))
}
// 去重
textArr = [...new Set(textArr)]
// 排序
let data = textArr.sort().reduce((prev, cur, index, arr) => {
prev[index] = cur
return prev
}, {})
jsonData[prefix] = data
jsonData = Object.keys(jsonData)
.sort()
.reduce((prev, cur, index, arr) => {
prev[cur] = jsonData[cur]
return prev
}, {})
// console.log('textArr', textArr)
fs.outputJSONSync('./src/lang/zh.json', jsonData, {
spaces: 2
})
}