我的项目地址 https://github.com/goblin-pitcher/i18n-collector
老我的项目引入i18n
国际化后,须要对我的项目中所有中文包裹$t('中文')
办法,对象不同,包裹的办法也有差别:
- 在
vue
的template
中,间接对中文包裹$t('中文')
- 在
vue
的组件代码中,因为$t
是全局引入,因而需包裹成this.$t('中文')
- 对于纯
js
局部,需 importi18n
模块,并对中文包裹i18n.t('中文')
- 对于带数字的字符串,如【
共计 ${count}条数据
】,需转换为$t('共计 count 条数据', {count: 100})
的构造,转换前的代码在不同中央可能有不一样的示意,比方在vue
的template
中,转换前的词条可能是这样:【共计 {{count}} 条数据
】
问题剖析
面对此类问题,首先想到的天然是将代码转换成 ast
树,对其中的中文字符串进行解决,再转换为代码,但理论会遇到以下几个问题:
- 个别的 parser(如
@bable/parser
)只能解决js
或jsx
文件,无奈解决vue
模板,利用vue-loader
将.vue
文件转换成.js
文件尽管能够配合@bable/parser
进行解析,但转换成.js
文件后的代码,没有相干的转换器将其反过来转换成.vue
代码,这和咱们的需要不符 - 即便有
.vue
文件的 parser(如vue-eslint-parser
),然而没有对应的 traverse 和 generator 工具,不能将解析的ast
反过来转换成代码 - 即便有
.vue
文件的 parser、traverse、generator 配套工具,从新生成的vue
代码格局很大概率无奈满足eslint
校验,须要主动进行格局修改
解决思路
通过对以后问题的剖析,目前面临的问题有两个:
- 须要有
.vue
文件配套的解析、生成工具 - 解决转换后代码的
eslint
格局问题
问题 2 能够通过在生成解决后的 .vue
文件时,运行我的项目中的 eslint --fix
命令实现,若我的项目不校验格局,天然不会装置 eslint
,但若校验格局,则必定会装置eslint
,也就是能够执行eslint --fix
命令。
以后主要矛盾是问题 1,而察看问题 1,.vue
文件中 js
文件有配套的转换工具,主要矛盾集中在 template
上,而目前尽管没有 template
的生成工具,但能够将其视作 html
解析,template
个性的解析作为 html parser
的插件实现。
用法
npm i git+https://github.com/goblin-pitcher/i18n-collector.git -D
---------------------------------
npx i18n-collect
参数
参数名 | 简写 | 阐明 | 默认值 |
---|---|---|---|
dir |
d | 须要进行国际化解决的目录 | ./ |
ignoredir |
i | 须要疏忽的文件或者文件夹 如 -i car.js 会疏忽掉所有以 car.js 结尾的文件 |
无论传不传此参数,都会疏忽掉 i18n 文件夹 |
fix |
f | 运行完 collect 之后是否主动执行 eslint –fix, 默认开启,–fix false 即敞开 eslint 执行 | true |
配置
新建 i18n-collect.config.js
文件可传入具体配置,默认配置如下:
const defConfig = {
// 转换当前目录下的文件
dir: './',
// 疏忽项
ignoredir: [],
// 是否执行 eslint --fix
fix: true,
// 收集中文词条的文件名
output: 'zh-CN.js',
// 文件解决配置
file: {// 模板中包裹中文的函数名,如 $t('中文')
template: {prefix: "$t"},
// 对于纯 js 文件的解决
js: {
// 若有中文词条须要提取,须要先引入 i18n 相干包能力包裹,该配置为增加引入文件的配置
// 默认引入时增加 import {i18n} from '@/utils/i18n.utils'
addImport: {
from: "@/utils/i18n.utils",
data: ["i18n"],
},
// 包裹中文词条的办法,如 i18n.t('中文')
prefix: "i18n.t",
},
// .vue 文件中 script 包裹中文的办法, 如 this.$t('中文')
// 遇到 sparePrefix 配置,即 i18n.t('中文')的字段,也会当作已包裹转换方法的字符串,而不会再用 this.$t 包裹一次
vue: {prefix: "this.$t", sparePrefix: 'i18n.t'}
}
};