Next.JS v13在Docker中不遵循路径别名,但在本地工作。

huangapple go评论116阅读模式
英文:

Next.JS v13 in Docker does not respect path alias but works locally

问题

以下是要翻译的部分:

错误:

  1. > [builder 6/6] RUN pnpm run build:
  2. #25 0.534
  3. #25 0.534 > p-stack-fs@0.1.0 build /app
  4. #25 0.534 > next build
  5. #25 0.534
  6. #25 0.940 - 警告:您已启用了next.config.js中的实验性功能(instrumentationHook)。
  7. #25 0.941 - 警告:实验性功能不受semver支持,可能导致意外或破坏的应用程序行为。自行承担风险使用。
  8. #25 0.941
  9. #25 1.010 - 信息 正在创建优化的生产构建...
  10. #25 10.94 编译失败。
  11. #25 10.94
  12. #25 10.95 ./src/app/layout.tsx
  13. #25 10.95 模块未找到:无法解析'~/components/NavBar'
  14. #25 10.95
  15. #25 10.95 https://nextjs.org/docs/messages/module-not-found
  16. #25 10.95
  17. #25 10.95 ./src/app/layout.tsx
  18. #25 10.95 模块未找到:无法解析'~/styles/css'
  19. #25 10.95
  20. #25 10.95 https://nextjs.org/docs/messages/module-not-found
  21. #25 10.95
  22. #25 10.95
  23. #25 10.95 > 构建失败,因为webpack错误
  24. #25 11.09  ELIFECYCLE  命令以退出码1失败。

你可以看到文件存在且命名正确的部分在这里:

Next.JS v13在Docker中不遵循路径别名,但在本地工作。

Dockerfile:

  1. ARG ALPINE_VERSION=3.17
  2. FROM node:20-alpine AS base
  3. # 仅在需要时安装依赖项
  4. FROM base AS deps
  5. # 查看https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine 以了解为什么可能需要libc6-compat。
  6. RUN apk add --no-cache libc6-compat
  7. WORKDIR /app
  8. COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
  9. COPY panda.config.ts ./
  10. RUN npm i -g pnpm && pnpm i --prod --frozen-lockfile
  11. # 仅在需要时重新构建源代码
  12. FROM base AS builder
  13. WORKDIR /app
  14. COPY --from=deps /app/node_modules ./node_modules
  15. COPY . .
  16. # Panda在“prepare”命令中构建,在“install”后运行,因此我们在这里将其复制过来以进行构建
  17. # COPY --from=deps /app/src/styles/ ./src/styles/
  18. RUN ["chmod", "+x", "./docker-entrypoint.sh"]
  19. # Next.js会收集关于一般用法的完全匿名的遥测数据。
  20. # 了解更多信息:https://nextjs.org/telemetry
  21. # 在构建过程中禁用遥测时,请取消下面一行的注释。
  22. ENV NEXT_TELEMETRY_DISABLED 1
  23. RUN npm i -g pnpm
  24. RUN pnpm run build
  25. # 生产镜像,复制所有文件并运行next
  26. FROM alpine:${ALPINE_VERSION} AS runner
  27. WORKDIR /app
  28. # 在运行时禁用遥测时,请取消下面一行的注释。
  29. ENV NEXT_TELEMETRY_DISABLED 1
  30. RUN apk add --no-cache --update nodejs
  31. # 使用Go二进制文件获取AWS SSM参数,减小镜像大小
  32. # 注意:如果不使用USER nextjs,则可能会出现“8: not found”错误,与ca-certificates有关
  33. RUN apk update && apk add --no-cache ca-certificates && update-ca-certificates
  34. RUN wget https://github.com/pthieu/go-aws-get-parameter/raw/master/ssm_get_parameter
  35. RUN ["chmod", "+x", "./ssm_get_parameter"]
  36. RUN addgroup --system --gid 1001 nodejs
  37. RUN adduser --system --uid 1001 nextjs
  38. # 自动利用输出跟踪以减小镜像大小
  39. # https://nextjs.org/docs/advanced-features/output-file-tracing
  40. COPY --from=builder /app/.next/standalone ./
  41. COPY --from=builder /app/public ./public
  42. COPY --from=builder /app/.next/static ./.next/static
  43. # COPY --from=builder /app/src/db/migrations ./migrations
  44. COPY --from=builder --chown=nextjs:nodejs /app/docker-entrypoint.sh ./
  45. USER nextjs
  46. EXPOSE 80
  47. ENV PORT 80
  48. ENTRYPOINT [ "sh", "docker-entrypoint.sh" ]
  49. CMD ["node", "server.js"]
  50. # 用于调试,保持容器处于活动状态
  51. # CMD ["tail", "-f", "/dev/null"]

