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(如上所示)以支持 styled-components 和 styled-jsx(我不使用后者,这是 NextJS 的依赖部分和错误来源)
- 尝试在本地构建(使用
npm run build
构建得很好)
- 检查 window 对象是否存在于 index.tsx 和 _app.tsx
中
- 在任何组件中调用
fetch
之前检查是否存在 window.fetch
- 注释掉带有 dangerouslySetInnerHTML 的渲染 iFrame
我还没有考虑到什么?
您可以使用此示例测试您的 _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 解决了这个问题。
我正在将 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
构建得很好) - 检查 window 对象是否存在于 index.tsx 和 _app.tsx 中
- 在任何组件中调用
fetch
之前检查是否存在 window.fetch - 注释掉带有 dangerouslySetInnerHTML 的渲染 iFrame
我还没有考虑到什么?
您可以使用此示例测试您的 _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 解决了这个问题。