利用Trae熟悉Nuxt与Next
最近的后端儿开始接受LLM业务。在谁都不太懂,市场还在迭代的过程中,老板两手空空说 "接下来你自己发挥" ,让端儿开始面向老板编程,需要快速开发验证性的产品。
为了快速开发产品展示思路与方案,也方便别人理解,同时满足快速变更迭代的节奏,加上langchain等工具都有基于Nodejs的包,于是端儿来到了Nuxt与Next的双岔路,接下来该和谁牵手❤️?
网上的两者的比较让人看得眼花缭乱,但是端儿只有一个要求,写起来顺手就行。所以需要"比较"两者,这时候我想到最近一直闪动的Trae------好一个身着红衣的媒婆👩🏻(带着豆包👧🏻与Cici👧🏻)。
Trae来写
让Trae写两份简单的代码出来瞧瞧,通过代码风格纵观全局,再让Trae实现一个需求,最后自己对着写一些功能,就知道如何选择了。
首先用后端熟悉的方式,让Trae用前端与后端实现一个CRUD需求,然后让它改写为Nuxt与Next实现,看各自的对比。
生成的常规前后端分离 NestJs + React:
java
├── README.md
├── build
│ └── Dockerfile
├── client
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ └── index.html
│ ├── src
│ │ ├── App.tsx
│ │ ├── components
│ │ │ └── Layout.tsx
│ │ ├── index.css
│ │ ├── index.tsx
│ │ └── pages
│ │ ├── Dashboard.tsx
│ │ ├── Login.tsx
│ │ └── Register.tsx
│ └── tsconfig.json
├── database.sqlite
├── package-lock.json
├── package.json
├── src
│ ├── app.module.ts
│ ├── auth
│ │ ├── auth.controller.ts
│ │ ├── auth.module.ts
│ │ ├── auth.service.ts
│ │ ├── jwt-auth.guard.ts
│ │ └── jwt.strategy.ts
│ ├── main.ts
│ ├── test
│ │ ├── auth
│ │ │ └── auth.controller.spec.ts
│ │ └── users
│ │ └── users.controller.spec.ts
│ └── users
│ ├── dto
│ │ └── create-user.dto.ts
│ ├── user.entity.ts
│ ├── users.controller.ts
│ ├── users.module.ts
│ └── users.service.ts
└── tsconfig.json
这个项目主要是登录认证功能,使用sqlite存储数据。
在user中,存在service、ccontroller、dto等等,entity定义了数据层的实体,service构建了数据行为,dto构建了数据传输对象,controller包装service后控制业务执行,最后借助controller提供对外的api(通过装饰器)。 在client文件夹中生成了react的前端代码。
然后让Trae开始搬砖编写新代码,分别用Nuxt与Next重写:

一顿操作猛如虎,Trae最终还是写出了对应的代码。虽然看起来不错,但是生成的代码中还是有很多报错,还错误得莫名其妙。
让它自己修复,结果...

那就多跑几轮多次等待,最终Trae还是交出了一份答卷:

