基于 VS Code 2026 (1.100+) 的实战踩坑经验总结。从零开始,一步步深入理解 VS Code 的配色系统架构,最终完成自定义主题的创建与语法颜色覆盖。
VS Code 2026 对主题系统做了重大变更:内置主题名称从 Light+ / Dark+ 改为 Light 2026 / Dark 2026。如果你沿用旧的配置方式,许多操作将直接失效。
本指南记录了一段完整的探索过程:从简单的主题切换,到深入调试 SQLite 缓存、文件优先级、扩展注册机制,最终建立了一个稳定、可复用的配色方案。
配色系统的层级架构(从低到高优先级):
| 层级 | 载体 | 职责 |
|---|---|---|
| Product | product.json |
应用默认主题列表,定义合法的内置主题名称 |
| Theme | 主题扩展 (package.json) 或内置主题 |
提供 colors + tokenColors 基准定义 |
| Runtime Cache | state.vscdb(SQLite) |
缓存当前主题数据,可能覆盖 settings.json |
| colorCustomizations | settings.json |
覆盖 UI 工作台颜色(侧边栏、标题栏等) |
| tokenColorCustomizations | settings.json |
覆盖语法高亮颜色(关键字、字符串等) |
注意:
colorCustomizations和tokenColorCustomizations是两个独立维度。前者管 UI 控件颜色,后者管代码语法颜色。
| 旧名称 (VS Code <= 1.99) | 新名称 (VS Code 2026 / 1.100+) |
|---|---|
Light+ |
Light 2026 |
Dark+ |
Dark 2026 |
Light (Visual Studio) |
Light 2026(已合并) |
| 文件 | 路径 | 类型 | 作用 |
|---|---|---|---|
settings.json |
%APPDATA%/Code/User/settings.json |
JSON | 用户配置中心 |
state.vscdb |
%APPDATA%/Code/User/globalStorage/state.vscdb |
SQLite | 运行时缓存,可能覆盖配置 |
storage.json |
%APPDATA%/Code/User/globalStorage/storage.json |
JSON | 运行时状态,会被回写覆盖 |
product.json |
安装目录 resources/app/product.json |
JSON | 应用默认值 |
extensions.json |
%USERPROFILE%/.vscode/extensions/extensions.json |
JSON | 扩展注册表 |
.obsolete |
扩展目录下 | 标记文件 | 存在则禁用该扩展 |
| 主题扩展 | %USERPROFILE%/.vscode/extensions/<name>/ |
目录 | package.json + themes/*.json |
VS Code 窗口的每个可见区域都有对应的 CSS 风格属性名:
┌──────────────────────────────────────────────────────────────┐
│ titleBar.* ● █ Yanmi Light — filename.ts │
├────────┬─────────────────────────────────────────────────────┤
│actBar.*│ sideBar.* │ editor.* │
│ ┌────┐ │ ┌──────────────────┐ │ ┌──────────────────────────┐ │
│ │ 📁 │ │ │ EXPLORER │ │ │ const x = "hello" │ │
│ │ 🔍 │ │ │ ▸ src/ │ │ │ │ │
│ │ 🔧 │ │ │ app.ts │ │ │ ← tab.* (Active Tab) │ │
│ │ ▶ │ │ │ utils.ts │ │ │ │ │
│ │ 🧪 │ │ │ ▸ tests/ │ │ │ │ │
│ └────┘ │ └──────────────────┘ │ └──────────────────────────┘ │
├────────┴─────────────────────────────────────────────────────┤
│ panel.* PROBLEMS OUTPUT DEBUG CONSOLE TERMINAL │
├──────────────────────────────────────────────────────────────┤
│ statusBar.* Ln 14, Col 8 Spaces: 2 UTF-8 TypeScript │
└──────────────────────────────────────────────────────────────┘
| 区域 | 前缀 | 核心属性 |
|---|---|---|
| 标题栏 | titleBar |
activeBackground, activeForeground, inactiveBackground, border |
| 活动栏 | activityBar |
background, foreground, activeBorder, inactiveForeground, border |
| 侧边栏 | sideBar |
background, foreground, sideBarTitle.foreground, sideBarSectionHeader.background |
| 编辑器 | editor |
background, foreground, lineHighlightBackground, selectionBackground, cursor.foreground, lineNumber.foreground |
| 标签页 | tab |
activeBackground, activeForeground, inactiveBackground |
| 面板 | panel |
background, border, panelTitle.activeForeground, terminal.background |
| 状态栏 | statusBar |
background, foreground, noFolderBackground, border |
优点:无需创建扩展,直接编辑,即时生效,不受 .obsolete / extensions.json 影响,优先级最高。
- 创建扩展目录结构:
package.json+themes/your-theme.json - 编写
package.json(含contributes.themes声明) - 编写主题 JSON(含
colors+tokenColors) - 在
extensions.json中注册(这是最容易遗漏的步骤!) - 删除可能存在的
.obsolete文件 - 重启 VS Code
// extensions.json 示例
[
{
"identifier": { "id": "yanmi.yanmi-light-theme" },
"version": "1.0.0",
"location": { "path": "yanmi-light-theme" }
}
]常见陷阱:
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 扩展被禁用 | 存在 .obsolete 文件 |
删除 .obsolete |
| 扩展不加载 | 未在 extensions.json 注册 |
添加注册条目 |
| 主题名不匹配 | label/name/colorTheme 不一致 |
确保三处名称一致 |
| tokenColors 不生效 | 本地扩展刷新不可靠 | 改用方法三 |
扩展主题的 tokenColors 在某些情况下不会正确重载,但 settings.json 中的 editor.tokenColorCustomizations 始终生效。
// 基础用法
{
"editor.tokenColorCustomizations": {
"[Yanmi Light]": {
"comments": "#6a737d",
"keywords": "#d73a49",
"strings": "#032f62",
"functions": "#6f42c1",
"variables": "#e36209",
"numbers": "#005cc5",
"types": "#22863a"
}
}
}
// 高级用法(textMateRules)
{
"editor.tokenColorCustomizations": {
"textMateRules": [
{
"scope": "entity.name.function",
"settings": { "foreground": "#6f42c1", "fontStyle": "bold" }
},
{
"scope": "variable.other.readwrite",
"settings": { "foreground": "#005cc5" }
}
]
}
}查找当前 Token 的 Scope:命令面板 Ctrl+Shift+P -> Developer: Inspect Editor Tokens and Scopes
| 问题 | 诊断步骤 | 解决方案 |
|---|---|---|
| 主题名不生效 | 检查 product.json 的 onboardingThemes |
使用 2026 系列主题名 |
| settings.json 改了没反应 | 检查 state.vscdb 缓存 |
关闭 VS Code 后重启 |
| 自定义扩展不加载 | 检查 extensions.json + .obsolete |
注册扩展 + 删除 .obsolete |
| Token 颜色不改 | 用 Inspect Editor Tokens 查 scope | 用 tokenColorCustomizations |
| 改 storage.json 后还原 | VS Code 会回写该文件 | 改 settings.json,不要改 storage.json |
import sqlite3, json
db = sqlite3.connect("%APPDATA%/Code/User/globalStorage/state.vscdb")
cursor = db.cursor()
# 查看所有 key
cursor.execute("SELECT key FROM ItemTable")
for row in cursor.fetchall():
print(row[0])
# 查看 colorThemeData
cursor.execute("SELECT value FROM ItemTable WHERE key = 'colorThemeData'")
data = cursor.fetchone()
if data:
theme = json.loads(data[0])
print(json.dumps(theme, indent=2, ensure_ascii=False))
db.close()注意:查询前必须先关闭 VS Code,否则 SQLite 文件被锁定。
flowchart TD
A["<b>1. 初始状态</b><br/>Dark 2026 深色主题"] --> B["<b>2. 尝试 Light+</b><br/>设置 workbench.colorTheme"]
B -->|不生效 ❌| C["<b>3. 排查</b><br/>发现 state.vscdb 缓存了 Dark 2026<br/>VS Code 不认识旧名称 Light+"]
C --> D["<b>4. 尝试改 storage.json</b>"]
D -->|无效 ❌| E["<b>5. 尝试 Light (Visual Studio)</b>"]
E -->|无效 ❌| F["<b>6. 查看 product.json</b><br/>发现仅含 2026 系列主题名"]
F --> G["<b>7. 切换 Light 2026</b><br/>成功!"]
G --> H["<b>8. colorCustomizations 调整 UI</b><br/>多轮迭代侧边栏、面板、标题栏"]
H --> I["<b>9. 创建独立主题 Yanmi Light</b><br/>编写 package.json + theme JSON"]
I --> J["<b>10. .obsolete 禁用扩展</b><br/>未注册 extensions.json"]
J --> K["<b>11. 注册 + 删 .obsolete</b><br/>主题加载成功!"]
K --> L["<b>12. 调整 Token 颜色</b><br/>多轮迭代加深语法色"]
L --> M["<b>13. 扩展 tokenColors 不生效</b><br/>本地扩展刷新不可靠"]
M --> N["<b>14. 终态 🎯</b><br/>Yanmi Light 主题<br/>+ tokenColorCustomizations 覆盖语法色"]
style A fill:#1b3a1b,stroke:#4caf50,color:#fff
style B fill:#1a2a4a,stroke:#42a5f5,color:#fff
style C fill:#3e2a00,stroke:#ff9800,color:#fff
style D fill:#3e1515,stroke:#f44336,color:#fff
style E fill:#3e1515,stroke:#f44336,color:#fff
style F fill:#3e2a00,stroke:#ff9800,color:#fff
style G fill:#1a3a1a,stroke:#66bb6a,color:#fff
style H fill:#2a1a3a,stroke:#ab47bc,color:#fff
style I fill:#1a2a4a,stroke:#42a5f5,color:#fff
style J fill:#3e1515,stroke:#f44336,color:#fff
style K fill:#1a3a1a,stroke:#66bb6a,color:#fff
style L fill:#2a1a3a,stroke:#ab47bc,color:#fff
style M fill:#3e1515,stroke:#f44336,color:#fff
style N fill:#1a1a3a,stroke:#00bcd4,color:#fff
flowchart TB
subgraph App["应用层"]
PF["product.json<br/><i>应用默认值<br/>onboardingThemes</i>"]
BT["内置主题<br/><i>Dark 2026 / Light 2026</i>"]
end
subgraph User["用户配置层"]
SG["settings.json<br/><i>用户配置中心<br/>colorTheme / colorCustomizations<br/>/ tokenColorCustomizations</i>"]
end
subgraph Runtime["运行时层"]
ST["state.vscdb (SQLite)<br/><i>缓存 colorThemeData<br/>⚠ 可能覆盖配置</i>"]
SR["storage.json<br/><i>运行时状态<br/>⚠ 会被回写覆盖</i>"]
end
subgraph Ext["扩展层"]
EX["extensions.json<br/><i>扩展注册表<br/>⚠ 必须注册</i>"]
OB[".obsolete<br/><i>标记文件<br/>⚠ 存在则禁用扩展</i>"]
TH["主题扩展<br/><i>package.json<br/>themes/xxx.json</i>"]
end
subgraph Outcome["最终效果"]
WIN["VS Code 窗口<br/><i>生效的配色</i>"]
end
PF --> BT
BT --> WIN
SG --> WIN
ST --> WIN
SR -.->|被回写| WIN
EX --> TH
OB -.->|禁用| TH
TH --> WIN
%% Override arrows
SG -.->|覆盖| ST
SG -.->|覆盖| BT
style PF fill:#1b5e20,stroke:#4caf50,color:#fff
style BT fill:#0d47a1,stroke:#1565c0,color:#fff
style SG fill:#4a148c,stroke:#6a1b9a,color:#fff
style ST fill:#e65100,stroke:#ff9800,color:#fff
style SR fill:#b71c1c,stroke:#f44336,color:#fff
style EX fill:#4a148c,stroke:#6a1b9a,color:#fff
style OB fill:#b71c1c,stroke:#f44336,color:#fff
style TH fill:#0d47a1,stroke:#1565c0,color:#fff
style WIN fill:#006064,stroke:#00bcd4,color:#fff
- 选择基础主题:使用
Light 2026/Dark 2026等 2026 系列名称 - 创建独立扩展:固化 UI 颜色,方便跨项目复用
- 在 extensions.json 中注册:手动安装的主题扩展必须注册
- 删除 .obsolete:避免扩展被自动禁用
- 用 tokenColorCustomizations 覆盖语法色:最可靠的方法,不受扩展加载状态影响
- 遇到不生效先查 state.vscdb:SQLite 缓存可以覆盖一切
MIT License
本文基于 VS Code 2026 (1.100+) 实测经验编写 -- 2026年4月
{ "workbench.colorTheme": "Light 2026", "workbench.colorCustomizations": { "[Light 2026]": { "sideBar.background": "#f0f0f5", "sideBar.foreground": "#333333", "panel.background": "#ffffff", "editor.background": "#ffffff", "titleBar.activeBackground": "#e8e8f0", "statusBar.background": "#e0e0ea" } } }