我正在尝试使用 Prismjs 实现语法突出显示(标记化)代码块的服务器端渲染(注意:我知道如何通过useEffect
and使用客户端渲染来做到这一点refs
,并且我使用prism-react-renderer得到了这个工作。我是专门寻找“裸” Prismjs & SSR 的解决方案)。
// codeExamples = array of some code strings
const Code = ({ code, language }) => {
const html = Prism.highlight(code, Prism.languages[language], language);
return (
<pre
data-language={language}
className={`language-${language}`}
>
<code
dangerouslySetInnerHTML={{
__html: html,
}}
/>
</pre>
);
};
export default function Home() {
return codeExamples.map((example, i) => (
<Code
language="javascript"
code={example}
key={i}
></Code>
));
}
它在某种程度上确实有效,但我遇到了一个问题:代码块被短暂地重新渲染,可能是因为属性上的前导空格:class
- 第一次渲染:
class="language-javascript"
- 第二次渲染:
class=" language-javascript
这导致(除了无意义的昂贵重新渲染之外)令人不快的布局偏移,通过向元素添加硬编码font-size
像素来临时修复<pre>
。
我偶尔会收到一些警告,要么是服务器和客户端道具不匹配(现在无法重现),要么是Extra attributes from the server: class
——但仅在运行时next dev
,而不是在运行时next build && next start
。
在最新版本的 Nextjs 和 Prism 上测试。