NextJS 使用 SSR 和样式化组件构建错误

NextJS Build Errors with SSR and Styled-Components

我正在将 NextJS 应用程序部署到 Vercel 并使用 styled-components。这是我的 _document.tsx 文件:

import Document from 'next/document'
import { ServerStyleSheet } from 'styled-components'
import flush from 'styled-jsx/server'

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const sheet = new ServerStyleSheet()
    const originalRenderPage = ctx.renderPage

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) =>
            sheet.collectStyles(<App {...props} />),
        })

      const initialProps = await Document.getInitialProps(ctx)
      const styledJSXStyles = flush()
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
            {styledJSXStyles}
          </>
        ),
      }
    } finally {
      sheet.seal()
    }
  }
}

我从 Vercel 看到的错误是 document is not defined at new StyleSheet:

02:22:23    > Build error occurred
02:22:23    ReferenceError: document is not defined
02:22:23        at new StyleSheet (/vercel/workpath0/node_modules/styled-jsx/dist/lib/stylesheet.js:40:35)
02:22:23        at new StyleSheetRegistry (/vercel/workpath0/node_modules/styled-jsx/dist/stylesheet-registry.js:26:33)
02:22:23        at Object.<anonymous> (/vercel/workpath0/node_modules/styled-jsx/dist/style.js:15:26)
02:22:23        at Module._compile (internal/modules/cjs/loader.js:1063:30)
02:22:23        at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
02:22:23        at Module.load (internal/modules/cjs/loader.js:928:32)
02:22:23        at Function.Module._load (internal/modules/cjs/loader.js:769:14)
02:22:23        at Module.require (internal/modules/cjs/loader.js:952:19)
02:22:23        at require (internal/modules/cjs/helpers.js:88:18)
02:22:23        at Object.<anonymous> (/vercel/workpath0/node_modules/styled-jsx/dist/server.js:9:14)
02:22:23        at Module._compile (internal/modules/cjs/loader.js:1063:30)
02:22:23        at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
02:22:23        at Module.load (internal/modules/cjs/loader.js:928:32)
02:22:23        at Function.Module._load (internal/modules/cjs/loader.js:769:14)
02:22:23        at Module.require (internal/modules/cjs/loader.js:952:19)
02:22:23        at require (internal/modules/cjs/helpers.js:88:18)

我假设在我的文档文件中使用 SeverStyleSheet 会解决这个问题,但事实似乎并非如此。

以下是我尝试过的方法:

我还没有考虑到什么?

您可以使用此示例测试您的 _document.tsx:

import React from 'react'
import Document, {
  DocumentContext,
  DocumentInitialProps,
  Head,
  Html,
  Main,
  NextScript
} from 'next/document'
import { ServerStyleSheet } from 'styled-components'

export default class MyDocument extends Document {
  static async getInitialProps(
    ctx: DocumentContext
  ): Promise<DocumentInitialProps> {
    const sheet = new ServerStyleSheet()
    const originalRenderPage = ctx.renderPage

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: App => props => sheet.collectStyles(<App {...props} />)
        })

      const initialProps = await Document.getInitialProps(ctx)
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        )
      }
    } finally {
      sheet.seal()
    }
  }

  render(): JSX.Element {
    return (
      <Html lang="en">
        <Head>
          <title>your app title</title>
          <meta charSet="utf-8" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

事实证明问题出在旧版本的 NextJS 上,将我的版本从 10.0.6 升级到 10.0.9 解决了这个问题。