VSCode 扩展开发规则与最佳实践
更新时间
2025-09-27
项目结构理解
仓库关系
- 主项目:
/Users/ghost/work/WorldTourCasino/
- WorldTourCasino 主仓库 - 文档子项目:
/Users/ghost/work/WorldTourCasino/docs/
- 独立的 Git 仓库(不是子模块) - 扩展子项目:
/Users/ghost/work/WorldTourCasino/vscode-extensions/
- 独立的 Git 仓库(不是子模块)
重要:这些是独立的 Git 仓库,通过目录挂载方式组织,不使用 Git 子模块管理。
扩展安装方式
VSCode 扩展通过符号链接方式安装,不是复制或全局安装:
bash
# 正确的安装方式
ln -sf /path/to/extension ~/.vscode/extensions/extension-name-version
# 错误的理解
❌ 扩展会被全局安装到所有项目
❌ 扩展会被复制到 extensions 目录
多编辑器支持规则
支持的编辑器及目录
javascript
const SUPPORTED_EDITORS = {
'VSCode': '~/.vscode/extensions',
'Trae': '~/.trae/extensions',
'Trae-CN': '~/.trae-cn/extensions', // 注意:是 .trae-cn 不是 .traeCN
'Windsurf': '~/.windsurf/extensions',
'Cursor': '~/.cursor/extensions'
}
命名规范
- 目录名称:严格按照编辑器的实际目录名,如
.trae-cn
(不是.traeCN
) - 扩展命名:
{name}-{version}
格式,如wtc-toolbar-0.0.1
扩展激活规则
限制扩展仅在特定项目激活
1. package.json 配置
json
{
"activationEvents": [
"workspaceContains:**/WorldTourCasino.code-workspace",
"workspaceContains:.vscode/settings.json"
]
}
2. 扩展代码中的检查
typescript
// 在 activate 函数中检查
export async function activate(context: vscode.ExtensionContext) {
// 检查是否是 WTC 项目
const isWTC = await checkIsWTCProject();
if (!isWTC) {
return;
}
// 检查 WTC.is_wtc 标志
const config = vscode.workspace.getConfiguration('WTC');
if (!config.get('is_wtc')) {
return;
}
// 激活扩展功能...
}
工作区 vs 文件夹模式
- 工作区模式:打开
.code-workspace
文件 - 文件夹模式:直接打开项目文件夹
- 重要:扩展必须在两种模式下都能正常工作
配置文件管理
隐私配置处理
敏感配置不应放在 settings.json
(会被 Git 同步),应使用本地配置文件:
typescript
// 本地配置文件路径
const LOCAL_CONFIG = '.vscode/google-drive-folders.local.json';
// 自动创建配置文件
if (!fs.existsSync(localConfigPath)) {
const template = {
folders: {
"示例-文件夹": "请替换为实际的 Google Drive 文件夹 ID"
}
};
fs.writeFileSync(localConfigPath, JSON.stringify(template, null, 4));
// 自动打开配置文件让用户编辑
await vscode.window.showTextDocument(
await vscode.workspace.openTextDocument(localConfigPath)
);
}
.gitignore 配置
bash
# 本地配置文件
.vscode/google-drive-folders.local.json
# 认证令牌
*/scripts/token.json
# Node modules
*/node_modules/
node_modules/
# VS Code 扩展包
*.vsix
OAuth 认证自动化
自动化原则
用户要求:"请你谨记,我们要做的足够自动化"
实现方式
javascript
// 使用本地服务器自动捕获 OAuth 回调
async function getNewTokenWithDeviceCode(oAuth2Client) {
const server = http.createServer(async (req, res) => {
const reqUrl = url.parse(req.url, true);
if (reqUrl.pathname === '/' && reqUrl.query.code) {
const code = reqUrl.query.code;
// 自动交换 token
const { tokens } = await oAuth2Client.getToken(code);
// 保存 token
fs.writeFileSync(TOKEN_PATH, JSON.stringify(tokens));
// 返回成功页面
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>认证成功!</h1><p>窗口将自动关闭...</p>');
server.close();
resolve(tokens);
}
});
// 动态分配端口
const port = await getAvailablePort();
server.listen(port);
// 自动打开浏览器
const authUrl = oAuth2Client.generateAuthUrl({
redirect_uri: `http://localhost:${port}`,
access_type: 'offline',
scope: SCOPES
});
await vscode.env.openExternal(vscode.Uri.parse(authUrl));
}
Git 提交规则
多仓库提交策略
- 主项目提交:需要用户明确确认
- docs 子项目:可以自动提交(用户说"提交 docs"或"都提交吧")
- vscode-extensions 子项目:独立仓库,单独提交
提交前检查
bash
# 完整的提交流程
git add -A
git commit -m "提交信息"
git pull --rebase
git push
# 如有冲突,自动 stash 并恢复
git stash
git pull --rebase
git push
git stash pop
忽略构建产物
提交时忽略以下模式的文件:
res_*/flavor/index.html
res_*/flavor/main*.css
res_*/flavor/project.json
res_*/resource_list/**/*.json
node_modules/
脚本更新策略
fix-environment.sh 脚本维护
当配置结构变化时,优先考虑:
- 硬编码关键信息:避免依赖可能变化的配置结构
- 兼容性优先:使用基础 bash 语法,避免高级特性(如关联数组)
- 扩展性设计:使用数组和循环处理多个扩展和编辑器
bash
# 好的做法:硬编码扩展信息
declare -a EXTENSIONS=(
"wtc-toolbar:0.0.1:vscode-toolbar-extension"
"google-drive-uploader:0.0.1:google-drive-uploader"
)
# 避免:依赖可能变化的配置
EXTENSION_NAME=$(get_extensions_name) # 配置结构变化时会失败
图标设计原则
Google Drive 上传扩展图标
用户反馈:"算了,效果不好,还是你重新找个合适的吧,要体现'上载'"
解决方案:创建云上传图标,使用 Google 品牌色彩:
- 主体:向上的箭头表示上传
- 背景:云朵形状
- 颜色:Google 四色(蓝、红、黄、绿)
调试技巧
扩展不显示的排查
- 检查符号链接是否正确创建
- 验证
activationEvents
配置 - 确认
WTC.is_wtc
标志设置 - 检查工作区模式 vs 文件夹模式
常用调试命令
bash
# 检查扩展链接
ls -la ~/.vscode/extensions/ | grep wtc
# 检查多个编辑器
for editor in .vscode .trae .trae-cn .windsurf .cursor; do
echo "=== $editor ==="
ls -la ~/$editor/extensions/ | grep -E "wtc|google" 2>/dev/null
done
# 调试脚本执行
bash -x script.sh 2>&1 | head -100
文档记录原则
技术迭代记录位置
- 主项目技术迭代 →
docs/
下的相应分类目录 - docs 子项目技术迭代 →
docs/技术文档.md
- 故障排查 →
docs/故障排查/
- 工具和自动化 →
docs/工程-工具/
- VSCode 相关 →
docs/工程-工具/vscode/
文档命名规范
- 使用描述性中文名称
- 避免使用版本号或日期作为文件名
- 相关文档放在同一目录下
常见错误及解决
1. OAuth 重定向 URI 错误
错误:redirect_uri_mismatch
原因:使用了废弃的 urn:ietf:wg:oauth:2.0:oob
解决:使用动态 localhost 端口
2. 扩展全局可见
错误:扩展在所有项目中都显示 原因:未正确配置激活条件 解决:结合 activationEvents
和代码内检查
3. 配置读取失败
错误:extensionName
为空 原因:配置结构变更 解决:硬编码关键信息,减少配置依赖
4. Bash 兼容性问题
错误:declare -A: invalid option
原因:关联数组在某些 bash 版本不支持 解决:使用普通变量和循环
最佳实践总结
- 自动化优先:减少用户手动操作,提供一键解决方案
- 隐私保护:敏感配置使用本地文件,不提交到 Git
- 多编辑器兼容:支持主流的 VSCode 分支编辑器
- 错误恢复:提供清晰的错误信息和恢复方法
- 文档完善:及时记录技术决策和解决方案
- 代码简洁:移除不必要的依赖和冗余代码
- 用户友好:自动打开配置文件,提供模板和示例