为什么我要重新写一个国际化提取脚本 Code-Extractor

文章首发于飞书知识库:极简化前端 - 为什么我要重新写一个国际化提取脚本 Code-Extractor

最近入职以后的第一份内容是完成项目的国际化工作,为此写了一个 Code-Extractor 工具。

仓库地址是:github.com/Wetoria/Cod...

说明:

最新代码我并没有提交上去,因为还有些内容正在调整当中。

未来什么时候有心情把代码优化完了,我再推上去。

这篇文章算是用来记录一些,在这个过程中思考及实现思路。

为什么我要重新写一个提取脚本

原因:我不信任任何一个现有的库脚本

我测试过几个包括库,它们的提取逻辑,目测只是简单的搜索项目中的中文并进行提取。

无论是哪个库,在以下几个点上,或多或少的存在我认为不够好的地方。

  1. 哪些文件里包含了中文?

  2. 提取出来的内容是哪个文件里的、哪部分内容,提取结果是否正确?

  3. 格式化后的结果是什么?是否正确?

  4. 提取出来的内容,如何方便的查找到对应的翻译结果?

并且有些地方,我觉得可以有更好的做法,并且我也实现了部分。

注:

当我编写这篇文章的时候,离我开发这个脚本,已经过去了几周时间。

许多细节我不打算再重新测试并确认,仅凭印象编写的该文章。

哪些文件里包含了中文?

在这个问题上,我在使用 kiwi-cli 的时候,有显示在哪个文件中提取出来了中文,但是仅仅显示了文件路径。

而我在这一点上,增加了 的提取,然后利用 VS Code 的路径跳转功能,如果你是在 VSC 的终端里执行脚本,那么你可以利用 opt + click 跳转到精确位置。

你可以按照以下步骤进行测试:

  1. 用 VSC 随便打开一个项目,并复制一个文件的路径。
  1. 然后在路径后面拼上 :行号:列号
  2. 在 VSC 的终端里输入 echo [上一步的路径],你就可以用 opt + click 跳转了。

这算是一个国际化提取脚本的基操,我只是加了一个小优化。

接着看提取部分。

提取出来的内容是哪个文件里的、哪部分内容,提取结果是否正确?

这里直接展示一下结果吧。

先是对一些注释内容进行过滤,然后利用终端输出的格式化语法,对命中的内容进行高亮,并显示对应的文件位置信息。

如果出现了提取错误的地方,可以对提取规则进行调整,或者是快速跳转到文件的位置对文件内容进行调整。两者皆可。

之所以这样做的原因是。

项目已经开发过一段时间了,提取的结果肯定足够多。

利用 kiwi 这样的工具,虽然也能在提取完成以后,利用 git diff 的对比,对提取结果进行确认,但是整个确认工作还是稍显麻烦的。

PS:写的时候,想起来终端里用 diff 直接查看的话,可以类似图中这样的展示效果。

格式化后的结果是什么?是否正确?

先不说结果是否正确,光是一个个确认提取的地方,工作量已经足够多了。

提取出来的内容,如何方便的查找到对应的翻译结果?

我测试的几个库,提取过程都类似,先是 init 初始化配置,然后进行提取得到配置文件。

并且有些类库增加了 VS Code 插件的支持,但是在使用上给我一种很蠢的感觉。没错,就是蠢。

比如,提示文件中是否有未提取的中文。

那我是不是要打开每个文件确认才能知道?

比如,kiwi 的提取后的key,采用 文件路径 + 翻译结果 的形式,也就是 ppath.spath.file.key

并且说是提供了搜索功能,快速查看翻译结果,但是光复制粘贴和输入这段 key,就已经足够麻烦了。

这里我在调研飞书的做法时,想起来下划线是个好东西,所以最后我用的是 path_filename_中文内容 的方式,作为配置文件的 key。

好处是,中文直接能知道这里是什么意思。

如果需要确认翻译结果,双击 key,即可选中复制,然后打开对应语言的配置文件,进行查找即可。

当然,像 kiwi 等插件的做法,增加一个插件读取并展示也可以。只不过没有接触过 VSC 的插件开发,所以暂不考虑。

