Shark-Auto VSCode 插件
智能多语言代码转换工具 - 自动化维护多语言代码映射关系的 IDE 插件
核心特性
智能转换
- 精准文本识别: 使用高级正则表达式引擎,智能识别代码中的中文文本
- 智能复用机制: 自动检测并复用已有翻译,避免重复翻译相同文本
- 批量翻译优化: 支持批量API调用,大幅提升处理效率(提升95%+)
- 多翻译模式: 支持本地映射(maphash)和多种在线翻译API
高效工作流
- 单文件转换: 快速转换当前编辑的文件
- 批量文件夹处理: 一键处理整个项目或指定文件夹
- 智能去重: 自动避免重复映射和冲突处理
- 实时进度反馈: 详细的处理进度和统计信息
用户体验
- InlayHint 智能提示: 代码中直接显示中文原文,支持悬停查看详情
- 中文快速搜索: 通过中文关键词快速定位代码位置
- 可视化管理: 侧边栏显示语言映射和变更历史
- 一键安全回退: 支持完整的操作回退和文件恢复
安全可靠
- 自动备份: 转换前自动备份原始文件
- 智能检测: 避免重复转换已处理的文本
- 错误恢复: 完善的错误处理和恢复机制
- 数据完整性: 确保转换过程中数据不丢失
安装方式
方式一:VSCode 扩展市场(推荐)
- 在 VSCode 中按
Ctrl+Shift+X
打开扩展面板
- 搜索 "Shark-Auto"
- 点击安装并重启 VSCode
方式二:手动安装开发版
# 克隆项目
git clone https://git.dev.sh.ctripcorp.com/zzhiyong/shark-auto.git
cd shark-auto
# 安装依赖
npm install
# 编译插件
npm run compile
# 打包为.vsix文件
npm run package
快速开始
第一步:基础配置
打开 VSCode 设置 (Ctrl+,
),搜索 "shark-auto" 进行基础配置:
{
"shark-auto.includeFileTypes": [".tsx", ".jsx", ".ts", ".js", ".vue"],
"shark-auto.languageMapFile": "src/utils/shark-key/index.ts",
"shark-auto.translationFunctionName": "t",
"shark-auto.translationMode": "maphash"
}
第二步:选择翻译模式
本地映射模式 (maphash) - 推荐新手
- 优势: 无需配置API,开箱即用
- 适用: 小型项目,快速原型开发
- 配置: 无需额外配置
在线翻译模式 - 推荐生产环境
- 优势: 翻译质量高,支持批量处理
- 适用: 大型项目,生产环境
- 配置: 需要配置翻译API密钥
第三步:开始使用
使用方法
方法一:右键菜单(最便捷)
在任意支持的文件或文件夹上右键,选择相应的转换选项:
- 单文件转换: 在
.tsx/.jsx/.ts/.js/.vue
文件上右键 → "转化多语言"
- 批量转换: 在文件夹上右键 → "转化文件夹中的多语言"
- 查看报告: 右键 → "显示转化报告"
- 安全回退: 右键 → "回退上次多语言转化"
方法二:命令面板(快捷键)
按 Ctrl+Shift+P
(Windows/Linux) 或 Cmd+Shift+P
(Mac) 打开命令面板:
Shark Auto: 转化多语言 # 转换当前文件
Shark Auto: 转化文件夹中的多语言 # 批量转换文件夹
Shark Auto: 显示转化报告 # 查看详细报告
↩ Shark Auto: 回退上次多语言转化 # 安全回退操作
Shark Auto: 刷新语言映射 # 刷新InlayHint
Shark Auto: 打开设置 # 快速打开设置
方法三:侧边栏(可视化管理)
点击活动栏中的 Shark Auto 图标,使用可视化界面:
- 语言映射管理: 查看和管理所有翻译映射
- 最近变更: 查看最近的转换历史
- 快速操作: 一键执行常用操作
- 设置面板: 快速访问插件配置
完整工作流程
智能转换流程
graph TD
A[选择文件/文件夹] --> B[检测中文文本]
B --> C{检查已有翻译}
C -->|找到| D[复用已有key]
C -->|未找到| E[调用翻译API/生成key]
D --> F[应用替换到文件]
E --> F
F --> G[更新shark文件]
G --> H[生成处理报告]
H --> I[刷新InlayHint]
I --> J[完成转换]
转换示例
基础转换示例
转换前:
import React from 'react';
const UserProfile = () => {
const handleSave = () => {
message.success('保存成功');
};
return (
<div className="user-profile">
<h1>用户管理</h1>
<div className="form-section">
<label>用户名</label>
<input placeholder="请输入用户名" />
</div>
<div className="actions">
<button onClick={handleSave}>保存</button>
<button>取消</button>
</div>
</div>
);
};
转换后:
import React from 'react';
const UserProfile = () => {
const handleSave = () => {
message.success(t('saveSuccess'));
};
return (
<div className="user-profile">
<h1>{t('userManagement')}</h1>
<div className="form-section">
<label>{t('username')}</label>
<input placeholder={t('enterUsername')} />
</div>
<div className="actions">
<button onClick={handleSave}>{t('save')}</button>
<button>{t('cancel')}</button>
</div>
</div>
);
};
生成的映射文件 (shark.ts):
import transform from './utils/transform'
const map = {
// 智能生成的有意义key
userManagement: 'CON001001', // 用户管理
username: 'CON001002', // 用户名
enterUsername: 'CON001003', // 请输入用户名
save: 'CON001004', // 保存
cancel: 'CON001005', // 取消
saveSuccess: 'CON001006', // 保存成功
}
export default transform(map)
InlayHint 效果展示
转换后的代码会自动显示中文提示:
const message = t('userManagement'); /* 用户管理 */
const placeholder = t('enterUsername'); /* 请输入用户名 */
翻译模式配置
Shark-Auto 支持多种翻译模式,满足不同项目需求:
翻译模式对比
模式 |
优势 |
适用场景 |
配置复杂度 |
翻译质量 |
maphash |
免费、快速、离线 |
原型开发、小项目 |
⭐ |
⭐⭐⭐ |
腾讯翻译 |
免费额度高、批量优化 |
大型项目、生产环境 |
⭐⭐ |
⭐⭐⭐⭐⭐ |
火山翻译 |
字节跳动技术、稳定 |
企业级应用 |
⭐⭐ |
⭐⭐⭐⭐ |
阿里云翻译 |
阿里云生态集成 |
云原生项目 |
⭐⭐ |
⭐⭐⭐⭐ |
推荐配置
新手推荐:maphash 模式
{
"shark-auto.translationMode": "maphash"
}
- ✅ 无需API配置,开箱即用
- ✅ 完全离线,无网络依赖
- ✅ 生成有意义的英文key
生产推荐:腾讯翻译模式
{
"shark-auto.translationMode": "tencent",
"shark-auto.tencentTranslation": {
"secretId": "你的SecretId",
"secretKey": "你的SecretKey",
"region": "ap-beijing"
}
}
- ✅ 500万字符/月免费额度
- ✅ 支持批量翻译,效率提升95%+
- ✅ 智能复用,避免重复翻译
翻译API服务商对比
以下是主流翻译API服务商的详细对比信息:
⭐ 推荐:腾讯翻译提供500万字符/月的免费额度,是目前免费额度最高的服务商,适合大多数开发场景。
腾讯翻译配置示例
{
"shark-auto.translationMode": "tencent",
"shark-auto.tencentTranslation": {
"secretId": "你的SecretId",
"secretKey": "你的SecretKey",
"region": "ap-beijing"
}
}
配置说明
默认正则表达式
插件预设了两个正则表达式来匹配中文文本:
- 双引号中文:
"([\\u4e00-\\u9fa5]+[^"]*?)"
- 单引号中文:
'([\\u4e00-\\u9fa5]+[^']*?)'
自定义正则表达式
可以添加更多正则表达式来匹配特定场景:
{
"shark-auto.regexPatterns": [
{
"name": "双引号中文",
"regex": "\"([\\u4e00-\\u9fa5]+[^\"]*?)\"",
"group": 1
},
{
"name": "JSX标签内容",
"regex": ">([\\u4e00-\\u9fa5][^<]*?)<",
"group": 1
}
]
}
高级配置
{
"shark-auto.includeFileTypes": [".tsx", ".jsx", ".ts", ".js", ".vue"],
"shark-auto.excludePatterns": [
"**/node_modules/**",
"**/dist/**",
"**/build/**",
"**/*.test.ts",
"**/*.spec.ts"
],
"shark-auto.languageMapFile": "src/i18n/zh-CN.ts",
"shark-auto.translationFunctionName": "i18n.t"
}
智能 Key 生成
插件会根据中文内容智能生成有意义的 key:
中文文本 |
生成的 Key |
确定 |
confirm |
取消 |
cancel |
保存 |
save |
删除 |
delete |
用户管理 |
user |
短文本 |
short_text_xxxx |
长文本内容 |
long_text_xxxx |
特色功能
InlayHint 智能提示系统
实时中文提示
转换后的代码会自动显示中文原文,让您一目了然:
// 自动显示中文提示
const title = t('userManagement'); /* 用户管理 */
const message = t('saveSuccess'); /* 保存成功 */
const placeholder = t('enterUsername'); /* 请输入用户名 */
悬停详情查看
鼠标悬停在任意 t()
函数上,查看完整信息:
键值对: userManagement: 'CON001001'
中文原文: 用户管理
强大的中文搜索功能
快速定位代码位置
方法一:工作区符号搜索(推荐)
- 按
Ctrl+T
(Windows/Linux) 或 Cmd+T
(Mac)
- 输入中文关键词,如:"用户管理"
- 立即跳转到对应的代码位置
方法二:当前文件搜索
- 按
Ctrl+Shift+O
(Windows/Linux) 或 Cmd+Shift+O
(Mac)
- 在当前文件内搜索中文内容
搜索结果示例
搜索:"用户管理"
结果:
用户管理 t("userManagement") src/components/User.tsx:15
用户管理 原始中文文本 src/pages/Admin.tsx:28
用户管理系统 原始中文文本 src/utils/constants.ts:5
智能匹配特性
- ✅ 完全匹配: "用户管理" → 精确找到
- ✅ 部分匹配: "用户" → 找到所有包含"用户"的文本
- ✅ 模糊匹配: "管理" → 找到所有管理相关功能
- ✅ 双向搜索: 既能找到已转换的
t()
调用,也能找到原始中文
智能复用系统
自动检测已有翻译
检测到:"用户管理"
✅ 在shark文件中找到匹配: userManagement: 'CON001001' // 用户管理
♻️ 自动复用,跳过翻译API调用
批量处理优化
- 批量翻译: 一次API调用处理多个文本
- 智能去重: 自动合并相同的翻译请求
- 效率提升: 相比单个翻译,效率提升95%+
可视化管理界面
侧边栏功能
- 语言映射管理: 查看所有翻译条目
- 最近变更历史: 追踪转换记录
- 快速操作面板: 一键执行常用功能
- 设置快捷入口: 快速访问配置
详细处理报告
转换完成报告
处理文件: 15个
总替换数: 127个文本
复用翻译: 89个 (70%)
新增翻译: 38个 (30%)
处理时间: 3.2秒
节省成本: 89次API调用
开发
本地开发
# 安装依赖
npm install
# 启动开发模式
npm run dev
# 在VSCode中按F5启动调试
构建发布
# 编译
npm run compile
# 打包生产版本
npm run package
# 生成VSIX文件
npm run vsix
贡献
欢迎提交 Issue 和 Pull Request!
许可证
MIT License
高级配置
自定义正则表达式
{
"shark-auto.regexPatterns": [
{
"name": "双引号中文",
"regex": "\"([\\u4e00-\\u9fa5]+[^\"]*?)\"",
"group": 1
},
{
"name": "JSX标签内容",
"regex": ">([\\u4e00-\\u9fa5][^<]*?)<",
"group": 1
},
{
"name": "模板字符串",
"regex": "`([\\u4e00-\\u9fa5][^`]*?)`",
"group": 1
}
]
}
完整配置示例
{
"shark-auto.includeFileTypes": [".tsx", ".jsx", ".ts", ".js", ".vue"],
"shark-auto.excludePatterns": [
"**/node_modules/**",
"**/dist/**",
"**/build/**",
"**/*.test.ts",
"**/*.spec.ts"
],
"shark-auto.languageMapFile": "src/utils/shark-key/index.ts",
"shark-auto.translationFunctionName": "t",
"shark-auto.translationMode": "tencent",
"shark-auto.tencentTranslation": {
"secretId": "你的SecretId",
"secretKey": "你的SecretKey",
"region": "ap-beijing"
}
}
开发指南
本地开发
# 克隆项目
git clone https://git.dev.sh.ctripcorp.com/zzhiyong/shark-auto.git
cd shark-auto
# 安装依赖
npm install
# 启动开发模式
npm run dev
# 在VSCode中按F5启动调试
构建发布
# 编译TypeScript
npm run compile
# 打包生产版本
npm run package
# 生成VSIX安装包
npm run vsix
更新日志
贡献指南
我们欢迎所有形式的贡献!
提交Issue
- Bug报告: 详细描述问题和复现步骤
- 功能建议: 提出新功能或改进建议
- 文档改进: 帮助完善文档和示例
提交PR
- Fork 项目到您的Git账户
- 创建功能分支:
git checkout -b feature/amazing-feature
- 提交更改:
git commit -m 'Add amazing feature'
- 推送分支:
git push origin feature/amazing-feature
- 创建Pull Request
技术支持
获取帮助
- 文档: 查看完整的使用文档和API参考
- Issue: 提交问题
- 讨论: 参与社区讨论和经验分享
WorkspaceSymbolProvider 搜索逻辑归纳
核心搜索流程
1. 输入验证与预处理
// 基本验证
if (!query.trim() || query.length < 2) return [];
if (token.isCancellationRequested) return [];
2. 环境准备
// 获取配置和工作区
const settings = loadSettings();
const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
const mapFilePath = path.resolve(workspaceFolder.uri.fsPath, settings.languageMapFile);
// 解析语言映射文件
const languageMap = this.inlayHintService.getLanguageMapWithComments(mapFilePath);
3. 文件搜索与分类
// 文件搜索模式
const includePattern = `projects/travel-agency/**/*.{tsx,jsx,ts,js}`;
const excludePattern = `{**/node_modules/**,**/dist/**,**/build/**,**/packages/**}`;
// 获取并排序文件
const allFiles = await vscode.workspace.findFiles(includePattern, excludePattern);
const sortedFiles = allFiles.sort((a, b) => a.fsPath.localeCompare(b.fsPath));
// 智能文件分类
const businessFiles = sortedFiles.filter(file => {
return filePath.includes('/src/pages/') ||
filePath.includes('/src/components/') ||
filePath.includes('/src/utils/') ||
filePath.includes('/src/services/') ||
(filePath.endsWith('.tsx') && !filePath.endsWith('.d.ts')) ||
(filePath.endsWith('.jsx') && !filePath.endsWith('.d.ts')) ||
(filePath.endsWith('.ts') && !filePath.endsWith('.d.ts') && !filePath.includes('.config.'));
});
const configFiles = sortedFiles.filter(file => {
return filePath.endsWith('.d.ts') ||
filePath.endsWith('.config.js') ||
filePath.endsWith('gulp.js') ||
filePath.includes('babel.') ||
filePath.includes('jest.');
});
// 优先级排序:业务文件 > 配置文件
const files = [...businessFiles, ...configFiles];
双路径搜索策略
路径1:Shark映射搜索(主要)
// 1. 预筛选匹配的keys
const matchingKeys: string[] = [];
for (const [key, item] of Object.entries(languageMap)) {
const displayText = item.comment || item.value;
if (displayText.includes(query)) {
matchingKeys.push(key);
}
}
// 2. 在文件中搜索t函数调用
for (const key of matchingKeys) {
const tFunctionRegex = new RegExp(
`${settings.translationFunctionName}\\s*\\(\\s*["']${key}["']\\s*\\)`,
"g"
);
while ((match = tFunctionRegex.exec(text)) !== null) {
// 创建符号信息
const symbol = new vscode.SymbolInformation(
displayText, // 显示中文
vscode.SymbolKind.Function, // 函数类型
`t("${key}")`, // 容器名称
location // 文件位置
);
symbols.push(symbol);
}
}
路径2:原始文本搜索(辅助)
// 搜索原始中文文本
while ((chineseMatch = chineseTextRegex.exec(text)) !== null) {
const chineseText = (chineseMatch[1] || chineseMatch[2] || '').trim();
if (chineseText.length > 0 && /[\u4e00-\u9fa5]/.test(chineseText)) {
const symbol = new vscode.SymbolInformation(
chineseText, // 显示原始文本
vscode.SymbolKind.String, // 字符串类型
"原始中文文本", // 容器名称
location // 文件位置
);
symbols.push(symbol);
}
}
性能优化策略
1. 分层限制机制
const maxFiles = 500; // 最大处理文件数
const maxSymbols = 100; // 最大返回符号数
const maxMatches = 20; // 每文件最大匹配数
2. 早期退出条件
// 取消令牌检查
if (token.isCancellationRequested) break;
// 文件数量限制
if (processedFiles >= maxFiles) break;
// 符号数量限制
if (symbols.length >= maxSymbols) break;
3. 预筛选优化
// 先筛选匹配的keys,避免无效搜索
if (matchingKeys.length === 0) return symbols;
搜索算法特点
1. 智能匹配
- 精确匹配:通过shark文件映射实现中文到key的精确匹配
- 模糊匹配:支持部分中文文本匹配
- 双重保障:既搜索t函数调用,也搜索原始文本
2. 文件优先级
- 业务优先:优先搜索业务代码文件
- 类型过滤:排除类型定义和配置文件
- 路径排序:确保搜索结果的一致性
3. 正则表达式策略
// t函数调用匹配
`${translationFunctionName}\\s*\\(\\s*["']${key}["']\\s*\\)`
数据流图
用户输入查询词
↓
输入验证 (长度≥2)
↓
加载配置和映射文件
↓
文件搜索和分类
↓
预筛选匹配的keys
↓
并行搜索路径:
├─ 路径1: t函数调用搜索
│ ├─ 正则匹配 t('key')
│ └─ 创建Function类型符号
└─ 路径2: 原始文本搜索
├─ 正则匹配中文文本
└─ 创建String类型符号
↓
合并结果并返回
关键配置参数
VSCode设置
{
"shark-auto.includeFileTypes": [".tsx", ".jsx", ".ts", ".js"],
"shark-auto.excludePatterns": ["**/node_modules/**", "**/dist/**", "**/build/**"],
"shark-auto.translationFunctionName": "t",
"shark-auto.languageMapFile": "src/utils/shark-key/index.ts"
}
性能参数
const maxFiles = 500; // 文件处理上限
const maxSymbols = 100; // 符号返回上限
const maxMatches = 20; // 单文件匹配上限
搜索结果类型
1. t函数调用结果
{
name: "环线总览", // 中文显示名
kind: SymbolKind.Function, // 函数类型
containerName: 't("ringOverview")', // 函数调用
location: Location // 文件位置
}
2. 原始文本结果
{
name: "环线总览", // 原始文本
kind: SymbolKind.String, // 字符串类型
containerName: "原始中文文本", // 类型标识
location: Location // 文件位置
}
错误处理机制
1. 文件级错误处理
try {
const document = await vscode.workspace.openTextDocument(file);
// 处理文件内容
} catch (error) {
console.error(`Error processing file ${file.fsPath}:`, error);
// 继续处理下一个文件
}
2. 全局错误处理
try {
// 整个搜索流程
} catch (error) {
console.error("Error providing workspace symbols:", error);
return symbols; // 返回已收集的符号
}
总结
这个搜索逻辑实现了:
- 双路径搜索:既能找到t函数调用,也能找到原始中文文本
- 智能文件分类:优先搜索业务代码,提高搜索效率
- 性能优化:多层限制机制,确保响应速度
- 结果一致性:文件排序和预筛选,保证搜索结果稳定
- 用户友好:支持取消操作,提供清晰的符号分类
整个系统在准确性、性能和用户体验之间达到了良好的平衡。
常见问题
许可证
本项目采用 MIT License 开源协议。