随后进行了多次提问,比如提问状态管理、数据流程、代码组织等等,回答有好有坏,结合我自己的理解,给出完整理解:
NextJs:
lua
.
├── README.md
├── next.config.ts
├── package-lock.json
├── package.json
├── postcss.config.mjs
├── prisma
│ └── schema.prisma
├── public
│ ├── file.svg
│ ├── globe.svg
│ ├── next.svg
│ ├── vercel.svg
│ └── window.svg
├── src
│ └── app
│ ├── api
│ │ └── auth
│ │ ├── [...nextauth]
│ │ │ └── route.ts
│ │ └── register
│ │ └── route.ts
│ ├── dashboard
│ │ └── page.tsx
│ ├── favicon.ico
│ ├── globals.css
│ ├── layout.tsx
│ ├── login
│ │ └── page.tsx
│ ├── page.tsx
│ └── register
│ └── page.tsx
└── tsconfig.json
开发流程首先利用prisma准备好数据层,实际业务逻辑在src/app/api完成(CRUD),基于api绑定page并由page返回html响应界面。
-
框架会自行将app目录下的page自动映射为路由(动态路由:/data/[id].tsx)。
-
如果页面功能复杂,比如复杂的dashboard,那应该在app/dashboard下分层建立文件夹按功能模块组织代码。
如components用于存放可复用组件,sections用于组织不同功能区块。使用React Context或状态管理库管理全局状态,确保组件间数据共享。将业务逻辑抽离到独立的hooks或service文件中,保持页面组件的简洁性。
-
'use client' 标识在客户端渲染
-
手动状态管理:在next/src/app/login/page.tsx中,使用原生的useState管理组件内部状态(formData和error),状态仅限于组件内部。跨组件状态共享需要手动实现Context API或引入Redux等第三方库。
-
认证状态通过next-auth库的signIn方法处理,库的导入方式为显式导入。
NuxtJs:
arduino
.
├── README.md
├── app.vue
├── assets
│ └── css
│ └── main.css
├── nuxt.config.ts
├── package-lock.json
├── package.json
├── pages
│ ├── dashboard.vue
│ ├── index.vue
│ ├── login.vue
│ └── register.vue
├── prisma
│ └── schema.prisma
├── public
│ ├── favicon.ico
│ └── robots.txt
├── server
│ ├── api
│ │ ├── auth
│ │ │ ├── login.post.ts
│ │ │ └── register.post.ts
│ │ └── users
│ │ └── profile.get.ts
│ └── tsconfig.json
├── tailwind.config.js
└── tsconfig.json
Nuxt中数据层管理也是交给Prisma,总入口为app.vue,pages下是各个分页,自动将login.vue对应/login路由。server中负责封装数据操作,pages负责控制数据流程并提供对外服务。
- 与Next一样基于文件路径映射路由,只是Nuxt是基于pages文件夹组织路由。(动态路由:/data/_id.vue)
- Nuxt整体流程比较简单,甚至会有点凌乱,比如自动导入组件的特点,在pages/index.vue中直接使用一些外层文件组件,刚开始看到某个方法却不知道哪里来的,显得有点突兀。(Next中则需要显式导入)
- Nuxt提供了内置的useState函数,可在任何组件中使用且自动处理SSR状态同步。在pages/login.vue中,可以直接使用这些状态而无需显式导入。(复杂状态逻辑推荐使用Pinia替代useState以获得更好的TypeScript支持)
- 在Nuxt.js中,composables目录是一个特殊的目录,用于存放可复用的组合式函数,这些函数会被自动导入到整个应用中。
- 页面中通过编写HTML代码,在下面引入script setup提供页面操作逻辑。
- 如果是写静态页面为主的程序比如博客管理系统,使用Nuxt就只要在stores中实现数据查询,然后在pages中写页面样式与数据渲染,打包发布即可。流量到达时会由nuxt调用store与page配合,渲染出页面html响应。
总结
Trae体验
通过Trae写代码的方式,对比两个框架,这种实战性可以加深对开发过程的理解,遇到一些不懂的也可以随时提问。比如:
- #nuxt 这个项目中,如果我有一个复杂的dashboard,那么在dashboard的page中应该如何组织代码
- #nuxt 以这个项目中,详细说明Nuxt的自动导入与状态管理特性
- 解决运行报错: ERROR [uncaughtException] @prisma/client did not initialize yet. Please run "prisma generate" and try to import it again.
- 举例解释"Nuxt支持在composables目录创建自定义状态逻辑,全局自动导入。"
- #next #nuxt 分别为这两个项目写打包发布的makefile与开箱即用的DockerFIle,举例详细说明两者在打包发布部署上的差异与优劣
但是,Trae只能帮你做0分到50分阶段(甚至可能运行不起来),如果要从50到60,甚至是60到80,无论如何都需要自己逐行检查,编写代码,做好抽象设计。
不存在任何银弹,别幻想😭。AI工具的出现只是加快了一些确定性的事物的效率,在程序编码领域的表现,从广度上削弱了顶级程序员与中级程序员之间、中级与初级之间的差距,只是一种提效工具。
框架选择
-
编写风格
Next会比较一板一眼,显式导包,显式状态管理,严谨的项目分层组织,就像强类型语言工程化;Nuxt则相对自由,各种关系调用比较跳脱,基于类似运行时的东西帮开发者管理代码中的数据与状态,开发速度比较快。
代码管理上考虑,Next适合大型项目与多人协作的情况;Nuxt虽然也可以满足大项目,但是需要更多的"约定"并且考验开发者的能力。
-
生态、特性等相差不大,性能虽然据说有差异,但是实在影响不大
-
打包与部署
Next.js
- 构建命令 :
next build
- 输出目录 :
.next
- 部署模式: 默认为服务端渲染(SSR),可配置为静态导出(SSG)
- 独特特性: 支持增量静态再生(ISR),自动静态优化
- Make: 主要关注单一构建流程和部署方式
Nuxt.js
- 构建命令 :
- SSR模式:
nuxt build
- 静态模式:
nuxt generate
- SSR模式:
- 输出目录 :
- SSR模式:
.output
- 静态模式:
.output/public
- SSR模式:
- 部署模式: 可选SSR或SSG,配置更加灵活.(需要两个不同的Dockerfile分别处理SSR和SSG,SSG模式可以使用纯静态服务器(如Nginx)部署)
- 独特特性: 自动路由生成,API路由集成
- Make: 需要处理两种不同的构建模式(SSR和SSG),命令和流程更复杂
- 构建命令 :
最终的项目代码放这里: