初次用bable遍历vue项目下的中文

利用 babel 找到 AST 中的中文

// 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
  })
}

在 vite.config.js 中的使用

import vitePluginBabelTransform from './vite-plugin-babel-transform'

//  https://cn.vitejs.dev/config
export default defineConfig(({ mode }) => {
  return {
    plugins: [vitePluginBabelTransform()]
  }
})
  • 最终会在 src/lang/zh.json 中生成语言包
  • 可利用通义千问对键进行驼峰命名,对值进行翻译
  • 话术:将以上的键做驼峰命名,值做英文翻译

在这里插入图片描述

相关推荐

  1. vue对象几种方式

    2024-07-10 21:10:01       51 阅读
  2. js循环

    2024-07-10 21:10:01       49 阅读
  3. 广度和深度

    2024-07-10 21:10:01       37 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-10 21:10:01       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-10 21:10:01       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-10 21:10:01       45 阅读
  4. Python语言-面向对象

    2024-07-10 21:10:01       55 阅读

热门阅读

  1. 每日一题cf

    2024-07-10 21:10:01       19 阅读
  2. Vue3+Element-plus的表单重置

    2024-07-10 21:10:01       16 阅读
  3. #B. 等离子电视

    2024-07-10 21:10:01       22 阅读
  4. 纤程和协程理解

    2024-07-10 21:10:01       18 阅读
  5. 几款常见的数字孪生引擎

    2024-07-10 21:10:01       16 阅读
  6. C++:cv.absdiff函数含义

    2024-07-10 21:10:01       22 阅读
  7. 自动回复机器人:源码搭建与智能化客户服务

    2024-07-10 21:10:01       21 阅读