请注意,Dockerfile和错误消息中可能包含的HTML字符实体已被保留,因为它们是代码的一部分。

英文:

I had a working docker build and when I put in absolute paths with a path alias, it suddenly started complaining module not found, can't resolve 'ComponentName'

It will fail at the pnpm run build step, but when I run it locally, it works fine.

tsconfig.json

  1. {
  2. "compilerOptions": {
  3. "target": "es5",
  4. "lib": [
  5. "dom",
  6. "dom.iterable",
  7. "esnext"
  8. ],
  9. "allowJs": true,
  10. "skipLibCheck": true,
  11. "strict": true,
  12. "forceConsistentCasingInFileNames": true,
  13. "noEmit": true,
  14. "esModuleInterop": true,
  15. "module": "esnext",
  16. "moduleResolution": "node",
  17. "resolveJsonModule": true,
  18. "isolatedModules": true,
  19. "jsx": "preserve",
  20. "incremental": true,
  21. "plugins": [
  22. {
  23. "name": "next"
  24. }
  25. ],
  26. "baseUrl": ".",
  27. "paths": {
  28. "~/*": [
  29. "./src/*"
  30. ]
  31. }
  32. },
  33. "include": [
  34. "next-env.d.ts",
  35. "**/*.ts",
  36. "**/*.tsx",
  37. ".next/types/**/*.ts"
  38. ],
  39. "exclude": [
  40. "node_modules"
  41. ]
  42. }

