Title: [Bug] Comprehensive Build & Runtime Failures with Next.js Standalone, Turbopack, and Docker
Environment:
- Framework: Next.js
15.5.2 (App Router, Turbopack)
- Library:
intlayer / next-intlayer v5.8.1
- Build Environment: Docker (
node:lts-bullseye) on Google Cloud Build
- Local Environment: Windows (PowerShell)
- Package Manager: pnpm
v10.15.1
Problem Summary:
We've been working to create a reliable production build using output: 'standalone' and Turbopack. This process uncovered a series of cascading issues related to Turbopack compatibility, build-time race conditions in Docker, and runtime errors with the standalone server. While we have found workarounds for all issues, the number of steps required suggests potential improvements for the library.
Detailed Breakdown of Issues and Solutions
Part 1: Turbopack Compatibility (next build --turbo)
The initial build attempts failed because several dependencies tried to import Node.js built-in modules on the client.
- Issue:
Module not found errors for fs, module, child_process, and esbuild binaries/readmes.
- Solution: We had to manually configure
next.config.mjs to stub out these modules for the client using turbopack.resolveAlias. This involved:
- Installing and aliasing browser-compatible polyfills (
path-browserify, crypto-browserify).
- Creating an empty stub file (
stubs/empty.js) and aliasing server-only modules (fs, child_process, module, esbuild) to it.
- Updating the stub file to export dummy implementations for required named exports like
existsSync and buildSync to satisfy imports from @intlayer/config.
Part 2: Build-Time "Dictionary not found" Error in Docker
After fixing the Turbopack issues, the build would fail during static page generation with Error: Dictionary <name> not found.
- Issue: The
next build command could not find the dictionary files, even though they were being generated in the preceding step.
- Investigation:
- We added
ls -lR .intlayer to the Dockerfile, which definitively confirmed that pnpm exec intlayer build was successfully creating all dictionary files in the correct .intlayer/dictionary directory before the next build command began.
- This pointed to a race condition or a filesystem caching issue within the Docker build process, where the Next.js build was not seeing the newly created files.
- Solution: We restructured the entire build process to be more robust:
- Moved the
pnpm exec intlayer build command to a postinstall script in package.json.
- This ensures the
.intlayer directory is reliably generated and present on the filesystem immediately after dependencies are installed, creating a stable state before any build commands are run.
Part 3: Runtime Errors with Standalone Server (pnpm start)
After a successful build, the local standalone server would crash or fail to serve assets.
- Issues:
TypeError: Cannot read properties of undefined (reading 'match') in the intlayerMiddleware.
404 Not Found for static assets in the public folder (e.g., logos).
- Investigation: The
output: 'standalone' build was not automatically including the necessary runtime files in the final .next/standalone directory. Specifically, it was missing:
intlayer.config.ts (causing the middleware crash).
- The generated
.intlayer directory (would cause dictionary errors).
- The
public folder.
- Solution: We created a
postbuild script in package.json that uses copyfiles to manually copy all three of these required assets into the .next/standalone directory after the next build completes.
Part 4: @intlayer/swc Failure on Windows
- Issue: Enabling the
@intlayer/swc plugin causes a build failure on Windows with a Module not found error for the .wasm file, citing "windows imports are not implemented yet".
- Workaround: The plugin had to be completely removed from the project to allow local development on Windows to succeed.
Final Working Configuration
For reference, here are the key parts of our final, working configuration:
package.json scripts:
"scripts": {
"build": "pnpm exec intlayer build && next build --turbo",
"postbuild": "pnpm exec copyfiles -u 1 \"public/**/*\" \".intlayer/**/*\" intlayer.config.ts .next/standalone",
"start": "cross-env PORT=3001 node .next/standalone/server.js",
"postinstall": "pnpm exec intlayer build"
}
Dockerfile:
# Use the official Node.js LTS image as a base
FROM node:lts-bullseye AS base
# Set up PNPM and Corepack environment
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
# Create a non-root user for security best practices
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
WORKDIR /app
# -----------------
# DEPS
# -----------------
# Install dependencies in a separate layer to leverage Docker's caching.
FROM base AS deps
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
# This command now also runs 'pnpm exec intlayer build' automatically via your postinstall script
RUN pnpm install --frozen-lockfile
# -----------------
# BUILDER
# -----------------
# Build the application.
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ARG NEXT_PUBLIC_API_URL
ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
# This single command runs 'next build' and then your 'postbuild' script to copy all necessary files.
RUN pnpm build
# -----------------
# RUNNER
# -----------------
# Create the final, lightweight production image.
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1
# Copy the prepared standalone output (which now includes public, .intlayer, etc.)
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
# Copy the necessary client-side static assets
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
# Run as the non-root user
USER nextjs
EXPOSE 3000
ENV PORT 3000
# Start the server
CMD ["node", "server.js"]
- This setup is now stable, but it required significant workarounds. Hopefully, this detailed report can help improve the out-of-the-box experience for other users in similar environments. Thank you!
Title: [Bug] Comprehensive Build & Runtime Failures with Next.js Standalone, Turbopack, and Docker
Environment:
15.5.2(App Router, Turbopack)intlayer/next-intlayerv5.8.1node:lts-bullseye) on Google Cloud Buildv10.15.1Problem Summary:
We've been working to create a reliable production build using
output: 'standalone'and Turbopack. This process uncovered a series of cascading issues related to Turbopack compatibility, build-time race conditions in Docker, and runtime errors with the standalone server. While we have found workarounds for all issues, the number of steps required suggests potential improvements for the library.Detailed Breakdown of Issues and Solutions
Part 1: Turbopack Compatibility (
next build --turbo)The initial build attempts failed because several dependencies tried to import Node.js built-in modules on the client.
Module not founderrors forfs,module,child_process, andesbuildbinaries/readmes.next.config.mjsto stub out these modules for the client usingturbopack.resolveAlias. This involved:path-browserify,crypto-browserify).stubs/empty.js) and aliasing server-only modules (fs,child_process,module,esbuild) to it.existsSyncandbuildSyncto satisfy imports from@intlayer/config.Part 2: Build-Time "Dictionary not found" Error in Docker
After fixing the Turbopack issues, the build would fail during static page generation with
Error: Dictionary <name> not found.next buildcommand could not find the dictionary files, even though they were being generated in the preceding step.ls -lR .intlayerto the Dockerfile, which definitively confirmed thatpnpm exec intlayer buildwas successfully creating all dictionary files in the correct.intlayer/dictionarydirectory before thenext buildcommand began.pnpm exec intlayer buildcommand to apostinstallscript inpackage.json..intlayerdirectory is reliably generated and present on the filesystem immediately after dependencies are installed, creating a stable state before any build commands are run.Part 3: Runtime Errors with Standalone Server (
pnpm start)After a successful build, the local standalone server would crash or fail to serve assets.
TypeError: Cannot read properties of undefined (reading 'match')in theintlayerMiddleware.404 Not Foundfor static assets in thepublicfolder (e.g., logos).output: 'standalone'build was not automatically including the necessary runtime files in the final.next/standalonedirectory. Specifically, it was missing:intlayer.config.ts(causing the middleware crash)..intlayerdirectory (would cause dictionary errors).publicfolder.postbuildscript inpackage.jsonthat usescopyfilesto manually copy all three of these required assets into the.next/standalonedirectory after thenext buildcompletes.Part 4:
@intlayer/swcFailure on Windows@intlayer/swcplugin causes a build failure on Windows with aModule not founderror for the.wasmfile, citing "windows imports are not implemented yet".Final Working Configuration
For reference, here are the key parts of our final, working configuration:
package.jsonscripts:Dockerfile: