-
-
Notifications
You must be signed in to change notification settings - Fork 97
Description
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-intlayerv5.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 founderrors forfs,module,child_process, andesbuildbinaries/readmes. - Solution: We had to manually configure
next.config.mjsto stub out these modules for the client usingturbopack.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
existsSyncandbuildSyncto satisfy imports from@intlayer/config.
- Installing and aliasing browser-compatible polyfills (
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 buildcommand could not find the dictionary files, even though they were being generated in the preceding step. - Investigation:
- We added
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. - 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.
- We added
- Solution: We restructured the entire build process to be more robust:
- Moved the
pnpm exec intlayer buildcommand to apostinstallscript inpackage.json. - This ensures the
.intlayerdirectory is reliably generated and present on the filesystem immediately after dependencies are installed, creating a stable state before any build commands are run.
- Moved the
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 theintlayerMiddleware.404 Not Foundfor static assets in thepublicfolder (e.g., logos).
- Investigation: The
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).- The generated
.intlayerdirectory (would cause dictionary errors). - The
publicfolder.
- Solution: We created a
postbuildscript inpackage.jsonthat usescopyfilesto manually copy all three of these required assets into the.next/standalonedirectory after thenext buildcompletes.
Part 4: @intlayer/swc Failure on Windows
- Issue: Enabling the
@intlayer/swcplugin causes a build failure on Windows with aModule not founderror for the.wasmfile, 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!