自定义编译器插件通过AST深度介入,在构建阶段精准识别并重命名隐私变量,结合命名模式+类型标注、赋值来源追溯、装饰器/注释标记三策略识别;仅修改Identifier节点name,用sha256生成一致混淆名,跳过export/declare/globalThis声明;支持TS transformer、Webpack loader、Vite插件集成;配套映射表审计,禁用console/throw/正则等敏感位置混淆,强调混淆仅为辅助防线。

自定义编译器插件可在代码构建阶段(如 Webpack、Vite 或 TypeScript 编译流程)中深度介入 AST,精准识别并重命名隐私敏感变量(如 idCard、phone、address 等),实现混淆而非简单正则替换,保障语义安全与运行正确性。
明确隐私变量的识别规则
不能依赖模糊关键词匹配,需结合上下文语义判断。推荐以下组合策略:
-
命名模式 + 类型标注:匹配变量名含
idcard、mobile、bankNo等关键字,且类型为string或number(通过 TypeScript 类型检查或 JSDoc 注解推断) -
赋值来源标记:若变量赋值来自用户输入(如
document.getElementById('phone').value)、本地存储(localStorage.getItem('token'))或 API 响应字段(res.data.user.phone),可沿 AST 数据流向上追溯并标记 -
装饰器或注释标记:支持显式声明,例如
@sensitive装饰器或// @obfuscate行注释,作为高置信度识别依据
在 AST 层实现安全重命名
混淆必须保持作用域和引用一致性,避免跨作用域误改或破坏闭包。关键要点:
- 仅修改
Identifier节点的name,不触碰字符串字面量、模板字面量或属性访问路径中的键名(如obj.phone中的phone是属性名,非变量名,不应混淆) - 使用唯一哈希(如
sha256(varName + scopePath))生成混淆名,确保同一变量在不同模块中重命名一致,便于调试与 sourcemap 映射 - 跳过声明在
export、declare、globalThis上的敏感变量,防止破坏外部调用契约
集成到主流构建工具链
以实际可用性为导向,适配常见环境:
-
TypeScript 编译期:编写
ttypescript自定义 transformer,在before阶段遍历VariableDeclaration和PropertyAssignment节点,调用上述识别与重命名逻辑 -
Webpack:开发
loader(如sensitive-var-loader),在source→AST→transform→generate流程中注入混淆步骤;配合babel-loader使用时,需置于其后以保证已解析为标准 AST -
Vite:作为
esbuild插件(onTransform钩子)或rollup插件(transform钩子),利用acorn或estree-walker解析并修改 AST
验证与防护边界
混淆不是万能的,需配套验证机制与明确限制:
- 生成混淆映射表(JSON 文件),记录原始名→混淆名对应关系,供审计与白盒测试使用;该文件不应进入生产包
- 禁止混淆
console.log参数、throw new Error()消息、正则表达式字面量等可能暴露原始信息的位置 - 对加密/解密函数参数、JWT payload 字段、接口请求体 key 等场景,建议结合运行时加密而非仅混淆变量名,混淆仅作为辅助防线

















