VSCode 插件开发实战(十五):如何支持多语言
前言
在软件开发中,多语言支持(i18n)是一个非常重要的功能。无论是桌面应用、移动应用,还是浏览器插件,都需要考虑如何支持不同国家和地区的用户,软件应用的多语言支持(i18n)已经成为提升用户体验的关键因素之一。
那么如何为您的自定义 VSCode 插件添加多语言支持,以便更好地服务来自不同语言背景的开发者?本教程将详细介绍如何通过简单而高效的方法,为您的 VSCode 插件实现多语言支持,从而提升其国际化能力。
添加多语言支持
1. 创建语言包文件
在你的插件项目中,创建一个 i18n 目录,用于存放不同语言的翻译文件。每种语言会对应一个单独的 JSON 文件,比如 en.json(英文)和 zh-cn.json(中文)。
en.json
{"helloWorld": "Hello, World!","greeting": "Welcome to our VSCode extension!"
}
zh-cn.json
{"helloWorld": "你好,世界!","greeting": "欢迎使用我们的 VSCode 插件!"
}
完整示例
以下是一个完整的插件目录结构示例:
my-vscode-extension
├── .vscode
│ ├── tasks.json
│ └── launch.json
├── .gitignore
├── README.md
├── package.json
├── src
│ ├── extension.ts
│ └── i18n
│ ├── en.json
│ └── zh-cn.json
├── tsconfig.json
└── vsc-extension-quickstart.md
2. 加载语言包
接下来,我们需要在插件代码中加载这些语言包。可以在 extension.js 或 extension.ts 中实现这一功能。
extension.ts
import * as vscode from 'vscode';
import * as path from 'path';
import * as fs from 'fs';function loadMessageBundle(locale: string) {const filePath = path.join(__dirname, 'i18n', `${locale}.json`);if (fs.existsSync(filePath)) {return JSON.parse(fs.readFileSync(filePath, 'utf8'));} else {// Default to English if locale file is not foundreturn JSON.parse(fs.readFileSync(path.join(__dirname, 'i18n', 'en.json'), 'utf8'));}
}export function activate(context: vscode.ExtensionContext) {const locale = vscode.env.language; // Get the current language setting of VSCodeconst messages = loadMessageBundle(locale);let disposable = vscode.commands.registerCommand('extension.helloWorld', () => {vscode.window.showInformationMessage(messages['helloWorld']);});context.subscriptions.push(disposable);
}export function deactivate() {}
3. 更新 package.json
最后,我们需要更新 package.json 文件,声明插件的语言包配置。
{"contributes": {"localizations": [{"languageId": "en","languageName": "English","translations": [{"id": "en","path": "./i18n/en.json"}]},{"languageId": "zh-cn","languageName": "Chinese (Simplified)","translations": [{"id": "zh-cn","path": "./i18n/zh-cn.json"}]}]}
}
进阶操作
动态切换语言
有时候,用户可能希望在不重启 VSCode 的情况下切换语言。我们可以借助 VSCode API 实现这一功能。
修改 extension.ts
首先,我们需要修改 extension.ts 文件,以支持动态加载语言包。
import * as vscode from 'vscode';
import * as path from 'path';
import * as fs from 'fs';let currentLocale: string = vscode.env.language;
let messages: { [key: string]: string };function loadMessageBundle(locale: string) {const filePath = path.join(__dirname, 'i18n', `${locale}.json`);if (fs.existsSync(filePath)) {return JSON.parse(fs.readFileSync(filePath, 'utf8'));} else {return JSON.parse(fs.readFileSync(path.join(__dirname, 'i18n', 'en.json'), 'utf8'));}
}function refreshMessages() {messages = loadMessageBundle(currentLocale);
}export function activate(context: vscode.ExtensionContext) {refreshMessages();let disposable = vscode.commands.registerCommand('extension.helloWorld', () => {vscode.window.showInformationMessage(messages['helloWorld']);});let changeLocaleCommand = vscode.commands.registerCommand('extension.changeLocale', async () => {const picked = await vscode.window.showQuickPick(['en', 'zh-cn'], {placeHolder: 'Select a language'});if (picked) {currentLocale = picked;refreshMessages();vscode.window.showInformationMessage(messages['greeting']);}});context.subscriptions.push(disposable, changeLocaleCommand);
}export function deactivate() {}
更新 package.json
为了让用户能够通过命令面板切换语言,我们需要在 package.json 中添加相应的命令配置。
{"contributes": {"commands": [{"command": "extension.helloWorld","title": "Hello World"},{"command": "extension.changeLocale","title": "Change Language"}],"localizations": [{"languageId": "en","languageName": "English","translations": [{"id": "en","path": "./i18n/en.json"}]},{"languageId": "zh-cn","languageName": "Chinese (Simplified)","translations": [{"id": "zh-cn","path": "./i18n/zh-cn.json"}]}]}
}
使用 TypeScript 类型定义
为了编写更健壮的代码,我们可以为语言包定义一个类型,并在加载语言包时进行类型检查。
定义类型
interface Messages {helloWorld: string;greeting: string;
}修改 loadMessageBundle 函数
function loadMessageBundle(locale: string): Messages {const filePath = path.join(__dirname, 'i18n', `${locale}.json`);if (fs.existsSync(filePath)) {return JSON.parse(fs.readFileSync(filePath, 'utf8')) as Messages;} else {return JSON.parse(fs.readFileSync(path.join(__dirname, 'i18n', 'en.json'), 'utf8')) as Messages;}
}
这样,我们在使用 messages 对象时,TypeScript 会帮助我们进行类型检查,确保代码的可靠性。
处理复杂的翻译需求
在实际应用中,翻译内容可能不仅仅是简单的字符串,还会涉及变量和占位符。我们可以使用较为成熟的 i18n 库来处理这些复杂的翻译需求。例如,使用 i18n 或 i18next 库。
使用 i18n
首先,安装 i18n 库:
npm install i18n
配置 i18n
import * as i18n from 'i18n';
import * as path from 'path';i18n.configure({locales: ['en', 'zh-cn'],directory: path.join(__dirname, 'i18n'),defaultLocale: 'en',extension: '.json',register: global
});function setLocale(locale: string) {i18n.setLocale(locale);
}export function activate(context: vscode.ExtensionContext) {setLocale(vscode.env.language);let disposable = vscode.commands.registerCommand('extension.helloWorld', () => {vscode.window.showInformationMessage(__('helloWorld'));});let changeLocaleCommand = vscode.commands.registerCommand('extension.changeLocale', async () => {const picked = await vscode.window.showQuickPick(['en', 'zh-cn'], {placeHolder: 'Select a language'});if (picked) {setLocale(picked);vscode.window.showInformationMessage(__('greeting'));}});context.subscriptions.push(disposable, changeLocaleCommand);
}export function deactivate() {}
修改语言包格式
i18n 库要求语言包文件的格式与之前有所不同:
en.json
{"helloWorld": "Hello, World!","greeting": "Welcome to our VSCode extension!"
}
zh-cn.json
{"helloWorld": "你好,世界!","greeting": "欢迎使用我们的 VSCode 插件!"
}
总结
通过本文的详细步骤,我们深入探讨了如何为 VSCode 自定义插件添加多语言支持。我们从创建简单的语言文件开始,逐步实现了动态切换语言的功能,并结合 TypeScript 类型定义和第三方库来处理复杂的翻译需求。掌握这些技术,您不仅能提高插件的用户体验,还能扩大其用户群体,推动插件在国际化市场上的应用。
相关文章:
VSCode 插件开发实战(十五):如何支持多语言
前言 在软件开发中,多语言支持(i18n)是一个非常重要的功能。无论是桌面应用、移动应用,还是浏览器插件,都需要考虑如何支持不同国家和地区的用户,软件应用的多语言支持(i18n)已经成…...
面试241228
面试可参考 1、cas的概念 2、AQS的概念 3、redis的数据结构 使用场景 不熟 4、redis list 扩容流程 5、dubbo 怎么进行服务注册和调用,6、dubbo 预热 7如何解决cos上传的安全问题kafka的高并发高吞吐的原因ES倒排索引的原理 spring的 bean的 二级缓存和三级缓存 spr…...
Python数据序列化模块pickle使用
pickle 是 Python 的一个标准库模块,它实现了基本的对象序列化和反序列化。序列化是指将对象转换为字节流的过程,这样对象就可以被保存到文件中或通过网络传输。反序列化是指从字节流中恢复对象的过程。 以下是 pickle 模块的基本使用方法: …...
Spring Boot对访问密钥加解密——HMAC-SHA256
HMAC-SHA256 简介 HMAC-SHA256 是一种基于 哈希函数 的消息认证码(Message Authentication Code, MAC),它结合了哈希算法(如 SHA-256)和一个密钥,用于验证消息的完整性和真实性。 HMAC 是 “Hash-based M…...
HTML 元素:网页构建的基础
HTML 元素:网页构建的基础 HTML(HyperText Markup Language,超文本标记语言)是构建网页的基石。它定义了网页的结构和内容,而HTML元素则是构成HTML文档的基石。在本篇文章中,我们将深入探讨HTML元素的概念、类型、用法,以及如何在网页设计中有效地使用它们。 什么是HT…...
HEIC 是什么图片格式?如何把 iPhone 中的 HEIC 转为 JPG?
在 iPhone 拍摄照片时,默认的图片格式为 HEIC。虽然 HEIC 格式具有高压缩比、高画质等优点,但在某些设备或软件上可能存在兼容性问题。因此,将 HEIC 格式转换为更为通用的 JPG 格式就显得很有必要。本教程将介绍如何使用简鹿格式工厂…...
爆肝1个月:DDR4 的信号完整性(万字长文SI)
前言: 大学里面,总有很多课程,很浪费时间,学了没点用处,问过老师,为什么信号完整性,示波器使用等课程不开呢,这种是对工作真实有帮助的? 老师:因为老师…...
前端js验证码插件
相关代码,在最上方的绑定资源...
关于easy-es对时间范围查询遇到的小bug
前言:在使用easy-es之前作为一个小白的我只有es原生查询的基础,在自己通过查看官方文档自学easy-es遇到了一个挫折,其他的还好语法和MybatisPlus差不多,正以为我觉得很快就能入手,在对时间范围的判断就给我当头一棒&am…...
Mask R-CNN
目录 摘要 Abstract Mask R-CNN 网络架构 Backbone RPN Proposal Layer ROIAlign bbox检测 Mask分割 损失计算 实验复现 总结 摘要 Mask R-CNN是在Faster R-CNN的基础上进行改进的目标检测和实例分割网络。Faster R-CNN主要用于目标检测,输出对象的边…...
大模型-Dify使用笔记
大模型-Dify使用笔记 0、调整docker镜像源1、安装1、Docker Compose方式部署 2、访问 Dify 0、调整docker镜像源 由于墙的存在,所以默认的docker镜像源很难拉取项目,需要调整相关的docker配置文件 vim /etc/docker/daemon.json添加如下docker镜像源 { …...
Suno Api V4模型无水印开发「综合实战开发自己的音乐网站」 —— 「Suno Api系列」第14篇
历史文章 Suno AI API接入 - 将AI音乐接入到自己的产品中,支持120并发任务 Suno Api V4模型无水印开发「灵感模式」 —— 「Suno Api系列」第1篇 Suno Api V4模型无水印开发「自定义模式」 —— 「Suno Api系列」第2篇 Suno Api V4模型无水印开发「AI生成歌词」…...
云原生架构中的中间件容器化:优劣势与实践探索
在云原生架构逐步推进的过程中,许多企业已经开始将应用和服务容器化,以充分利用云计算带来的弹性和自动化。随着容器技术的发展,容器化不仅仅限于应用层,越来越多的中间件也被考虑纳入容器化范畴,包括Redis、Kafka、Ra…...
如何测试模型推理性能:从零开始的Python指南
如何测试模型推理性能:从零开始的Python指南 什么是模型推理性能?测试模型推理性能的步骤1. 监测内存使用情况2. 测试模型吞吐量 运行测试总结 在机器学习和深度学习中,模型的推理性能是一个非常重要的指标。它可以帮助我们了解模型在实际应用…...
我们来学activiti -- bpmn
bpmn 题记bpmn结余 题记 在《Activiti很难学》提到学习知识点需要面对的思想钢印问题 按常见步骤,先展示下官方的客套话 BPMN(Business Process Model and Notation)是一种业务流程建模符号, 它是一种图形化的语言,用…...
【每日学点鸿蒙知识】节点析构问题、区分手机和pad、 Navigation路由问题、Tabs组件宽度、如何监听Map
1、HarmonyOS 只调用根节点的dispose,是否其下的子节点都能析构掉还是需要遍历子节点,都执行dispose才能正常析构? 前端持有引用关系的需要dispose,new出来的builderNode和FrameNode也需要dispose。只调用根节点的dispose,无法保证其下的子节…...
敏捷测试文化的转变
敏捷文化是敏捷测试转型的基础,只有具备敏捷文化的氛围,对组织架构、流程和相关测试实践的调整才能起作用。在前面的敏捷测试定义中,敏捷测试是遵从敏捷软件开发原则的一种测试实践,这意味着敏捷的价值观。 此外,从传…...
如何配置线程池参数,才能创建性能最好、最稳定的Spring异步线程池?
配置性能最好、最稳定的Spring异步线程池,需要综合考虑业务场景、硬件资源(CPU核心数、内存等)、并发量、任务特性(CPU密集型、IO密集型等)以及线程池参数。 以下是优化线程池配置的关键点及代码示例: 线程…...
【时间之外】IT人求职和创业应知【80】-特殊日子
目录 北京冬季招聘会 OpenAI CEO炮轰马斯克 英伟达推出全新AI芯片B300 莫欢喜,总成空。本周必须要谨行慎言。 感谢所有打开这个页面的朋友。人生不如意,开越野车去撒野,会害了自己,不如提升自己。提升自己的捷径就是学习和思考…...
Vue中接入萤石等直播视频(更新中ing)
一、萤石: 1. 萤石云开发文档: https://open.ys7.com/help/31 2、安装: npm install ezuikit-js --save 3、在文件中引用:import EZUIKit from ezuikit-js 4、具体代码: 获取accessToken:https://open.…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...
