主题文件须放项目根目录下手动创建的 themes/ 文件夹内,路径为 ./themes/your-theme-name.json(全小写+连字符),json需格式正确、声明uitheme类型,并兼顾暗/亮模式适配。

主题文件放哪?themes/ 目录必须手动建
VSCode 不会自动创建主题存放路径,直接在扩展里点“新建主题”只生成骨架代码,themes/ 文件夹得你自己在扩展项目根目录下新建。漏掉这步,打包后主题根本不会出现在「颜色主题」列表里。
常见错误现象:Extension 'xxx' has no themes 报错,或者主题选单里完全看不到你的主题名。
- 路径必须是
./themes/your-theme-name.json(或.ctm),不能嵌套在src/或dist/下 - 文件名里的空格、大写字母、中文都会导致加载失败,建议全小写 + 连字符,比如
dark-sage.json - 如果用了 TypeScript 编写主题(少见但可行),编译后仍需把最终 JSON 放进
themes/,不是 TS 源文件
tokenColors 和 semanticTokenColors 到底该配哪个?
绝大多数语法高亮靠 tokenColors,它匹配传统 TextMate 作用域(如 keyword、string.quoted.double);而 semanticTokenColors 是 VSCode 1.43+ 引入的语义化着色机制,依赖语言服务器提供类型信息(比如把 const foo = 42 中的 foo 识别为变量而非普通标识符)。
使用场景:写一个通用主题,优先填满 tokenColors;想支持 TS/JS 的精准着色(如区分参数、方法、类名),再补 semanticTokenColors。
-
tokenColors兼容性好,老版本 VSCode 和所有语言都认;semanticTokenColors在 Python/Go 等语言中默认不启用,需用户手动开启"editor.semanticHighlighting": true - 二者不互斥,但同名 token 冲突时,
semanticTokenColors优先级更高 - 别硬背作用域名——用
Ctrl+Shift+P→Developer: Inspect Editor Tokens and Scopes实时点选代码,左下角直接显示当前 token 链
为什么改了 editor.foreground 没生效?
这个配置项只控制编辑器默认文字颜色,但实际渲染中,几乎所有语法元素都会被 tokenColors 里更具体的作用域覆盖。比如你设了 "editor.foreground": "#fff",但 tokenColors 里写了 {"scope": "comment", "settings": {"foreground": "#999"}},那注释就还是灰的。
性能影响:过度依赖 editor.* 全局色(如 editor.background)没问题;但滥用 tokenColors 里大量模糊 scope(如只写 "identifier")会导致匹配变慢,尤其在大型文件中。
- 真正要全局统一调整,优先动
tokenColors的顶层 fallback,比如加一条{"scope": ["*"], "settings": {"foreground": "#e0e0e0"}} -
editor.foreground主要影响行号、折叠箭头、空格符号等非语法区域,别指望它管代码文字 - 修改后必须重启窗口(
Cmd/Ctrl+Shift+P→Developer: Reload Window),热更新不触发主题重载
发布前必验:JSON 格式、scope 冲突、暗色模式适配
一个合法主题 JSON 可以跑起来,不代表它能被正确理解。VSCode 对格式宽松,但某些边缘 case 会导致部分颜色静默失效,比如 scope 字符串末尾多了一个空格,或 settings 里混进了 null 值。
容易被忽略的地方:很多人只在暗色模式下调试,但 VSCode 会根据系统或设置自动切换亮/暗主题。如果你的主题只提供了 dark 类型,用户切到亮色模式时会回退到默认主题,而不是你的亮版。
- 用
jq . -S或 VSCode 自带的格式化(Shift+Alt+F)确保 JSON 无语法错误,特别检查逗号和引号 - 在
tokenColors数组里,靠后的规则会覆盖前面同 scope 的规则——把宽泛 scope(如"variable")放在前面,具体 scope(如"variable.parameter")放后面 - 主题
package.json中的contributes.themes必须明确声明uiTheme类型:"uiTheme": "dark"、"uiTheme": "light"或"uiTheme": "hc-black",否则无法归类











