The "Unexpected Token" error during Next.js deployment on Google Cloud Platform (GCP) typically stems from Node.js attempting to parse ES Module syntax in a CommonJS context, or from stale build artifacts in the output directory. To resolve this, ensure your package.json correctly defines the module type, verify that your build process uses the standard next build command without custom transpilation that might break syntax, and clean the .next cache before redeploying.
Understanding the Root Cause
When deploying a Next.js application to GCP, whether via Cloud Run, App Engine, or Compute Engine, the environment must strictly adhere to the module system defined in your project configuration. The "Unexpected token 'export'" or similar syntax errors occur when the Node.js runtime encounters ES Module (ESM) syntax but is configured to run as CommonJS (CJS), or vice versa. This mismatch often happens after upgrading dependencies or changing the Node.js version, such as moving to 18.13.0, which has stricter default behaviors regarding module resolution. Additionally, GCP buildpacks or Dockerfiles may not automatically detect the correct entry point if the build output structure is non-standard. If your deployment pipeline runs a script that doesn't match the compiled output of Next.js, the server may try to execute source files directly instead of the optimized production bundle, leading to parsing failures.Verifying Package.json Configuration
The most common culprit is an incorrect or missing"type" field in your package.json. If your project uses ES modules for imports (e.g., import React from 'react'), you must explicitly tell Node.js to treat JavaScript files as ESM.
Open your package.json and check for the following:
- If you are using ES Modules: Ensure the file contains
"type": "module". - If you are using CommonJS: Remove the
"type"field entirely, or set it to"commonjs".
export statement in a CJS context. For example, if you have "type": "module" but your server script uses require(), you will see unexpected token errors because require is not defined in ESM mode. Conversely, if you lack the "type" field but use import statements, Node.js 18+ will throw a syntax error.
Checking Build Output and Cache Integrity
Next.js generates a.next directory during the build process. If this directory contains corrupted files or remnants from a previous build with different configurations, the deployment will fail. GCP environments often mount volumes or copy artifacts, so ensuring a clean state is critical.
Before deploying, run the following commands locally to simulate the clean build:
- Delete the existing build directory:
rm -rf .next - Clean the node modules cache:
npm cache clean --force - Reinstall dependencies:
npm install - Run the production build:
next build
.next/server/ directory. The main server bundle should be a valid JavaScript file. If you see source maps or uncompiled JSX files being served, your build configuration is likely incorrect. In some cases, custom Webpack configurations in next.config.js may inadvertently expose internal modules or fail to transpile specific syntax, leading to runtime errors on the server side.
Dockerfile and Deployment Script Adjustments
If you are using a Dockerfile for GCP deployment, ensure that the build stage and the production stage are correctly separated. A common mistake is runningnpm start on the source code rather than the built output.
Your Dockerfile should look something like this:
FROM node:18.13.0-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:18.13.0-alpine
WORKDIR /app
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
EXPOSE 3000
CMD ["npm", "start"]
Notice that we only copy the .next folder and necessary files. We do not copy the entire source directory. This prevents the server from accidentally reading development-only files or config scripts that might contain syntax not supported by the production Node.js instance.
For those migrating from other platforms, understanding how module resolution differs is key. While Vercel handles many of these nuances automatically, GCP requires explicit configuration. For more insights on deployment strategies, you might find Deploying Serverless Node Apollo Graphql on Vercel: A Guide useful for comparing platform-specific behaviors.
Debugging with Verbose Logs
If the error persists, enable verbose logging to pinpoint the exact file causing the issue. Set theNODE_OPTIONS environment variable in your GCP deployment settings to include --trace-warnings or --inspect. This will provide a stack trace showing exactly which line triggered the parser error.
Often, the error message will indicate a specific file path. Check if that file is being imported incorrectly or if it relies on a feature not available in Node.js 18.13.0. If you are using third-party libraries, ensure they are compatible with your Node version. Sometimes, outdated packages rely on deprecated syntax that has been removed or restricted in newer Node releases.
For deeper dives into environment setup issues, consider reviewing How to Uninstall and Reinstall Node.js: A Step-by-Step Guide to ensure your local and remote environments are perfectly aligned.
Frequently Asked Questions
Why does my Next.js app work locally but fail on GCP?
Local development uses Next.js's dev server, which handles hot reloading and dynamic transpilation differently than the production build. The production build on GCP expects pre-compiled, static assets and strict module boundaries. Differences in environment variables, file permissions, or Node.js versions between your local machine and the GCP container can trigger these discrepancies.Can I use ESM in Next.js on GCP?
Yes, but you must configure yourpackage.json with "type": "module" and ensure all your server-side scripts also follow ESM syntax. Note that some older Node.js modules may not support ESM natively, requiring you to use createRequire from the module package to bridge compatibility gaps.
What if I am using TypeScript?
TypeScript requires compilation to JavaScript before deployment. Ensure your build step includestsc or that Next.js is handling the transpilation correctly via its integrated TypeScript support. Misconfigured tsconfig.json files can sometimes lead to output that Node.js cannot parse, especially if target settings are incompatible with your Node version.