@tc-i18n/core
@tc-i18n
核心库,提供核心的代码解析能力, 所有代码解析,语料提取能力都由该库提供,插件的 hooks
也由该库提供。核心类包括 Transformer
, ParseHTML
, ParseJS
, ParseVUE
, BaseParse
Transformer类
用于解析和转换单个文件,每次解析新文件时都会创建一个新的 Transformer
实例。
ts
class Transformer extends Utils {
config: Tci18nConfig; // tci18n.config.json配置内容
parseAST?: ParseAST; // AST解析类,提供 ParseHTML,ParseJS,ParseVUE
source: string = ''; // 文件源代码
originSourceType: string = ''; // 文件原始类型
sourceType: string & SOURCE_TYPE = SOURCE_TYPE.JS; // 文件解析类型
scene?: string; // 语料场景值(唯一标识)
hooks: Hooks; // 解析中使用的钩子,可用于插件开发, 详见插件API
primaryLocaleData: Record<string, string> = {}; // 文件解析后,存放提取出来的语料数据
errorData: { // 错误信息
code: string,
sourceType: string,
scene: string,
errorMessage?: string,
error: any,
}[] = [];
pluginTransformMap: Record<string, SOURCE_TYPE> = {}; // 插件开发中,指定特殊的文件类型按照某个基础类型进行解析
plugins: Plugin[] = []; // 需要加载的插件
pluginLoadStatus: 'wait' | 'loading' | 'loaded' = 'wait'; // 插件加载状态
appliedPlugins: (Plugin|string)[] = []; // 已加载并应用的插件
extractOnly: boolean = false; // 是否只提取语料,不替换源代码
async loadPlugins() => void; // 批量加载插件
async loadPlugin(plugin: string | [string, object] | Plugin[]) => Promise<Plugin>; // 加载单个插件
async waitPluginLoaded(): Promise<Plugin[]> => Promise<Plugin>; // 等待插件加载完成
matchSourceType(sourceTypeScope: Plugin['sourceTypeScope']) => boolean; // 判断是否匹配文件类型
applyPlugins() => void; // 执行插件的apply方法
async transformCode(source: string = '', sourceType: string, scene?: string) => Promise<{
code: string,
hasError: boolean,
hasChange: boolean
}> // 执行源代码解析和转换
transformJS(code: string) => string; // 解析js代码
transformWXS(code: string) => string; // 解析小程序wxs代码
transformVUE(code: string) => string; // 解析vue代码
transformHtml(code: string) => string; // 解析html代码
transformTS(code: string) => string; // 解析ts代码
}
ParseHTML类
用于解析HTML代码,默认处理 .html
文件, 可通过插件实现解析 类html文件。
ts
class ParseHTML extends BaseParse {
config: Tci18nConfig; // tci18n.config.json配置内容
sourceType: SOURCE_TYPE; // 文件类型
scene?: string; // 语料场景值(唯一标识)
ignoreLines: number[]; // 需要忽略的行,通过注释获取
parseJS?: ParseJS; // 用于解析HTML中的js代码
vueParser?: VueParser; // 用于解析HTML中的vue代码
miniprogramParser?: MiniprogramParser; // 用于解析HTML中的小程序代码
hooks: Hook; // 解析html中埋入的钩子,可用于插件开发,详见插件API
onlyBody: boolean; // 是否只返回html的body部分
hasChange: boolean; // 代码是否有变动,没有变动则代表代码中没有需要替换的语料,直接返回源代码
isTS; // html中的js代码是否是ts
extractOnly: boolean; // 是否只提取语料,不替换源代码
parseCode(sourceCode: string, scene?: string, prettierOptions: Object = {}) => string; // 解析html代码
getIgnoreLines(sourceCode: string) => number[]; // 获取需要忽略的行(注释)
shouldIgnore(node: parse5.ParseNode) => boolean; // 是否忽略该行
visitorHookSkip(type: string, node: parse5.ParseChildNode, ...args: any[]) => boolean; // 统一处理hooks,判断是否跳过该节点
traverse(node: parse5.ParseChildNode) => void; // 遍历处理html节点
parseAttrs(node: parse5.ParseTagNode) => void; // 解析节点属性
parseInnerText(node: parse5.ParseTextNode) => void; // 解析节点内部文本
parseStrByHogan(str: string) => void; // 解析{{}}语法(模板字符串)
parseAsJs(code: string) => string; // 解析js代码
}
ParseJS类
用于解析javascript代码,默认处理 .js
,.ts
,.jsx
,.tsx
文件。
ts
class ParseJS extends BaseParse {
config: Tci18nConfig; // tci18n.config.json配置内容
sourceType: SOURCE_TYPE;// 文件类型
scene?: string; // 语料场景值(唯一标识)
isTS = false; // 是否是ts文件
ignoreLines: number[] = []; //需要忽略的行,通过注释获取
miniprogramVisitor?: MiniprogramVisitor; // 处理微信小程序wxs相关代码
vueVisitor?: VueVisitor; // 处理js中vue相关代码
needImport = true; // 是否需要自动引入import代码,比如:html部分不需要引入
needI18nObject = true; // 替换函数是否需要i18n对象,比如:vue的html部分只需要$t即可
hasImport = false; // 是否已由import声明
hasChange = false; // 代码是否有变动,没有变动则代表代码中没有需要替换的语料,直接返回源代码
hooks: Hook; // 解析js中埋入的钩子,可用于插件开发,详见插件API
oncePrimaryLocale: string[] = []; // 单次解析提取到的语料
extractOnly: boolean = false; // 是否只提取语料,不替换源代码
generateCode(ast: babel.types.Node, sourceCode?: string) => string; // 将AST转化为代码
parseCode(sourceCode: string, scene?: string, prettierOptions = {}) => string; // 解析js代码
generateImportCode(sourceCode: string) => string; // 插入需要引入依赖的代码
getASTByBabel(code: string, options: babel.TransformOptions) => ParseResult | null // 通过babel获取js的AST
getIgnoreLines(sourceCode: string) => number[]; // 获取需要忽略的行(注释)
shouldIgnore(node: parse5.ParseNode) => boolean; // 是否忽略该行
visitorHookSkip(type: string, node: parse5.NodePath) => boolean; // 统一处理hooks,判断是否跳过该节点
ignoreStringsFromTemplateLiteralAndStringLiteral(path: babel.NodePath) => boolean; // 通过ignoreStrings配置项判断是否忽略
ignoreMethodFromStringLiteral(path: babel.NodePath<babel.types.StringLiteral>) => boolean; // 通过ignoreMethods配置项判断是否忽略
ignoreAST(path: babel.NodePath<babel.types.StringLiteral>) => boolean; // 通过ignoreAST断是否忽略该节点
ImportDeclaration(path: babel.NodePath<babel.types.ImportDeclaration>) => void; // 处理import代码
ExpressionStatement(path: babel.NodePath<babel.types.ExpressionStatement>) => void; // 处理表达式代码
Identifier(path: babel.NodePath<babel.types.Identifier>) => void; // 处理标识符代码
DirectiveLiteral(path: babel.NodePath<babel.types.DirectiveLiteral>) => void; // 处理指令代码,一般写在代码最上面
TemplateLiteral(path: babel.NodePath<babel.types.TemplateLiteral>) => void; // 处理模板字符串代码
StringLiteral(path: babel.NodePath<babel.types.StringLiteral>) => void; // 处理字符串代码, 代码中所有的字符串统一由此处理
ObjectExpression(path: babel.NodePath<babel.types.ObjectExpression>) => void; // 处理对象表达式代码
CallExpression(path: babel.NodePath<babel.types.CallExpression>) => void; // 处理函数调用代码
ArrowFunctionExpression(path: babel.NodePath<babel.types.ArrowFunctionExpression>) => void; // 处理箭头函数代码
ObjectMethod(path: babel.NodePath<babel.types.ObjectMethod>) => void; // 处理对象方法代码
FunctionDeclaration(path: babel.NodePath<babel.types.FunctionDeclaration>) => void; // 处理函数声明代码
JSXElement(path: babel.NodePath<babel.types.JSXElement & { ignore?: boolean }>) => void; // 处理jsx代码
JSXText(path: babel.NodePath<babel.types.JSXText>) => void; // 处理jsx文本代码
JSXAttribute(path: babel.NodePath<babel.types.JSXAttribute>) => void; // 处理jsx属性代码
replaceWith(path: babel.NodePath, value: any) => void; // 替换源代码判断
makeReplace(value: string, isTemplateLiteral = false, variables?: Record<string, any>) => babel.types.CallExpression | babel.types.StringLiteral | babel.types.TemplateLiteral | undefined; // 生成替换AST代码
makeStringLiteral(str: string): babel.types.StringLiteral // 生成字符串AST代码
makeTemplateLiteral(str: string): babel.types.TemplateLiteral // 生成模板字符串AST代码
makeStringAST(str: string, isTemplateLiteral = false) => babel.types.StringLiteral | babel.types.TemplateLiteral // 生成字符串或模板字符串AST代码
makeBinaryExpressionByArr(valueArr: string[], isTemplateLiteral = false, variables?: Record<string, any>) => babel.types.CallExpression | babel.types.StringLiteral | babel.types.TemplateLiteral | undefined // 生成二元表达式AST代码
makeObjectExpression(obj?: Record<string, any>) => babel.types.ObjectExpression // 生成对象表达式AST代码
makeI18nFunction(keyAST: babel.types.StringLiteral | babel.types.TemplateLiteral, variables?: Record<string, any>): babel.types.CallExpression // 生成i18n函数AST代码
}
ParseVUE类
用于解析vue的SFC代码,默认处理 .vue
文件,从 .vue
代码中提取出 template
, script
,并分别使用 ParseHTML
,ParseJS
进行再次解析,最终再合并成完成的 .vue
文件。
ts
class ParseVUE {
config: Tci18nConfig; // tci18n.config.json配置内容
sourceType: SOURCE_TYPE;// 文件类型
scene?: string; // 语料场景值(唯一标识)
parseHTML: ParseHTML; // 解析html代码(template部分)
parseJS: ParseJS; // 解析js代码(script部分)
hooks: Hook; // 解析vue中埋入的钩子,可用于插件开发,详见插件API
extractOnly: boolean = false; // 是否只提取语料,不替换源代码
parseCode(sourceCode: string, scene?: string, prettierOptions = {}) => string; // 解析vue代码
parseTemplate(template: vue3Compiler.SFCTemplateBlock) => string; // 解析template部分
parseScript(script: vue3Compiler.SFCScriptBlock) => string; // 解析script部分
combineVue(template: vue3Compiler.SFCTemplateBlock | null, script: vue3Compiler.SFCScriptBlock | null, styles: vue3Compiler.SFCStyleBlock[], customBlocks: vue3Compiler.SFCBlock[]) => string; // 将template,script组合成SFC代码
openTag(sfcBlock: vue3Compiler.SFCTemplateBlock | vue3Compiler.SFCScriptBlock | vue3Compiler.SFCStyleBlock | vue3Compiler.SFCBlock) => string; // 处理SFC中的开标签,用于组合SFC代码
closeTag(sfcBlock: vue3Compiler.SFCBlock) => string; // 处理SFC中的闭标签,用于组合SFC代码
}
BaseParse基类
所有解析类的基类,提供了一些公共方法。
ts
abstract class BaseParse extends Utils {
config: Tci18nConfig; // tci18n.config.json配置内容
sourceType: SOURCE_TYPE;// 文件类型
scene?: string; // 语料场景值(唯一标识)
primaryRegx: RegExp = /[\u4e00-\u9fa5]/; // 语料正则,匹配上代表是需要提取的语料
primaryRegxMap: Record<string, RegExp> = { // 语料正则映射,用于不同语料的正则
'zh-cn': /[\u4e00-\u9fa5]/,
'en-us': /[a-zA-Z]/,
};
filterMatch: RegExp[] = [ // 需要排除的语料字符串正则
/^https?:/, // 网络地址
/\.(jpg|jpeg|png|gif|bmp|txt|pdf|doc|docx|xls|xlsx|ppt|pptx)$/, // 常见文件
];
hasPrimary?: boolean; // 是否匹配到语料
static keyMap = new Map<string, Map<string, Array<string>>>(); // 用于缓存单词解析中提取出来的语料
primaryLocaleData: Record<string, string> = {}; // 语料数据
isPrimary(str: string = '', type?: string) => boolean; // 判断是否命中语料正则
isPurePrimary(str: string) => boolean; // 判断是否是纯语料
formatValue(value: string) => string; // 格式化语料值
formatKey(value: string) => string; // 格式化语料key
formatKeyForAttr(key: string) => string; // 格式化html中的属性key
formatJSONKey(key: string) => string; // 格式化json中的key
collectKey(key: string, value?: string) => void; // 收集语料
makeKey(keyValue: string, isAttr = false) => string; // 生成语料key
connectKey(value: string) => string; // 组合语料key
splitKey(key: string) => [string, string, string]; // 拆分语料key
ignoreStrings(str: string) => boolean; // 是否忽略该语料
ignoreMethods(methodName: string) => boolean; // 是否忽略该方法
ignoreComponents(componentName: string) => boolean; // 是否忽略该组件
ignoreAttrs(attrName: string) => boolean; // 是否忽略该属性
}