【问题标题】:NextJS Blank Page in Production Build in Docker OnlyNextJS 仅在 Docker 中的生产构建中的空白页
【发布时间】:2021-12-08 19:14:13
【问题描述】:

我遇到了一个刚刚开始的问题,该问题于 2021 年 12 月 7 日(美国东部标准时间)中午左右开始。我在 Docker 容器中部署了 NextJS 应用程序。现在,从容器内部以生产模式部署此应用程序会在浏览器控制台中显示空白页面和 React minify 错误(更多详细信息见下文)。

在昨天之前我没有遇到过这样的问题。

在 AWS EC2 实例和我的本地计算机上运行的 Docker 容器中可以重现此问题。在使用 npm run dev 进行本地开发期间,也没有在 docker 容器外运行 npm run build && npm run start 时显示错误。一切都在我的本地开发环境中开发、构建和显示。

在 docker 容器中,我可以正常运行项目并使用 npm run dev 加载页面,但错误似乎是特定于 生产构建 inside 这个 Docker 容器。这是 Dockerfile 配置:

# Install dependencies only when needed
FROM node:14-buster-slim AS deps

WORKDIR /app
COPY package.json ./

RUN apt-get update && apt-get install -y g++ make cmake python

RUN npm install --frozen-lockfile

# clean up any extra apt packages to save on space
RUN apt-get remove -y g++ make cmake python
RUN apt autoremove -y

# Rebuild the source code only when needed
FROM node:14-buster-slim AS builder
WORKDIR /app
COPY . .
COPY --from=deps /app/node_modules ./node_modules
RUN apt-get update && apt-get install -y g++ make cmake python
RUN npm run build && npm install --production --ignore-scripts --prefer-offline

# clean up any extra apt packages to save on space
RUN apt-get remove -y g++ make cmake python
RUN apt autoremove -y

# Production image, copy all the files and run next
FROM node:14-buster-slim AS runner
WORKDIR /app

# install cron and curl for the expiringCertificates cron job
RUN apt-get update && apt-get -y install cron curl

# make a folder where the cron job can store cookies as text files (see expiringCertificatesCron.sh for reference)
RUN mkdir /app/cron

# Copy cron files to the cron.d directory
COPY --from=builder /app/cron/expiringCertificatesCron /etc/cron.d/expiringCertificatesCron
COPY --from=builder /app/cron/expiringCertificatesCron.sh /app/cron/expiringCertificatesCron.sh

# modify permissions of both cron files to ensure they can be used properly
RUN chmod 0644 /etc/cron.d/expiringCertificatesCron
RUN chmod +x /app/cron/expiringCertificatesCron.sh

# apply the cron job
RUN crontab /etc/cron.d/expiringCertificatesCron

# Create the log file for cron to be able to run tail
RUN touch /var/log/cron.log

ENV NODE_ENV production

COPY --from=builder /app/next.config.js ./
COPY --from=builder /app/.env.production.local ./
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json

EXPOSE 3000

ENV PORT 3000

CMD ["sh", "-c", "cron && node_modules/.bin/next start"]

我在东部标准时间中午左右重新构建并部署到生产环境时发现了这个问题,并且惊讶地看到一个没有标题的空白站点、我的一些深灰色 css 样式以及浏览器控制台中的以下错误。

main-deb592798b94b511.js:1 Error: Minified React error #200; visit https://reactjs.org/docs/error-decoder.html?invariant=200 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
    at Object.t.hydrate (framework-8957c350a55da097.js:1)
    at d.default.createElement.callbacks (main-deb592798b94b511.js:1)
    at xe (main-deb592798b94b511.js:1)
    at main-deb592798b94b511.js:1
    at s (main-deb592798b94b511.js:1)
    at Generator._invoke (main-deb592798b94b511.js:1)
    at Generator.S.forEach.e.<computed> [as next] (main-deb592798b94b511.js:1)
    at L (main-deb592798b94b511.js:1)
    at i (main-deb592798b94b511.js:1)
    at main-deb592798b94b511.js:1
ye @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
s @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
S.forEach.e.<computed> @ main-deb592798b94b511.js:1
L @ main-deb592798b94b511.js:1
i @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
de @ main-deb592798b94b511.js:1
ve @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
s @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
S.forEach.e.<computed> @ main-deb592798b94b511.js:1
L @ main-deb592798b94b511.js:1
i @ main-deb592798b94b511.js:1
Promise.then (async)
L @ main-deb592798b94b511.js:1
i @ main-deb592798b94b511.js:1
Promise.then (async)
L @ main-deb592798b94b511.js:1
i @ main-deb592798b94b511.js:1
Promise.then (async)
L @ main-deb592798b94b511.js:1
i @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
he @ main-deb592798b94b511.js:1
t.initNext @ main-deb592798b94b511.js:1
2870 @ main-deb592798b94b511.js:1
n @ webpack-cf0a2826ddaf11f3.js:1
(anonymous) @ main-deb592798b94b511.js:1
n.O @ webpack-cf0a2826ddaf11f3.js:1
(anonymous) @ main-deb592798b94b511.js:1
t @ webpack-cf0a2826ddaf11f3.js:1
(anonymous) @ main-deb592798b94b511.js:1

