Shiki 是 Astro 内置的语法高亮引擎。它和高亮库的常见做法有个根本区别:在构建阶段把代码切成带颜色的 HTML 片段,而不是在浏览器里跑解析器。
双主题是怎么工作的
配置是这样:
shikiConfig: {
themes: { light: 'github-light', dark: 'github-dark-dimmed' },
defaultColor: false,
}
defaultColor: false 是关键。它让 Shiki 把两套配色都写成 CSS 变量,同时挂在代码块上:
<pre class="astro-code" style="--shiki-light:#24292e; --shiki-dark:#adbac7;">
然后样式表按当前主题二选一。结果是切换深色模式不需要重新下载任何东西,也不会有颜色闪一下。
行号与高亮行
Astro 的代码围栏可以带额外参数:
```ts title="src/app.ts" showLineNumbers {3,7-9}
这些参数由自定义的 transformer 解析:
| 写法 | 效果 |
|---|---|
title="..." | 代码块上方显示一条文件名栏 |
showLineNumbers 或 ln | 左侧显示行号 |
{3,7-9} | 指定行加高亮底色 |
实现的关键是 transformer 提供两个钩子:pre(node) 处理整个代码块,line(node, lineNumber) 逐行处理。只在 pre 里做行高亮是个典型错误,因为那个钩子拿不到每一行。
为什么不引第三方高亮库
Astro 自带 Shiki,额外装 highlight.js 或 Prism 只是多一份需要维护的依赖,还多一份样式要覆盖。少一个依赖,少一类问题。
代价
因为高亮发生在构建阶段,构建产物里每种语言都会多出一份对应的 HTML 结构,
dist/会变大一些。换来的是浏览器不需要执行任何高亮脚本。