初次用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 中生成语言包
  • 可利用通义千问对键进行驼峰命名,对值进行翻译
  • 话术:将以上的键做驼峰命名,值做英文翻译

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/789810.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

.Net C#执行JavaScript脚本

文章目录 前言一、安装二、执行 JavaScript 脚本三、与脚本交互四、JS 调用 C# 方法五、多线程使用总结 前言 ClearScript 是一个 .NET 平台下的开源库,用于在 C# 和其他 .NET 语言中执行脚本代码。它提供了一种方便和安全的方法来将脚本与应用程序集成,…

使用Go编写的持续下行测速脚本,快速消耗流量且不伤硬盘

介绍 使用go语言编写的持续下行测速脚本,可用于任意平台使用,通过指定URL清单文本文件自动遍历测速,支持多线程,支持多平台 特性 轻量级,无依赖采用内存进行缓存数据,不占用磁盘(如果内存较小请使用gcd项目),最大程度减少磁盘IO,保护硬盘寿命可自定义最大下载文件…

Hum Brain Mapp:青春期早期的灰质流失可以用白质生长来解释吗?

摘要 关于大脑发育的一个基本谜题是,为什么儿童进入青春期时,灰质(GM)体积明显减少,而白质(WM)体积明显增加。一种流行的理论认为,由于被修剪的突触太小而不足以影响脑灰质体积,因此大脑总体积保持稳定,而…

Puppeteer 是什么以及如何在网络抓取中使用它 | 2024 完整指南

网页抓取已经成为任何处理网页数据提取的人都必须掌握的一项重要技能。无论你是开发者、数据科学家还是希望从网站收集信息的爱好者,Puppeteer都是你可以使用的最强大工具之一。本完整指南将深入探讨什么是Puppeteer以及如何有效地在网页抓取中使用它。 Puppeteer简…

wifi模组Ai-M62-32S的IO映射和UDP透传测试

