Back

Next.js 系列 07:客户端组件的传染性

Published on 17th October 2024

结论

在客户端组件中,除以 props 获取到的 RSC 以外,都会成为客户端组件。

我们继续使用代码高亮 highlight.js 来举证。

// app/code-highlight.jsx
 
import hljs from "highlight.js/lib/core";
import javascript from "highlight.js/lib/languages/javascript";
import "highlight.js/styles/github-dark.css";
 
hljs.registerLanguage("javascript", javascript);
 
const code = "console.log('Hello world')";
const highlightedCode = hljs.highlight(code, {
  language: "javascript",
}).value;
 
export function CodeHighlight() {
  return (
    <pre>
      <code dangerouslySetInnerHTML={{ __html: highlightedCode }}></code>
    </pre>
  );
}
// app/client-wrapper.jsx
 
"use client";
 
import { CodeHighlight } from "./code-highlight";
 
export function ClientWrapper() {
  return <CodeHighlight />;
}
// app/page.jsx
 
import { ClientWrapper } from "./client-wrapper";
 
export default function Home() {
  return <ClientWrapper />;
}
 

对上面代码作简要说明。CodeHighlight 是一个服务器组件,ClientWrapper 是一个客户端组件,在 page 中引入 ClientWrapper

使用 @next/bundle-analyzer 来观察打包后的客户端代码。

img

可以看到,highlight.js 的 JavaScript 依然被打包到了客户端。

我们将 CodeHighlight 在 page 中引入,作为 ClientWrapper 的 children props,变更后的代码如下:

// app/page.jsx
 
import { ClientWrapper } from "./client-wrapper";
import { CodeHighlight } from "./code-highlight";
 
export default function Home() {
  return (
    <ClientWrapper>
      <CodeHighlight />
    </ClientWrapper> 
 
    // 等价于 <ClientWrapper children={<CodeHighlight />} />
  );
}
"use client";
 
export function ClientWrapper({ children }) {
  return children;
}

CodeHighlight 保持不变。再次使用 @next/bundle-analyzer 来观察打包后的客户端代码。

img

highlight.js 的 JavaScript 不再被打包到客户端。

如果你想将 Page Router 的 Next.js 项目迁移到 App Router,并使用 RSC,可以渐进式迁移,在最外层添加 use client,然后一层一层剥离它。

🎉

PixZip 是一款简单易用的图片压缩软件,可以批量压缩图像到指定文件夹,支持 JPG、PNG、WebP、GIF 和 AVIF 格式。现在购买使用折扣码 G1MDK4NW 立享 50% 折扣,仅需 $4.95 即可入手。

立即购买

你的支持是我写作的动力❤️