这是我们仅在多个节点上运行时才会出现的问题。
我们的应用程序托管在 AWS ECS docker 容器上,并附有由应用程序负载均衡器管理的 Auto Scaling 组。
NextJs 应用程序仅在一个节点上运行时运行良好。但为了确保高可用性,我们需要从多个节点提供服务器。由于它有多个构建ID,我们在
next.config.js
文件中添加了以下配置
const nextConfig = {
generateBuildId: async () => "default-build",
experimental: {
isrMemoryCacheSize: 0,
},
};
module.exports = nextConfig;
浏览器控制台错误日志如下
Failed to load resource: the server responded with a status of 404(Not Found)
ChunkLoadError: Loading chunk 84 failed.
(error: http://replaced-this-url/_next/static/chunks/app/%5Blang%5D/layout-332c238ae51cc7a7.js)
at d.f.j(webpack - 8b6d851d58492f7f.js: 1: 3285)
at webpack - 8b6d851d58492f7f.js: 1: 1427
at Array.reduce(<anonymous>)
at d.e (webpack-8b6d851d58492f7f.js:1:1393)
at self.__next_chunk_load__ (488-4c8bbce90f9d2c06.js:1:3713)
at 488-4c8bbce90f9d2c06.js:9:5403
at 488-4c8bbce90f9d2c06.js:9:5813
at N (488-4c8bbce90f9d2c06.js:9:6016)
at t (488-4c8bbce90f9d2c06.js:9:8912)
Uncaught Error: Minified React error #423; visit https://reactjs.org/docs/error-decoder.html?invariant=423 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
at iv (2443530c-01613f55fe4aacb8.js:9:113059)
at oR (2443530c-01613f55fe4aacb8.js:9:90030)
at 2443530c-01613f55fe4aacb8.js:9:89879
at oD (2443530c-01613f55fe4aacb8.js:9:89886)
at ow (2443530c-01613f55fe4aacb8.js:9:87588)
at ok (2443530c-01613f55fe4aacb8.js:9:86450)
at E (488-4c8bbce90f9d2c06.js:25:1398)
at MessagePort.C (488-4c8bbce90f9d2c06.js:25:1951)
ChunkLoadError: Loading chunk 84 failed.
(error: http://replaced-this-url/_next/static/chunks/app/%5Blang%5D/layout-332c238ae51cc7a7.js)
at d.f.j (webpack-8b6d851d58492f7f.js:1:3285)
at webpack-8b6d851d58492f7f.js:1:1427
at Array.reduce (<anonymous>)
at d.e (webpack-8b6d851d58492f7f.js:1:1393)
at self.__next_chunk_load__ (488-4c8bbce90f9d2c06.js:1:3713)
at 488-4c8bbce90f9d2c06.js:9:5403
at 488-4c8bbce90f9d2c06.js:9:5813
at N (488-4c8bbce90f9d2c06.js:9:6016)
at t (488-4c8bbce90f9d2c06.js:9:8912)
window.console.error @ 488-4c8bbce90f9d2c06.js:1
Uncaught (in promise) Error: A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received
我知道启用粘性可以解决这个问题。但由于这是一个静态 Web 应用程序,因此这不是最佳实践,因为我们需要确保负载平衡。因此,应该从应用程序逻辑方面对问题进行排序
Dockerfile
ARG base_image_build="node:18.17.1"
ARG base_image_run="node:18.17.1-slim"
FROM ${base_image_build} AS builder
WORKDIR /opt/app
COPY . .
RUN yarn install --frozen-lockfile --production
FROM ${base_image_run} AS runner
ENV NODE_ENV=production
USER node
WORKDIR /opt/app
COPY --chown=node:node --from=builder /opt/app /opt/app
COPY --chown=node:node --from=builder /opt/app/node_modules ./node_modules
CMD ["yarn", "docker"]
yarn docker
:yarn build && yarn start
在容器启动中构建应用程序时,它会为具有不同工件的每个节点生成不同的 .next 文件夹,导致这种分离导致块未找到错误。在 webpack 配置中重命名客户端的文件名和块将能够在所有构建中保留相同的工件,这将有助于解决找不到块的问题。在
next.config.js
上添加以下内容解决了块加载问题,最终解决了问题。
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
if (!isServer) {
config.output.filename = 'static/chunks/[name].js';
config.output.chunkFilename = 'static/chunks/[name].js';
}
return config;
}