wifi模组Ai-M62-32S的IO映射和UDP透传测试 基本IO 映射配网示例开启UDP透传示例复位AT查询wifi是否在线配置DHCP静态IP连接wifi连接UDP开启透传 基本IO 映射 对于wifi模组Ai-62-32S来说其模组 IO 引脚(从模组左上角逆时针排序,引脚序号从 1 开始&#x…

LeetCode 2 两数相加

题目 给你两个 非空 的链表,表示两个非负的整数 它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字 请你将两个数相加,并以相同形式返回一个表示和的链表 你可以假设除了数字 0 之外,这两个数都不会以…

小程序需要进行软件测试吗?小程序测试有哪些测试内容?

在如今移动互联网快速发展的时代,小程序已成为人们生活中不可或缺的一部分。然而,面对日益增长的小程序数量和用户需求,小程序的稳定性和质量问题日益突显。因此,对小程序进行软件测试显得尤为重要。 近期的一项调查显示&#xf…

鸿蒙语言基础类库:【@ohos.util (util工具函数)】

util工具函数 说明: 本模块首批接口从API version 7开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。开发前请熟悉鸿蒙开发指导文档:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 该模块…

3d已经做好的模型怎么改单位?---模大狮模型网

在展览3D模型设计行业中,经常会遇到需要将已完成的模型进行单位转换的需求。这可能涉及从一种度量单位转换为另一种,例如从英制单位转换为公制单位,或者根据特定的展览场地要求进行尺寸调整。本文将探讨如何有效地修改已完成的3D模型的单位&a…

js实现图片放大镜功能,简单明了

写购物项目的时候&#xff0c;需要放大图片&#xff0c;这里用js写了一个方法&#xff0c;鼠标悬浮的时候放大当前图片 这个是class写法 <!--* Descripttion: * Author: 苍狼一啸八荒惊* LastEditTime: 2024-07-10 09:41:34* LastEditors: 夜空苍狼啸 --><!DOCTYPE …

【CSS in Depth 2 精译】2.4 视口的相对单位

当前内容所在位置 第一章 层叠、优先级与继承第二章 相对单位 2.1 相对单位的威力2.2 em 与 rem2.3 告别像素思维2.4 视口的相对单位 ✔️2.5 无单位的数值与行高2.6 自定义属性2.7 本章小结 2.4 视口的相对单位 前面介绍过的 em 和 rem 是相对于 font-size 定义的&#xff0…

【Pikachu靶场】安装部署通关详解超详细!!!(持续更新)

安装部署 Pikachu靶场&#xff0c;是一个带有漏洞的Web应用系统&#xff0c;在这里包含了常见的web安全漏洞。使用世界上最好的语言PHP进行开发-_-&#xff0c;数据库使用的是mysql&#xff0c;因此运行Pikachu你需要提前安装好"PHPMYSQL中间件&#xff08;如apache,ngin…

【HTML入门】第八课 - 链接的学习(二)

我们上一节学习了&#xff0c;链接的基本知识&#xff0c;有锚点&#xff0c;还有鼠标上移的title属性的作用&#xff0c;这一节&#xff0c;我们继续说链接的知识点。 目录 1 跳转本项目的网页 1.1 修改html文件名 1.2 新建index1.html文件 1.3 修改index1.html文件 1.4…

python7:装饰器

目录 1.调用外部程序os.system-阻塞式调用subprocess-python中的模块 2.装饰器前戏作用域&#xff08;1&#xff09;全局和局部-就近原则&#xff08;2&#xff09;嵌套作用域&#xff08;3&#xff09;内置作用域、变量 高阶函数&#xff1a;函数是最高级的对象&#xff08;1&…

几种不同的方式禁止IP访问网站(PHP、Nginx、Apache设置方法)

1、PHP禁止IP和IP段访问 <?//禁止某个IP$banned_ip array ("127.0.0.1",//"119.6.20.66","192.168.1.4");if ( in_array( getenv("REMOTE_ADDR"), $banned_ip ) ){die ("您的IP禁止访问&#xff01;");}//禁止某个IP段…

【Linux操作系统-测试】第三节.Linux 系统、网络信息、用户权限命令总结

文章目录 前言一、Linux 系统相关信息命令 1.1 df 命令--查看磁盘剩余 1.2 ps 命令--查看进程 1.3 top 命令--显示进程运行状态 1.4 kill 命令说明 -- 杀死进程二、Linux 网络信息命令 2.1 ping 命令--检查网络是否连通 2.1 ifconfig--显示网络设…

传知代码-图神经网络长对话理解(论文复现)

代码以及视频讲解 本文所涉及所有资源均在传知代码平台可获取 概述 情感识别是人类对话理解的关键任务。随着多模态数据的概念&#xff0c;如语言、声音和面部表情&#xff0c;任务变得更加具有挑战性。作为典型解决方案&#xff0c;利用全局和局部上下文信息来预测对话中每…

数据库-ubuntu环境下安装配置mysql

文章目录 什么是数据库&#xff1f;一、ubuntu环境下安装mysql二、配置mysql配置文件1.先登上root账号2.配置文件的修改 mysql和mysqld数据库的基础操作登录mysql创建数据库显示当前数据库使用数据库创建表插入students表数据打印students表数据select * from students; ![在这…

响应式布局下关于gird栅格布局的一些构思

1、传列数&#xff0c;根据列数计算元素容器宽度 好处是子元素可以写百分比宽度&#xff0c;不用固定某一种宽度&#xff0c;反正知道列数通过计算间距就能得到外层容器的宽度。 举个简单的例子&#xff1a; &#xff08;ps:以下用例皆在html中去模拟&#xff0c;就不另外起r…

零基础STM32单片机编程入门(十二) HC-SR04超声波模块测距实战含源码

文章目录 一.概要二.HC-SR04主要参数1.模块引脚定义2.模块电气参数3.模块通讯时序4.模块原理图 三.STM32单片机超声波模块测距实验四.CubeMX工程源代码下载五.小结 一.概要 HC-SR04超声波模块常用于机器人避障、物体测距、液位检测、公共安防、停车场检测等场所。HC-SR04超声波…