main-deb592798b94b511.js:1 A client-side exception has occurred, see here for more info: https://nextjs.org/docs/messages/client-side-exception-occurred
ye @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
s @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
S.forEach.e.<computed> @ main-deb592798b94b511.js:1
L @ main-deb592798b94b511.js:1
i @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
de @ main-deb592798b94b511.js:1
ve @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
s @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
S.forEach.e.<computed> @ main-deb592798b94b511.js:1
L @ main-deb592798b94b511.js:1
i @ main-deb592798b94b511.js:1
Promise.then (async)
L @ main-deb592798b94b511.js:1
i @ main-deb592798b94b511.js:1
Promise.then (async)
L @ main-deb592798b94b511.js:1
i @ main-deb592798b94b511.js:1
Promise.then (async)
L @ main-deb592798b94b511.js:1
i @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
he @ main-deb592798b94b511.js:1
t.initNext @ main-deb592798b94b511.js:1
2870 @ main-deb592798b94b511.js:1
n @ webpack-cf0a2826ddaf11f3.js:1
(anonymous) @ main-deb592798b94b511.js:1
n.O @ webpack-cf0a2826ddaf11f3.js:1
(anonymous) @ main-deb592798b94b511.js:1
t @ webpack-cf0a2826ddaf11f3.js:1
(anonymous) @ main-deb592798b94b511.js:1

main-deb592798b94b511.js:1 Uncaught (in promise) Error: Cancel rendering route
    at oe (main-deb592798b94b511.js:1)
    at main-deb592798b94b511.js:1
    at new Promise (<anonymous>)
    at xe (main-deb592798b94b511.js:1)
    at main-deb592798b94b511.js:1
oe @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
xe @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
Promise.then (async)
(anonymous) @ main-deb592798b94b511.js:1
Promise.then (async)
ye @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
s @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
S.forEach.e.<computed> @ main-deb592798b94b511.js:1
L @ main-deb592798b94b511.js:1
i @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
de @ main-deb592798b94b511.js:1
ve @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
s @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
S.forEach.e.<computed> @ main-deb592798b94b511.js:1
L @ main-deb592798b94b511.js:1
i @ main-deb592798b94b511.js:1
Promise.then (async)
L @ main-deb592798b94b511.js:1
i @ main-deb592798b94b511.js:1
Promise.then (async)
L @ main-deb592798b94b511.js:1
i @ main-deb592798b94b511.js:1
Promise.then (async)
L @ main-deb592798b94b511.js:1
i @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
(anonymous) @ main-deb592798b94b511.js:1
he @ main-deb592798b94b511.js:1
t.initNext @ main-deb592798b94b511.js:1
2870 @ main-deb592798b94b511.js:1
n @ webpack-cf0a2826ddaf11f3.js:1
(anonymous) @ main-deb592798b94b511.js:1
n.O @ webpack-cf0a2826ddaf11f3.js:1
(anonymous) @ main-deb592798b94b511.js:1
t @ webpack-cf0a2826ddaf11f3.js:1
(anonymous) @ main-deb592798b94b511.js:1

framework-8957c350a55da097.js:1 Uncaught (in promise) Error: Minified React error #200; visit https://reactjs.org/docs/error-decoder.html?invariant=200 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
    at Object.t.hydrate (framework-8957c350a55da097.js:1)
    at d.default.createElement.callbacks (main-deb592798b94b511.js:1)
    at xe (main-deb592798b94b511.js:1)
    at main-deb592798b94b511.js:1

我可以在Network选项卡中看到所有缩小的JS文件下载成功,并且在服务器控制台中没有错误。这是空白站点的 DOM(我可以看到它试图加载我的 FullPageLoader 组件,但实际上没有显示任何内容):

Blank DOM

这是我的package.json

