vs code代码片段需重启才生效,且依赖语言模式、scope字段、prefix/body格式等严格条件。未保存文件、错误languageid、空格导致scope失效、变量使用不当等均会导致片段不触发。

直接改 JSON 文件根本不会生效
VS Code 的代码片段不是“保存就热更新”的机制,它只在启动时加载一次 snippets 目录下的 JSON 文件。你改完 javascript.json 或 my-common.code-snippets,不重启编辑器,旧配置照常运行——这是最常被忽略的硬性限制。
常见错误现象:
输入 log 没反应;补全列表里看不到刚加的片段;修改了 body 但插入内容还是老样子。
- 确认当前文件右下角语言模式是
javascript(不是JavaScript React或typescript),否则语言专属片段压根不加载 - 未保存的临时标签页(如
Untitled-1)不会触发任何用户片段 - 全局片段放在
common.code-snippets里,但没加"scope": "javascript"字段,结果在 .js 文件里也不出现
prefix 和 body 的写法容错率极低
prefix 看似简单,实则严格:必须是纯字符串、不能含空格或特殊符号、大小写敏感。而 body 表面是数组,实际每项都得是独立字符串,靠数组元素换行,不是靠 \n。
-
"prefix": "console.log"❌ —— VS Code 不支持带点号的触发词,只认log或cl -
"body": "console.log($1);\n$0"❌ —— 必须写成["console.log($1);", "$0"] -
"body": ["function $1() {", " $0", "}"]✅ —— 缩进用空格/制表符写死在字符串里,\t不会被自动识别为缩进 -
$1和${1:default}行为不同:后者首次 Tab 会选中 default 文本,前者只是光标停靠点
scope 字段不是可选项,而是生效开关
很多人以为不写 scope 就是“全局可用”,其实不然。全局片段(common.code-snippets)默认作用域是空,等价于 "scope": "",只在 languageId 为空的上下文中触发——也就是几乎从不触发。
- 想让片段在 .ts 和 .tsx 文件都生效,必须写
"scope": "typescript,typescriptreact"(注意:不是tsx,也不是typescript,tsx) - 查当前真实 languageId:按
Ctrl+Shift+P→ 输入Developer: Inspect Editor Tokens and Scopes→ 看弹窗里languageId字段值 -
"scope": "javascript, typescript"❌ —— 逗号后有空格会导致整个字段失效,VS Code 静默忽略 - 工作区级片段放
.vscode/snippets/javascript.json,比 global + scope 更可靠,尤其适合项目专用结构(如rc生成 React 组件)
变量不是万能的,依赖上下文才有效
$TM_FILENAME_BASE、$CLIPBOARD、$TM_SELECTED_TEXT 这些变量看着方便,但各自有硬性前提,写错一个字母或用错时机就返回空字符串。
-
$TM_FILENAME_BASE在未保存文件中为空,只有已保存的foo.js才展开为foo -
$TM_SELECTED_TEXT必须先选中文本再触发片段,否则插入空字符串;用于包裹操作(如加try/catch)时很实用,但不能当通用变量用 -
$CLIPBOARD在 macOS 上有时权限受限,Linux 下可能依赖 xclip,Windows 一般稳定 - 所有变量必须用大括号包裹:
${TM_FILENAME_BASE}✅,$TM_FILENAME_BASE❌
真正卡住人的从来不是语法多难,而是 VS Code 对 JSON 格式、languageId、文件状态这些条件的静默容忍——它不报错,只沉默跳过。每次改完,务必用已保存的对应类型文件实测,别信“应该可以”。