The file causing the error:

  1. import { Providers } from './providers';
  2. import NavBar from '~/components/NavBar';
  3. import { css } from '~/styles/css';
  4. import './global.css';
  5. export const metadata = {
  6. title: 'p-stack-fs',
  7. description: 'A boilerplate for TypeScript, Next.js, and PostgreSQL',
  8. };
  9. export default function RootLayout({
  10. children,
  11. }: {
  12. children: React.ReactNode;
  13. }) {
  14. return (
  15. <html lang="en">
  16. <body>
  17. <Providers>
  18. <div className={css({ minH: '100vh' })}>
  19. <NavBar />
  20. {children}
  21. </div>
  22. </Providers>
  23. </body>
  24. </html>
  25. );

Error:

  1. > [builder 6/6] RUN pnpm run build:
  2. #25 0.534
  3. #25 0.534 > p-stack-fs@0.1.0 build /app
  4. #25 0.534 > next build
  5. #25 0.534
  6. #25 0.940 - warn You have enabled experimental feature (instrumentationHook) in next.config.js.
  7. #25 0.941 - warn Experimental features are not covered by semver, and may cause unexpected or broken application behavior. Use at your own risk.
  8. #25 0.941
  9. #25 1.010 - info Creating an optimized production build...
  10. #25 10.94 Failed to compile.
  11. #25 10.94
  12. #25 10.95 ./src/app/layout.tsx
  13. #25 10.95 Module not found: Can't resolve '~/components/NavBar'
  14. #25 10.95
  15. #25 10.95 https://nextjs.org/docs/messages/module-not-found
  16. #25 10.95
  17. #25 10.95 ./src/app/layout.tsx
  18. #25 10.95 Module not found: Can't resolve '~/styles/css'
  19. #25 10.95
  20. #25 10.95 https://nextjs.org/docs/messages/module-not-found
  21. #25 10.95
  22. #25 10.95
  23. #25 10.95 > Build failed because of webpack errors
  24. #25 11.09  ELIFECYCLE  Command failed with exit code 1.
  25. ------
  26. executor failed running [/bin/sh -c pnpm run build]: exit code: 1

You can see the files exist and are named properly here:

Next.JS v13在Docker中不遵循路径别名,但在本地工作。

FWIW, here's my Dockerfile

  1. ARG ALPINE_VERSION=3.17
  2. FROM node:20-alpine AS base
  3. # Install dependencies only when needed
  4. FROM base AS deps
  5. # Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
  6. RUN apk add --no-cache libc6-compat
  7. WORKDIR /app
  8. COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
  9. COPY panda.config.ts ./
  10. RUN npm i -g pnpm && pnpm i --prod --frozen-lockfile
  11. # Rebuild the source code only when needed
  12. FROM base AS builder
  13. WORKDIR /app
  14. COPY --from=deps /app/node_modules ./node_modules
  15. COPY . .
  16. # Panda is built in the `prepare` command, which runs after
  17. # `install`, so we copy it over here for building
  18. # COPY --from=deps /app/src/styles/ ./src/styles/
  19. RUN ["chmod", "+x", "./docker-entrypoint.sh"]
  20. # Next.js collects completely anonymous telemetry data about general usage.
  21. # Learn more here: https://nextjs.org/telemetry
  22. # Uncomment the following line in case you want to disable telemetry during the build.
  23. ENV NEXT_TELEMETRY_DISABLED 1
  24. RUN npm i -g pnpm
  25. RUN pnpm run build
  26. # Production image, copy all the files and run next
  27. FROM alpine:${ALPINE_VERSION} AS runner
  28. WORKDIR /app
  29. # Uncomment the following line in case you want to disable telemetry during runtime.
  30. ENV NEXT_TELEMETRY_DISABLED 1
  31. RUN apk add --no-cache --update nodejs
  32. # Get AWS SSM Params using a Go binary, reduces image size
  33. # Note: this might get a "8: not found" error if not using the USER nextjs, has
  34. # to do with something with the ca-certificates
  35. RUN apk update && apk add --no-cache ca-certificates && update-ca-certificates
  36. RUN wget https://github.com/pthieu/go-aws-get-parameter/raw/master/ssm_get_parameter
  37. RUN ["chmod", "+x", "./ssm_get_parameter"]
  38. RUN addgroup --system --gid 1001 nodejs
  39. RUN adduser --system --uid 1001 nextjs
  40. # Automatically leverage output traces to reduce image size
  41. # https://nextjs.org/docs/advanced-features/output-file-tracing
  42. COPY --from=builder /app/.next/standalone ./
  43. COPY --from=builder /app/public ./public
  44. COPY --from=builder /app/.next/static ./.next/static
  45. # COPY --from=builder /app/src/db/migrations ./migrations
  46. COPY --from=builder --chown=nextjs:nodejs /app/docker-entrypoint.sh ./
  47. USER nextjs
  48. EXPOSE 80
  49. ENV PORT 80
  50. ENTRYPOINT [ "sh", "docker-entrypoint.sh" ]
  51. CMD ["node", "server.js"]
  52. # For debugging, keeps container alive
  53. # CMD ["tail", "-f", "/dev/null"]

答案1

得分: 2

Found the issue.

问题已找到。

The solution was to update next.config.js to set the path alias in webpack. This should be the same as your tsconfig.json.

解决方案是更新 next.config.js 来在 webpack 中设置路径别名。这应该与你的 tsconfig.json 相同。

  1. const nextConfig = {
  2. output: 'standalone',
  3. webpack: (config, { isServer }) => {
  4. config.resolve.alias['~'] = path.join(__dirname, 'src');
  5. return config;
  6. },
  7. };

这是我的假设:在 Next.js 13 中,他们转向了 turbopack,但仍然使用 Webpack 作为打包工具。Webpack 运行的阶段与 TS 编译阶段不同,因此它不会考虑 tsconfig.json

Here's my hypothesis: in Next.js 13, they moved to turbopack but still use Webpack as a bundler. Webpack runs at a different phase than the TS compilation phase, so it doesn't take into account tsconfig.json.

这是我的假设:在 Next.js 13 中,他们转向了 turbopack,但仍然使用 Webpack 作为打包工具。Webpack 运行的阶段与 TS 编译阶段不同,因此它不会考虑 tsconfig.json

英文:

Found the issue.

The solution was to update next.config.js to set the path alias in webpack. This should be the same as your tsconfig.json.

  1. const nextConfig = {
  2. output: 'standalone',
  3. webpack: (config, { isServer }) => {
  4. config.resolve.alias['~'] = path.join(__dirname, 'src');
  5. return config;
  6. },
  7. };

Here's my hypothesis: in Next.js 13, they moved to turbopack but still use Webpack as a bundler. Webpack runs at a different phase than the TS compilation phase, so it doesn't take into account tsconfig.json.

huangapple
  • 本文由 发表于 2023年7月13日 14:21:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76676456.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定