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

Next.js 13 + Framer Motion:无法解析‘v8’模块问题求助

解决Next.js 13 App目录中Framer Motion导致的"Module not found: Can't resolve 'v8'"错误

问题原因

这个错误本质是浏览器环境中不存在Node.js内置的v8模块,触发场景通常是:

  • 客户端组件中调用了仅能在服务器端运行的代码(比如你的getSession如果依赖服务器端的Node.js API)
  • Framer Motion或相关依赖的版本与Next.js 13 App目录不兼容,间接引入了依赖v8的模块

结合你的代码来看,核心矛盾是:RootLayout加了'use client'变成客户端组件,但里面直接await getSession(),如果getSession是基于服务器端逻辑实现的(比如依赖next-auth的服务器端API),就会在客户端打包时引入仅Node.js支持的模块,进而触发v8找不到的错误。

解决方案

1. 拆分服务器/客户端逻辑,分离动画组件

App目录中根布局默认是服务器组件,建议将需要客户端交互的动画部分抽成独立的客户端组件,RootLayout保留为服务器组件处理session等服务器端逻辑:

步骤1:创建单独的客户端动画容器组件(components/PageTransition.js)

'use client';

import { useRouter } from 'next/navigation';
import { motion, AnimatePresence } from 'framer-motion';

export default function PageTransition({ children }) {
  const router = useRouter();
  
  return (
    <AnimatePresence exitBeforeEnter>
      <motion.div
        key={router.pathname}
        initial="initialState"
        animate="animateState"
        exit="exitState"
        transition={{ duration: 0.75 }}
        variants={{
          initialState: { opacity: 0, clipPath: 'polygon(0 0, 100% 0, 100% 100%, 0% 100%)' },
          animateState: { opacity: 1, clipPath: 'polygon(0 0, 100% 0, 100% 100%, 0% 100%)' },
          exitState: { clipPath: 'polygon(50% 0, 50% 0, 50% 100%, 50% 100%)' }
        }}
      >
        {children}
      </motion.div>
    </AnimatePresence>
  );
}

步骤2:修改RootLayout为服务器组件(移除'use client')

import { Poppins } from '@next/font/google';
import { getSession } from '../lib/session';
import Header from '../components/Header';
import Footer from '../components/Footer';
import AuthContext from '../components/AuthContext';
import PageTransition from '../components/PageTransition';
import '../styles/globals.css';

const poppins = Poppins({ weight: '500' });

export default async function RootLayout({ children }) {
  const session = await getSession();
  
  return (
    <html lang="en" className={poppins.className}>
      <head />
      <body>
        <AuthContext session={session}>
          <Header />
          <PageTransition>{children}</PageTransition>
        </AuthContext>
        {session && <Footer />}
      </body>
    </html>
  );
}

2. 检查并更新依赖版本

  • 确保framer-motion版本≥10.16.0(该版本开始优化了与Next.js 13 App目录的兼容性)
  • 确保next-auth版本与Next.js 13兼容,避免版本冲突导致的间接依赖问题

执行命令更新:

npm install framer-motion@latest next-auth@latest

3. 临时webpack fallback(仅当上述方案无效时使用)

如果是某个依赖强制引入v8模块,可在next.config.js中添加webpack配置忽略该模块:

/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (config) => {
    config.resolve.fallback = {
      ...config.resolve.fallback,
      v8: false, // 告诉webpack不要尝试解析v8模块
    };
    return config;
  },
};

module.exports = nextConfig;

关键注意点

  • App目录中,服务器组件不能调用客户端API(比如useRouter),反之客户端组件也不能直接await服务器端的异步函数(除非该函数是客户端兼容的)
  • next-auth的客户端session获取应该用useSession钩子(来自next-auth/react),而不是服务器端的getSession

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 02:55:23