{
  "name": "website",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "cross-env NODE_OPTIONS='--inspect' next dev",
    "build": "next build --debug",
    "start": "next start",
    "lint": "next lint",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:coverage": "jest --coverage"
  },
  "dependencies": {
    "aws-sdk": "^2.1021.0",
    "bcrypt": "^5.0.1",
    "cookie": "^0.4.1",
    "jsonwebtoken": "^8.5.1",
    "next": "^12.0.2",
    "node-ssh": "^12.0.0",
    "nodemailer": "^6.7.0",
    "react": "17.0.2",
    "react-dom": "^17.0.2",
    "react-hook-form": "^7.16.1",
    "react-icons": "^4.2.0",
    "react-router-dom": "^5.3.0",
    "sass": "^1.38.0",
    "serverless-mysql": "^1.5.4",
    "swr": "^0.5.6",
    "uuid": "^8.3.2"
  },
  "devDependencies": {
    "@babel/core": "^7.15.0",
    "@babel/preset-typescript": "^7.15.0",
    "@testing-library/jest-dom": "^5.14.1",
    "@testing-library/react": "^12.0.0",
    "@types/bcrypt": "^5.0.0",
    "@types/cookie": "^0.4.1",
    "@types/jest": "^27.0.1",
    "@types/jsonwebtoken": "^8.5.5",
    "@types/node": "^16.6.1",
    "@types/nodemailer": "^6.4.4",
    "@types/react": "17.0.18",
    "@types/react-dom": "^17.0.9",
    "@types/react-router-dom": "^5.3.1",
    "@types/ssh2": "^0.5.48",
    "@types/uuid": "^8.3.3",
    "@typescript-eslint/eslint-plugin": "^4.29.1",
    "@typescript-eslint/parser": "^4.29.1",
    "babel-jest": "^27.0.6",
    "cross-env": "^7.0.3",
    "eslint": "^7.32.0",
    "eslint-config-airbnb": "^18.2.1",
    "eslint-config-next": "11.1.0",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-import": "^2.24.0",
    "eslint-plugin-jsx-a11y": "^6.4.1",
    "eslint-plugin-prettier": "^3.4.0",
    "eslint-plugin-react": "^7.24.0",
    "eslint-plugin-react-hooks": "^4.2.0",
    "jest": "^27.0.6",
    "jest-environment-jsdom": "^27.0.6",
    "prettier": "^2.3.2",
    "ts-jest": "^27.0.4",
    "typescript": "4.3.5"
  },
  "description": "This is a [React.js](https://reactjs.org/) project using the [Next.js](https://nextjs.org/) framework to help with routing, rendering, and more. For styling the project includes [Sass](https://sass-lang.com/) to add superpowers to our CSS.",
  "main": ".eslintrc.js",
  "repository": {
    "type": "git",
    "url": "<hidden>"
  },
  "keywords": [
    ""
  ],
  "author": "<hidden>",
  "license": "ISC"
}

注意:回滚到以前的工作提交会产生相同的问题。

我必须放弃的唯一提示是,在失败的部署中,我在构建项目时开始看到以下 postcss 弃用警告,在昨天之前我没有看到此警告:

> next build

info  - Loaded env from /app/.env.production.local
Attention: Next.js now collects completely anonymous telemetry regarding usage.
This information is used to shape Next.js' roadmap and prioritize features.
You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
https://nextjs.org/telemetry

info  - Skipping validation of types...
info  - Creating an optimized production build...
postcss-resolve-url: postcss.plugin was deprecated. Migration guide:
https://evilmartians.com/chronicles/postcss-8-plugin-migration
postcss-resolve-url: postcss.plugin was deprecated. Migration guide:
https://evilmartians.com/chronicles/postcss-8-plugin-migration

没有任何方法可以在生产版本中正确调试,我不确定是什么导致了缩小错误。任何帮助将不胜感激!

【问题讨论】:

  • 当您禁用 javascript 时,您是否会在浏览器中返回任何内容 - 您是否在渲染 SSR?此外,我从您的屏幕截图&lt;addoninited.. 中看到我们的正文标记之前有一些无效的 html 检查哪个组件生成它并删除它这是否也可能是您的浏览器正在注入的东西,您是否尝试过网络之外的东西,另一个浏览器等?
  • 由于我正在使用内部前端设计系统库,我正在渲染整个应用程序客户端。 (我在 _app.tsx 中有 getInitialProps)。 addoninited 组件是为我的组织在我们的浏览器上安装的内部扩展的结果。我可以验证该站点仍然无法在我尝试过的任何其他设备/浏览器上加载相同的错误。 Desktop Edge 和 Firefox + Mobile/Desktop chrome/Brave
  • 再次查看您的屏幕截图,似乎只生成了_error.. 块,这意味着应用程序正在尝试加载错误页面并且它失败了。我会安装npmjs.com/package/pino 之类的东西,并通过INFO 块记录每个组件的成功,这可以让您看到应用程序的哪些部分成功 - 鉴于没有生成错误,它只是通过 prod 日志记录消除的过程。

标签: reactjs docker npm next.js minify


【解决方案1】:

不幸/幸运的是,在大约 12 月 15 日更新 NPM 软件包后,问题自行解决了。只能假设一个包引起了问题,将所有包更新到最新版本即可解决问题。

【讨论】:

    猜你喜欢
    • 2015-11-18
    • 1970-01-01
    • 2020-10-17
    • 1970-01-01
    • 1970-01-01
    • 2021-01-13
    • 1970-01-01
    • 2020-01-25
    • 1970-01-01
    相关资源
    最近更新 更多