NextJS 使用 s-s-r 和 Styled-Components 构建错误

Posted

技术标签:

【中文标题】NextJS 使用 s-s-r 和 Styled-Components 构建错误【英文标题】:NextJS Build Errors with s-s-r and Styled-Components 【发布时间】:2021-06-13 13:36:43 【问题描述】:

我正在将 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(如上所示)以支持 styled-components 和 styled-jsx(我没有使用后者,这是 NextJS 的依赖部分,也是错误的来源) 尝试在本地构建(使用 npm run build 构建就好了) 检查 index.tsx 和 _app.tsx 中是否存在窗口对象 在任何组件中调用 fetch 之前检查 window.fetch 是否存在 注释掉了带有危险SetInnerhtml 的渲染 iFrame

我还没有考虑什么?

【问题讨论】:

【参考方案1】:

您可以使用此示例测试您的 _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>
    )
  

【讨论】:

您在 Next JS 中使用 styled-components 是否遇到任何问题?我的意思是 SEO 的问题。【参考方案2】:

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

【讨论】:

以上是关于NextJS 使用 s-s-r 和 Styled-Components 构建错误的主要内容,如果未能解决你的问题,请参考以下文章

在 NextJS、nginx 和 Material-ui(s-s-r) 中使用 CSP

Apollo 中 NextJs s-s-r 和 cookie 的问题

在 NextJs s-s-r 中操作 DOM onClick

NextJS 上的 s-s-r 是如何工作的?

使用 NextJS 用 Class Components 和 getInitialProps 做 s-s-r,render 方法有未定义的数据

带有 Lerna + React + Styled 组件的 s-s-r