其他几个我考虑的地方

因为我完成这个 React 项目的国际化提取工作以后,可能还需要完成另一个 Vue 项目的国际化。

所以我这一点上我也需要留意。

然后这些提取脚本,基本上都是接入了第三方库,这一点上也让我特别难受。

我目前除了对接百度翻译需要用到 MD5 加密,引入了 crypto,其余的只用到了 js 和 nodejs 环境。

因为本质上就是一个文本提取并替换的功能,为此顺便把正则半通关了一遍。

几个知识点

key 需要文件路径 + key 的格式

虽然绝大多数时候,使用中文作为 key 就已经足够,但是有些页面上,虽然中文内容相同,但是翻译后的结果需要调整。

比如"周一",有的页面需要显示 Monday,有的页面可能只需要显示 Mon。

终端输出彩色字

\x1b[色号m 就可以在输出的时候带颜色了。

VS Code 路径跳转

前面提过了。opt + click 进行,前提是路径规则对了,并且是在 VSC 的终端里。

系统自带终端也有办法,只不过不能用这个快捷键。

文件读写

基本的按行读写文件,然后进行处理,最后整个文件清空再写入即可。

正则

我是按正则进行匹配的,而不是像其他库一样,用 Babel 转 AST 然后再处理,我觉得没必要。

哦对了,学正则的时候,看了菜鸟的解释,我只想说,说的真垃圾,真不容易懂。

JS 中,方法的 name

为了让我开发起来的时候更方便,写了个链式调用的方法。

为了指示正在运行的方法,我在上面的方法里加了 func.name 的输出。

这里就有意思了。

如果你是用 const func = () => {} 声明的方法,那么 func 就是 name

但是有些方法,有很多相同的逻辑,所以我做了包装,比如像下面这样:

javascript 复制代码
function wrapper(fn) {
    return (...args) => {
        // do sth like console.log
        const result = fn(...args)
        // record result
        return result
    }
}

这样包装了以后,返回的是一个箭头函数,它不带 name

前面的 func.name 输出的时候,值是 undefined

为了解决这个问题,我创建了下面这样的方法。

javascript 复制代码
function getNamedFunction(key, fn = () => {}) {
  const coloredKey = `${key}`
  const obj = {
    [coloredKey]: (...args) => {
      return fn(...args)
    }
  }
  return obj[coloredKey]
}

利用上面的方法,我可以给方法配置一个名称,比如:

输入的时候,会得到这样的结果:

任意增加"中间件"

在某个过程前后想插入方法的时候,直接写个方法,然后再进行处理就好。

比如下图中的方法列表,删除哪个方法,那就不会执行相应的逻辑。


差不多就这些吧。

一进来就搞这个国际化,我是觉得挺好玩的。

正则半通关、玩了终端"高亮"、文件读写替换等等。

相关推荐
Jiaberrr2 分钟前
Vite环境下uniapp Vue 3项目添加和使用环境变量的完整指南
前端·javascript·vue.js·uni-app
Marry1.011 分钟前
uniapp背景图用本地图片
前端·uni-app
夏河始溢16 分钟前
一七八、Node.js PM2使用介绍
前端·javascript·node.js·pm2
记忆深处的声音17 分钟前
vue2 + Element-ui 二次封装 Table 组件,打造通用业务表格
前端·vue.js·代码规范
陈随易18 分钟前
兔小巢收费引发的论坛调研Node和Deno有感
前端·后端·程序员
熊的猫32 分钟前
webpack 核心模块 — loader & plugins
前端·javascript·chrome·webpack·前端框架·node.js·ecmascript
速盾cdn39 分钟前
速盾:vue的cdn是干嘛的?
服务器·前端·网络
四喜花露水1 小时前
Vue 自定义icon组件封装SVG图标
前端·javascript·vue.js
前端Hardy1 小时前
HTML&CSS: 实现可爱的冰墩墩
前端·javascript·css·html·css3
web Rookie2 小时前
JS类型检测大全:从零基础到高级应用
开发语言·前端·javascript