最常见原因是语言上下文不匹配:snippet的scope字段必须与编辑器右下角显示的languageId完全一致,如typescriptreact、vue等,而非文件后缀;文件须置于snippets/目录下且命名严格匹配languageId,body必须为字符串数组格式。

为什么写完 snippet 文件却按 Tab 没反应
最常见原因是语言上下文不匹配。VSCode 不是“监听所有输入”,它只在当前编辑器右下角显示的 languageId 对应的语言模式下激活片段。比如你在 .ts 文件里敲 log,但片段定义在 javascript.json 里,且没加 "scope": "typescript",就不会触发。
查当前 languageId:按 Ctrl+Shift+P(macOS 是 Cmd+Shift+P),搜 Developer: Inspect Editor Tokens and Scopes,看顶部显示的 languageId 值——它可能叫 typescriptreact、vue 或 scss,不是文件后缀。
- 全局片段要删掉
scope字段,或显式写成"scope": "javascript,typescript,vue,scss" - 语言专属片段必须用对应语言 ID 命名文件,比如 TypeScript React 必须是
typescriptreact.json,不是tsx.json或ts.json - 文件路径必须严格落在
snippets/目录下:%APPDATA%\Code\User\snippets\(Windows)、$HOME/Library/Application Support/Code/User/snippets/(macOS)
如何正确写 body 字段避免静默失败
body 必须是字符串数组,不是单个字符串,也不是 JSONC 注释格式。VSCode 遇到语法错误不会报错,只会让整个片段失效。
错误写法:"body": "console.log();" → 缺少数组包装,不生效
正确写法:"body": ["console.log('${1:msg}');", "$0"]
- 每行一条语句,换行靠数组元素自然分隔,不用
\n - 制表符写成
\t,比如"\treturn $1;" - 占位符必须用
$1、$2、$0,不能写成${1}(除非带默认值,如${1:default}) - 同一个数字重复出现会同步更新,比如两个
$1,改一个另一个也变
全局片段 vs 语言专属片段怎么选
全局片段放 common.json,语言专属放 javascript.json、typescriptreact.json 等。别混用:想让 log 在 JS/TS/Vue/SCSS 里都生效,就别塞进 javascript.json,而该用全局 + 显式 scope。
- 全局文件名必须是
common.json(不是common.code-snippets或snippets.json) - 语言专属文件名必须和 VSCode 内置
languageId完全一致,大小写敏感 - 工作区级片段要放
.vscode/snippets/javascript.json,注意.vscode是隐藏目录 - 如果 prefix 冲突(比如多个片段都设
log),VSCode 只取第一个匹配的,顺序取决于文件加载顺序,不保证
修改后怎么让改动立刻生效
VSCode 不自动重载 snippets 文件。保存后必须手动重载窗口,否则永远看不到变化。
- 按
Ctrl+Shift+P,搜Developer: Reload Window,回车执行 - 不要依赖重启 VSCode,reload 更快且保留当前会话
- 如果 reload 后仍不生效,先删掉文件内容,只留
{},保存,再逐步加一个最简片段测试,排除 JSON 格式问题 - 文件编码必须是 UTF-8 无 BOM,Windows 下用记事本另存容易带 BOM,建议用 VSCode 自己保存
真正卡住人的地方往往不是语法,而是 languageId 匹配、文件路径层级、JSON 数组包装这三处。多看右下角那个小标签,比反复改 body 更管用。


















