参考官网的升级指引:Upgrade Guide · Get Started with Nuxt v4 ,对项目进行升级和自动化迁移目录结构后,执行nuxt dev启动项目,然后就开始了一路的解决报错之旅。
1 2 3 4 5 6 7 8 9 npm install nuxt@^4.0.0 npx codemod@0.18.7 nuxt/4/migration-recipe > y > [按下Enter键,等待自动迁移...]
报错1:File is not defined 这个报错信息并不是我的代码造成的,而是node_modules目录下的NPM包报错,所以我第一反应是node环境有变化了,于是去官网查看了node版本要求。果然,Nuxt 4需要 Node 20.X 以上的版本。
1 2 3 4 5 6 7 8 9 10 11 12 ERROR File is not defined 09:50:46 at Object.<anonymous> (node_modules\undici\lib\web\webidl\index.js:531:48) at Module._compile (node:internal/modules/cjs/loader:1364:14) at Module._extensions..js (node:internal/modules/cjs/loader:1422:10) at Module.load (node:internal/modules/cjs/loader:1203:32) at Module._load (node:internal/modules/cjs/loader:1019:12) at Module.require (node:internal/modules/cjs/loader:1231:19) at require (node:internal/modules/helpers:177:18) at Object.<anonymous> (node_modules\undici\lib\web\fetch\util.js:12:20) at Module._compile (node:internal/modules/cjs/loader:1364:14) at Module._extensions..js (node:internal/modules/cjs/loader:1422:10)
官网文档有提到Node版本要求
主包平时用nvm管理node多环境(参考这篇 ),这里切到了node 22.x版本就解决了。
报错2:Cannot start nuxt: Cannot find native binding. 没遇到过,问了豆包说可能是切换node版本之后,node_modules中的安装包需要重新安装导致的,于是按照豆包给的提示删除了项目下的node_modules 和package_locked.json ,重新执行npm install。
1 2 3 4 5 6 7 8 rm -rf node_modules package-lock.jsonnpm cache clean --force npm install
因为windows上没有rm -rf指令,需要手动删一下。重装之后问题解决。
报错3:Error: Could not load d:/***/app/lib/prisma (imported by server/api/***/***/[id].delete.ts): ENOENT: no such file or directory, open ‘d:\***\app\lib\prisma’ Nuxt4中把srcDir调整到app目录
原因是之前引用其他文件时,~指向的是根目录,而在Nuxt 4中~调整为指向app/目录。你可以在nuxt.config.ts中修改srcDir的值为.来恢复到Nuxt 3的状态,但这操作不排除会对app目录下的文件路由产生影响。所以这里我用相对路径替换,手动修改了这些文件的引用关系。
另一个变动项是:我把Prisma实例从lib\prisma.ts移动至server\utils\prisma.ts。
我最初打算将lib\prisma.ts文件移动至server\lib\prisma.ts,但依旧出现了找不到引用地址的问题。最后看Nuxt推荐的目录结构,将其放到了server\utils目录,就没出现报错了。
关于引用路径替换
最初我用相对路径替换prisma引用,后面发现使用~~也可以指向到根目录,即~~/server/就代表着根目录/server/目录,舒服了😁
调整1:工具类、类型定义文件迁移至shared目录 过去我把工具类放到了lib/utils.ts中,以导出方法的形式在服务端和客户端间调用。在Nuxt中则提供了/shared/目录,放置无状态的、不受运行环境限制的、服务端和客户端都可使用的代码(例如工具类和类型定义文件)。
由于/shared/utils和/shared/types下的ts文件,支持方法自动导入(auto-imports),所以这一步我把过去的工具类拆成了单个方法放置在/shared/utils/[xxx].ts;而对于类型定义文件,则直接迁移到/shared/types目录下。
报错4:Cannot find module ‘~/app/assets/css/***.css’ imported from ‘virtual:nuxt: .nuxt/css.mjs’. - If you rely on tsconfig.json’s “paths” to resolve modules, please install “vite-tsconfig-paths” plugin to handle module resolution. 原因是nuxt.config.ts中的css属性配置错误,因为srcDir的指向变了,这里导入的css路径也需要修改。修改完成后,重启项目,问题解决!
1 2 3 4 5 6 7 8 9 10 export default defineNuxtConfig({ // ... css: [ // 原来的配置 '~/app/assets/css/***.css' , // 修改为 '~/assets/css/***.css' , ], })
报错5:Uncaught (in promise) SyntaxError: The requested module ‘/_nuxt/@fs/xxx/node_modules/@prisma/client/index-browser.js’ does not provide an export named ‘PrismaClient’ 这个问题非常奇怪,侧边菜单栏的接口我是在composables中通过useFetch调用后端nuxt接口操作的,它可以正常调用;而我页面中是封装的$fetch调用后端接口,就会出现这个错误。
我试图在Github的两个项目中(@prisma/nuxt和prisma)查找解决方案,搜索了一些同样问题的issue,但是评论区的一些答案,对我并不起作用:
我又尝试了降级@prisma/client和新创建Nuxt 4项目测试,效果都不行。降级到@prisma/client@6.4.1,连客户端都无法生成了(提示:Failed to generate Prisma Client.);新创建的Nuxt 4项目在测试时也依旧存在该问题。
重新安装了一个nuxt 4,也仍然存在问题
我在这个问题上卡了两天,几乎试过了网上所有的解决方案,也和几个AI对话试图去寻找解决方案,最终都没有解决问题。直到有天我无意间点开了@prisma/nuxt的Pull Requests页面,看到了下图。
看到了一个兼容Nuxt4的合并请求,还被关闭了...
整了半天,插件还不支持Nuxt 4!此时我有点骑虎难下了,其他问题都解决了,就剩下一个Prisma兼容问题。如果让我放弃回滚代码还有点不甘心了(沉没成本已经2天半了😡)。然后我就开始搜Nuxt 4 + Prisma的使用教程,还真搜到一个:在 Nuxt4 中让 Prisma 正常工作 。最后我参考文章中的思路,放弃使用@prisma/nuxt,转而使用原生Prisma。
切换成原生Prisma包;
1 2 3 4 5 npm uninstall @prisma/nuxt npm install prisma @prisma/client
调整prisma/schema.prisma;
1 2 3 4 5 6 generator client { provider = "prisma-client-js" // 这里我和文章中不同,我测试使用非node_modules目录也不影响项目构建 output = "../prisma/generate" }
测试过构建项目了,没报错!
修改nuxt.config.ts,从modules中删除@prisma/nuxt;
在package.json中增加Prisma的相关命令;
1 2 3 4 5 6 7 8 { "scripts" : { "prisma:generate" : "prisma generate" , "prisma:migrate" : "npx prisma migrate dev" , "prisma:reset" : "prisma migrate reset" , "prisma:seed" : "npx prisma db seed" } }
以后schema.prisma结构更新,就要自己执行prisma:generate更新生成Prisma客户端了。
执行一次prisma:generate生成Prisma客户端;
这里有一点小差别:
Nuxt 3升级Nuxt 4不会遇到问题;
新创建的Nuxt 4项目底下多了一个prisma.config.ts配置文件,如果直接运行大概率会报错(Failed to load config file “****” as a TypeScript/JavaScript module. Error: PrismaConfigEnvError: Missing required environment variable: DATABASE_URL)。如果遇到这个报错请参考下方代码修改prisma.config.ts。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import dotenv from 'dotenv' ;import fs from 'fs' ;import { defineConfig, env } from "prisma/config" ;if (fs.existsSync ('.env' )) { dotenv.config ({path : '.env' }); } else { dotenv.config ({path : '.env.example' }); } export default defineConfig ({ schema : "prisma/schema.prisma" , migrations : { path : "prisma/migrations" , }, engine : "classic" , datasource : { url : env ("DATABASE_URL" ), }, });
创建Prisma单例文件;
1 2 3 4 5 6 7 8 9 10 11 12 import { PrismaClient } from "~~/prisma/generate" ;export * from "~~/prisma/generate" ;const prismaClientSingleton = ( ) => new PrismaClient ();declare const globalThis : { prismaGlobal : ReturnType <typeof prismaClientSingleton>; } & typeof global ; export const prisma = globalThis.prismaGlobal ?? prismaClientSingleton ();if (process.env .NODE_ENV !== "production" ) globalThis.prismaGlobal = prisma;
替换server/api/**/*.ts接口文件的Prisma引用;
重启项目,问题解决🚀
调整2:删除Vue页面中使用的工具类方法、类型定义的导入代码 在Prisma恢复正常后,页面上开始报错。是由 调整1 里将工具类、类型定义文件迁到shared目录下,导致页面中无法按路径导入文件产生的报错。处理方式也很简单,直接从页面中删除这些导入代码即可(因为shared目录下的这些文件会在运行时自动导入,所以这里不用再处理引用关系了😂)
结尾 整个Nuxt 4升级工作花了我三天时间,两天半的时间卡在 报错5 上,最后终于升级完成了,真不容易😄
我也用上 Nuxt 4了