Skip to content

@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,并分别使用 ParseHTMLParseJS 进行再次解析,最终再合并成完成的 .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;  // 是否忽略该属性
}