记一次迁移到Shiki的尝试
Apr 30, 2024
从写前端开始,我使用的语法高亮器一直是highlight.js,包括这个博客;但是,随着我将博客的CSS框架迁移到Tailwind CSS后,适配highlight.js时遇到了大大小小很多问题,之前写的代码也屎,就决定弃用了。看到了antfu老师的这篇博客了解到了Shiki,文档写的十分详细,支持很多现代新框架,便有了这次尝试。
此博客数据源是Markdown,加载MDX数据我使用的是next-mdx-remote,其中主要使用到<MDXRemote />
组件:
function MDXComponent({ source }) {
return (
<MDXRemote
{...source} // MDX Content
components={components} // Custom Components
/>
);
}
不像mdx-bundler那样可以在MDX中使用import
导入组件,next-mdx-remote则需要我们自己解析:
const components = {
pre: (props) => <Codeblock {...props} />,
//...
};
Shiki提供了Rehype插件,可直接传入<MDXRemote />
中:
function MDXComponent({ source }) {
return (
<MDXRemote
{...source}
components={components}
options={{
mdxOptions: {
rehypePlugins: [
[
rehypeShiki,
{
themes: {
light: "github-light",
dark: "github-dark",
},
//添加'language-*'到class中,可以用来在代码块中显示语言种类
addLanguageClass: true,
},
],
],
},
}}
/>
);
}
完成了这些,就可以去<Codeblock />
打印出接收到的props看看:
可以看到Shiki已经生效了,可以在组件内拿到'language-jsx'
,children是React Element可以直接丢到JSX中。
最后是对深色模式的支持:在前面的themes
选项中我们已经指定了light
、dark
两个主题,相应的样式已经已经挂在了标签上了:
在css中添加一些内容,使这些样式能响应深浅色模式:
html.dark .codeblock span {
color: var(--shiki-dark) !important;
}