reactjs - Next.JS v13 i Docker respekterer ikke stivaliaser, men fungerer lokalt


Jeg hadde en fungerende Docker-build, og når jeg satte inn absolutte stier med et stialias, begynte den plutselig å klage module not found, can't resolve 'ComponentName'

Det vil feile på pnpm run build-steget, men når jeg kjører det lokalt, fungerer det fint.

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "plugins": [
      {
        "name": "next"
      }
    ],
    "baseUrl": ".",
    "paths": {
      "~/*": [
        "./src/*"
      ]
    }
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    ".next/types/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}

Filen som forårsaker feilen:

import { Providers } from './providers';
import NavBar from '~/components/NavBar';
import { css } from '~/styles/css';

import './global.css';

export const metadata = {
  title: 'p-stack-fs',
  description: 'A boilerplate for TypeScript, Next.js, and PostgreSQL',
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <Providers>
          <div className={css({ minH: '100vh' })}>
            <NavBar />
            {children}
          </div>
        </Providers>
      </body>
    </html>
  );

Feil :

 > [builder 6/6] RUN pnpm run build:
#25 0.534
#25 0.534 > [email  build /app
#25 0.534 > next build
#25 0.534
#25 0.940 - warn You have enabled experimental feature (instrumentationHook) in next.config.js.
#25 0.941 - warn Experimental features are not covered by semver, and may cause unexpected or broken application behavior. Use at your own risk.
#25 0.941
#25 1.010 - info Creating an optimized production build...
#25 10.94 Failed to compile.
#25 10.94
#25 10.95 ./src/app/layout.tsx
#25 10.95 Module not found: Can't resolve '~/components/NavBar'
#25 10.95
#25 10.95 https://nextjs.org/docs/messages/module-not-found
#25 10.95
#25 10.95 ./src/app/layout.tsx
#25 10.95 Module not found: Can't resolve '~/styles/css'
#25 10.95
#25 10.95 https://nextjs.org/docs/messages/module-not-found
#25 10.95
#25 10.95
#25 10.95 > Build failed because of webpack errors
#25 11.09  ELIFECYCLE  Command failed with exit code 1.
------
executor failed running [/bin/sh -c pnpm run build]: exit code: 1

Du kan se at filene eksisterer og er navngitt riktig her:

For det det er verdt, her er Dockerfilen min

ARG ALPINE_VERSION=3.17

FROM node:20-alpine AS base

Install dependencies only when needed
FROM base AS deps
Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app

COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
COPY panda.config.ts ./

RUN npm i -g pnpm && pnpm i --prod --frozen-lockfile

Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
Panda is built in the `prepare` command, which runs after
`install`, so we copy it over here for building
COPY --from=deps /app/src/styles/ ./src/styles/

RUN ["chmod", "+x", "./docker-entrypoint.sh"]

Next.js collects completely anonymous telemetry data about general usage.
Learn more here: https://nextjs.org/telemetry
Uncomment the following line in case you want to disable telemetry during the build.
ENV NEXT_TELEMETRY_DISABLED 1

RUN npm i -g pnpm
RUN pnpm run build

Production image, copy all the files and run next
FROM alpine:${ALPINE_VERSION} AS runner

WORKDIR /app

Uncomment the following line in case you want to disable telemetry during runtime.
ENV NEXT_TELEMETRY_DISABLED 1

RUN apk add --no-cache --update nodejs
Get AWS SSM Params using a Go binary, reduces image size
Note: this might get a "8: not found" error if not using the USER nextjs, has
to do with something with the ca-certificates
RUN apk update && apk add --no-cache ca-certificates && update-ca-certificates
RUN wget https://github.com/pthieu/go-aws-get-parameter/raw/master/ssm_get_parameter
RUN ["chmod", "+x", "./ssm_get_parameter"]

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

Automatically leverage output traces to reduce image size
https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/src/db/migrations ./migrations

COPY --from=builder --chown=nextjs:nodejs /app/docker-entrypoint.sh ./

USER nextjs

EXPOSE 80

ENV PORT 80

ENTRYPOINT [ "sh", "docker-entrypoint.sh" ]
CMD ["node", "server.js"]
For debugging, keeps container alive
CMD ["tail", "-f", "/dev/null"]

Svar #1

Fant problemet.

Løsningen var å oppdatere next.config.js for å sette sti-aliaset i webpack. Dette bør være det samme som i din tsconfig.json.

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

Her er hypotesen min: i Next.js 13 gikk de over til turbopack, men bruker fortsatt Webpack som bundler. Webpack kjører i en annen fase enn TS-kompileringsfasen, så det tar ikke hensyn til tsconfig.json.

Svar #2

I mitt tilfelle brukte vi DigitalOceans App-plattform for å bygge en Next-app, og problemet var at utviklingsavhengigheter ikke ble installert fordi vi hadde NODE_ENV=production. Som standard vil NPM ignorere utviklingsavhengigheter når det ser at miljøvariabelen er satt.

Dessverre inkluderte dev-avhengigheter kritisk TypeScript, og derfor hadde ikke innstillingene vi hadde i vår tsconfig.json noen effekt (som inkluderte den viktige innstillingen: compilerOptions.paths).

Løsningen var å endre byggekommandoen fra npm run build til npm install --production=false && npm run build && npm ci, noe som sikret at utviklingsavhengigheter ble installert og brukt under bygging.

Relaterte artikler