You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 12.1.6配置experimental.runtime报错需启用reactRoot搭配React18

问题根因
  • 报错experimental.runtime requires experimental.reactRoot to be enabled along with React 18的核心原因是Next 12.1.6 dev模式的依赖检测bug:你的Next应用托管在./src/client子目录,React、react-dom依赖被提升到了项目根目录的node_modules中,dev模式启动热重载时,webpack配置初始化阶段的React版本检测逻辑不会正确向上遍历查找被提升的依赖包,误判当前环境React版本低于18,且未自动开启reactRoot特性,直接抛出错误。生产构建(npm run build)使用独立的依赖解析逻辑,能正确识别根目录的React 18版本,因此构建流程可正常运行。
  • 同版本依赖的全新空白项目不触发报错,是因为空项目的Next、React、react-dom都安装在同一级目录下,不存在子目录托管、依赖提升的场景,dev模式可直接读取到正确的React版本,自动开启reactRoot特性,不会触发校验拦截。
  • 切换到next@canary后出现的HookWebpackError: The "to" argument must be of type string. Received undefined错误,是canary版本对跨层级自定义distDir配置的路径解析bug,和React Server Components本身的能力无关。
修复方案

方案1:使用Next 12.1.6稳定版(优先选择,无已知兼容bug)

  1. 修改next.config.js,显式开启reactRoot配置,跳过dev模式的自动版本检测逻辑:
const nextConfig = {
  distDir: '../../.next',
  reactStrictMode: true,
  experimental: {
    runtime: 'nodejs',
    serverComponents: true,
    concurrentFeatures: true,
    reactRoot: true, // 显式声明开启React 18 root API
  },
};

module.exports = nextConfig;
  1. 修改NestJS中启动Next服务的代码,将Next项目目录从相对路径改为绝对路径,避免Next内部路径解析、依赖查找逻辑出错:
import { Injectable, OnModuleInit } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import createServer from 'next';
import { NextServer } from 'next/dist/server/next';
import { Request, Response } from 'express';
import { join } from 'path';

@Injectable()
export class ViewService implements OnModuleInit {
  private server: NextServer;

  constructor(private configService: ConfigService) {}

  async onModuleInit(): Promise<void> {
    try {
      this.server = createServer({
        dev: this.configService.get<string>('NODE_ENV') !== 'production',
        dir: join(process.cwd(), 'src/client'), // 传入绝对路径指向Next项目目录
      });
      await this.server.prepare();
    } catch (error) {
      console.error(error);
    }
  }

  handler(req: Request, res: Response) {
    return this.server.getRequestHandler()(req, res);
  }
}
  1. 如果上述修改后仍报React版本检测错误,在项目根目录执行以下命令,将根目录的React依赖软链到Next子目录,保证Next可直接读取到正确版本:
npm link ./node_modules/react ./node_modules/react-dom --prefix ./src/client

方案2:使用next@canary版本(需使用最新RSC特性时选择)

  1. 移除next.config.js中跨层级的distDir配置,避免canary版本的路径解析bug:
const nextConfig = {
  // 删除distDir: '../../.next'配置
  reactStrictMode: true,
  experimental: {
    runtime: 'nodejs',
    serverComponents: true,
    concurrentFeatures: true,
  },
};

module.exports = nextConfig;
  1. 修改package.json中的build脚本,在Next构建完成后手动移动构建产物到目标路径:
"build": "nest build && cd src/client && next build && mv .next ../../.next"
  1. 同方案1第二步,将Next启动的dir参数改为绝对路径,保证路径解析正确。
验证步骤
  • 删除项目根目录、src/client目录下所有.next缓存文件夹
  • 重新执行npm run start:dev,校验dev服务是否正常启动
  • 执行npm run build校验生产构建流程是否正常,React Server Components能力是否可正常使用

内容的提问来源于stack exchange,提问作者ORLVNI

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 07:12:52