Nextjs:由 Prismjs 突出显示的服务器渲染代码块不匹配,并由于 class 属性上的前导空格而导致重新渲染
Nextjs: server rendered code blocks highlighted by Prismjs mismatches and causes re-render due to leading whitespace on class attribute
我正在尝试使用 Prismjs 实现语法突出显示(标记化)代码块的服务器端渲染(注意:我知道如何通过 useEffect
和 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
– 但仅当 运行ning next dev
, 而不是 运行ning next build && next start
.
已在最新版本的 Nextjs 和 Prism 上进行测试。
我从 Prismjs
source code:
中得到了答案
if (parent && parent.nodeName.toLowerCase() === 'pre') {
parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
}
这就是空格的来源。很明显,为什么它在这里(作为字符串连接的填充)。
一个临时的 hacky 修复是在 <pre>
元素的 className
中添加一个前导空格。
<pre
data-language={language}
className={` language-${language}`}
>
但很明显,这不是使用Prismjs
SSR的好方法。
我正在尝试使用 Prismjs 实现语法突出显示(标记化)代码块的服务器端渲染(注意:我知道如何通过 useEffect
和 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
– 但仅当 运行ning next dev
, 而不是 运行ning next build && next start
.
已在最新版本的 Nextjs 和 Prism 上进行测试。
我从 Prismjs
source code:
if (parent && parent.nodeName.toLowerCase() === 'pre') {
parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
}
这就是空格的来源。很明显,为什么它在这里(作为字符串连接的填充)。
一个临时的 hacky 修复是在 <pre>
元素的 className
中添加一个前导空格。
<pre
data-language={language}
className={` language-${language}`}
>
但很明显,这不是使用Prismjs
SSR的好方法。