Slidev 代码高亮配置详解:用 setup/shiki.ts 定制 Shiki 主题、语言与 Transformer

发布时间:2026/9/6 17:43:42
Slidev 代码高亮配置详解:用 setup/shiki.ts 定制 Shiki 主题、语言与 Transformer Slidev 代码高亮配置详解用 setup/shiki.ts 定制 Shiki 主题、语言与 Transformer【免费下载链接】slidevPresentation Slides for Developers项目地址: https://gitcode.com/GitHub_Trending/sl/slidevSlidev 内置的代码高亮由 Shiki 驱动一份setup/shiki.ts文件即可掌控所有代码块的主题、语言与 token 转换行为。本文基于 Slidev 官方文档《Configure Highlighter》(docs/custom/config-highlighter.md) 展开逐条讲清配置项的写法与取值并深入源码核实这些选项在客户端与 Node 端是如何被解析、合并与消费的帮助你在主题开发和幻灯片项目中精确控制代码块渲染。为什么是 ShikiSlidev 选择 Shiki 作为代码高亮器见文档原文说明它有三个对幻灯片场景至关重要的特性TextMate Grammar 驱动与 VS Code 同等精准Shiki 解析的是与 VS Code 相同的 TextMate 文法因此高亮结果与你在编辑器中看到的一致不会出现 Prism 一类正则高亮器在嵌套泛型、模板字符串等场景下的误判直接生成带色的 token无需额外 CSS高亮结果在构建期/运行期就内联为带颜色样式的 HTML不依赖运行时注入的样式表这对 Slidev 的导出PDF、图片快照与 PWA 场景尤为重要内置丰富的主题库可以直接按名称引用 Shiki 内置主题如min-dark、vitesse-dark等也可以在需要时加载自定义主题。此外Slidev 在 Shiki 之上还提供了 TwoSlash 集成代码块中未定义的变量会以红色波浪线标注把代码演示与类型检查合二为一这是文档中专门点名的增强能力。快速开始创建 setup/shiki.ts在项目根目录或主题根目录创建./setup/shiki.ts用slidev/types导出的defineShikiSetup包裹一个返回配置对象的函数import { defineShikiSetup } from slidev/types export default defineShikiSetup(() { return { themes: { dark: min-dark, light: min-light, }, transformers: [ // ... ], } })三个关键配置项配置项类型说明themesRecordstring, 主题名 \| 主题对象多主题映射。键可以是任意名称约定为dark/light代码块会根据当前暗/亮模式选择对应主题渲染langs(内置语言名 \| 文法对象)[]或Recordstring, 语言输入声明代码块需要用到的语言可混用内置语言字符串与自定义 TextMate 文法transformersShiki transformers 数组对生成的 HTML token 做二次加工行内高亮样式、行号、边框等来自 Shiki 生态defineShikiSetup本身只是一个类型断言辅助函数见 packages/types/src/setups.tsfunction defineSetupFn(fn: Fn) { return fn } export const defineShikiSetup defineSetupShikiSetup真正有价值的是它约束的返回类型ShikiSetupReturnpackages/types/src/setups.ts#L56-L64它是 Shiki 的CodeToHastOptionsCommon剔除lang字段、CodeOptionsThemes、CodeOptionsMeta与langs字段的Partial交叉——也就是说除了上述三项Shiki 高亮 API 的其他通用选项如defaultColor、mergeOptions等同样可以透传并能在编辑器中获得类型补全。自定义主题与语言导入 TextMate JSON要添加 Shiki 未内置的主题或语言把它们以 TextMate 格式的 JSON 文件放入项目如customTheme.tmTheme.json、customLanguage.tmLanguage.json然后在 setup 文件中直接导入import { defineShikiSetup } from slidev/types // ts-expect-error missing types import customLanguage from ./customLanguage.tmLanguage.json // ts-expect-error missing types import customTheme from ./customTheme.tmTheme.json export default defineShikiSetup(() { return { themes: { dark: customTheme, light: min-light, }, langs: [ js, typescript, cpp, customLanguage, // ... ], transformers: [ // ... ], } })要点说明themes的值可以是主题名字符串或原始主题 JSON 对象两者可混用上例dark用对象、light用内置名。对象形式的主题必须带有name字段否则 Slidev 会在控制台警告 does not have a name, which may cause issues.langs的条目同样可以是内置语言名或文法对象内置语言名在 Node 端按需加载、无额外开销但在浏览器环境如浏览器内运行时需要显式声明这一点由源码注释明确说明见下文解析机制文档中引用的ts-expect-error missing types是示例的组成部分仓库未为.json文法文件提供类型声明实际使用时需自行处理类型可用// ts-ignore或本地.d.ts内置语言与主题的完整清单以 Shiki 官方文档为准文档原文指向 shiki.style 的语言/主题列表页。源码解析setup/shiki.ts 是如何被消费与合并的这一节回答这些配置到底影响了什么。Slidev 在客户端与 Node 端各有一条 Shiki 初始化链路二者共用同一个选项合并函数。客户端解析、合并并创建高亮器客户端入口 packages/client/setup/shiki.ts 的流程通过虚拟模块#slidev/setups/shiki收集所有 setup该模块由 Slidev 的 vite 插件按约定路径动态生成见 packages/types/client.d.ts#L43 的模块声明与 packages/slidev/node/virtual/setups.ts#L22 中的setupModules列表其中第一个就是shiki将每个 setup 的返回值统一交给resolveShikiOptions合并用合并结果调用createBundledHighlightershiki/core并注入createJavaScriptRegexEngine引擎再通过createSingletonShorthands得到惰性加载的getEagerHighlighter、languageNames、themeNames等单例。合并规则resolveShikiOptions核心逻辑在 packages/client/setup/shiki-options.ts 中值得逐条对照的行为选项浅合并多个 setup 的返回值按Object.assign顺序合并后者的标量字段覆盖前者theme与themes的归一化若同时提供theme和themestheme被丢弃若theme是一个多主题映射对象无name、无tokenColors则被重命名为themes兜底默认主题当既没有theme也没有themes时自动注入themes: { dark: vitesse-dark, light: vitesse-light }packages/client/setup/shiki-options.ts#L28-L34——这就是 Slidev 开箱即见的代码块配色来源defaultColor自动关闭一旦配置了themes会强制defaultColor falsepackages/client/setup/shiki-options.ts#L36-L37使 token 颜色严格跟随所选主题不再叠加默认前景色语言白名单默认始终启用markdown、vue、javascript、typescript、html、css六种语言packages/client/setup/shiki-options.ts#L54你的langs在此基础上追加自定义文法的别名展开当langs条目是文法对象时会注册其name及全部aliases意味着 vue 之类的围栏语言名只要命中别名即可使用该文法packages/client/setup/shiki-options.ts#L71-L79格式校验langs数组中不允许出现函数应改用 record 格式{ [name]: () {...} }非法配置会输出红色console.error报错并忽略该项packages/client/setup/shiki-options.ts#L61-L64。Node 端同一套合并逻辑导 PDF、生成 OG 图等 Node 场景走 packages/slidev/node/setups/shiki.ts通过loadSetups(roots, shiki.ts, ...)加载各入口的setup/shiki.ts复用同一个resolveShikiOptions合并再创建createBundledHighlighter并缓存为{ shiki, shikiOptions }。因此浏览器预览与导出产物的高亮配置天然一致你只需维护一份 setup 文件。另外注意ShikiContext.loadTheme已被标记为废弃packages/types/src/setups.ts#L48-L54——旧写法通过loadTheme(path)加载主题Node 端实现会打印废弃警告客户端实现则直接抛错。替代方案是JSON.parse(fs.readFileSync(path, utf-8))读入原始主题对象后直接传入themes。仓库中的真实配置示例主题模板默认值create-theme脚手架生成的 packages/create-theme/template/setup/shiki.ts 展示了最小配置——只指定vitesse-dark/vitesse-light双主题其余全部依赖默认值import type { ShikiSetupReturn } from slidev/types import { defineShikiSetup } from slidev/types export default defineShikiSetup((): ShikiSetupReturn { return { themes: { dark: vitesse-dark, light: vitesse-light, }, } })显式声明语言清单demo/vue-runner/setup/shiki.ts 只声明了langs: [ts, js, vue, html]用于该演示项目中限定语言范围写法与上文完全一致。TwoSlash 集成与已知限制TwoSlashSlidev 在 Shiki 高亮之上叠加了 TwoSlash 集成见 docs/features/twoslash.md可在代码块中做类型级检查与诊断展示。相关样式入口为 packages/client/styles/shiki-twoslash.css。Magic Move 的限制文档明确提示——Shiki Magic Move代码块间 token 的动画过渡目前不支持 transformers。如果你的代码块使用了 magic move 效果transformers配置对其不生效这是当前版本的已知边界规划动画演示时需先确认是否依赖该特性。Prism 已移除历史迁移提示文档对 Prism 的态度是一句明确警告自 v0.50 起 Prism 支持已被移除请改用 Shiki。如果你的旧项目或旧主题还在通过 frontmatter 声明 Prism 相关配置这些字段已不再生效迁移路径就是按本文方式建立setup/shiki.ts——Shiki 的 TextMate 精准度与主题生态可以完整覆盖 Prism 的能力面。小结与适用前提一个setup/shiki.tsdefineShikiSetup即可声明themes/langs/transformers客户端与 Node 端共用同一份配置与合并逻辑预览和导出表现一致不写任何配置时Slidev 默认使用vitesse-dark/vitesse-light主题并预置markdown、vue、javascript、typescript、html、css六种语言自定义主题/语言直接导入 TextMate JSON 即可注意主题对象必须有name、浏览器环境下建议显式列出所用语言名使用loadTheme的旧代码需要迁移为直接传入主题对象依赖 transformers 的样式在 magic move 代码块上不生效本文基于当前仓库源码核实行号引用对应的实现位置见各小节给出的文件路径可据此继续深入阅读 packages/client/setup/shiki-options.ts 与 packages/slidev/node/setups/shiki.ts。【免费下载链接】slidevPresentation Slides for Developers项目地址: https://gitcode.com/GitHub_Trending/sl/slidev创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考