《从零搭建 Next.js + NestJS 全栈项目:踩坑实录》

markdown 复制代码
# 从零搭建 Next.js + NestJS 全栈项目:Turborepo + pnpm 踩坑实录与最佳实践

> **项目 GitHub 地址**:[https://github.com/yourname/freemonitor-app](https://github.com/yourname/freemonitor-app)  
> **技术栈**:Next.js + NestJS + Turborepo + pnpm + TypeScript + Tailwind CSS + Docker  
> **关键词**:`#Next.js` `#NestJS` `#Turborepo` `#pnpm` `#全栈开发` `#工程化`

---

## 🚀 引言

最近我着手开发一个监控平台 `FreeMonitor`,决定采用 **Next.js + NestJS** 作为前后端技术栈,并使用 **Turborepo + pnpm** 构建 Monorepo 项目。

本以为初始化脚手架后就能快速开发,结果在 `pnpm install`、`turbo run dev` 等环节踩了无数坑。经过连续调试,终于跑通了前后端一体化开发流程。

本文将**完整记录我遇到的所有问题、错误信息、错误操作和最终解决方案**,希望能帮你少走弯路。

---

## 🏗️ 项目初始化

使用 `create-next-app` 初始化前端,Turborepo 管理多项目:

```bash
# 初始化前端
pnpm create next-app@latest apps/frontend --use-pnpm --typescript --tailwind --eslint --app --src-dir --import-alias="@/*"

# 安装 Turborepo 到根目录
pnpm add -D -w turbo typescript @types/node

项目结构如下:

bash 复制代码
freemonitor-app/
├── apps/
│   ├── frontend/     # Next.js 前端
│   └── backend/      # NestJS 后端
├── packages/
│   └── types/        # 共享类型
├── turbo.json
├── package.json
└── pnpm-workspace.yaml

🧩 遇到的问题与解决方案

❌ 1. ERR_PNPM_WORKSPACE_PKG_NOT_FOUND:误用 workspace:*

报错信息:

kotlin 复制代码
ERR_PNPM_WORKSPACE_PKG_NOT_FOUND  In packages/types: "typescript@workspace:*" is in the dependencies but no package named "typescript" is present in the workspace

错误原因 :
typescript 是 npm 包,不是 workspace 内部包,不能用 workspace:*。

错误操作:

json 复制代码
"devDependencies": {
  "typescript": "workspace:*"
}

✅ 解决方案 :

改为从 npm 安装:

json 复制代码
"devDependencies": {
  "typescript": "^5.9.2"
}

❌ 2. ERR_PNPM_ADDING_TO_ROOT:未明确依赖安装位置

报错信息:

csharp 复制代码
ERR_PNPM_ADDING_TO_ROOT  Running this command will add the dependency to the workspace root...

原因:pnpm 提示你是否要安装到根目录。

✅ 解决方案 :

明确使用 -w:

bash 复制代码
pnpm add -D -w tailwindcss postcss autoprefixer

❌ 3. WARN Ignoring broken lockfile:pnpm 版本不兼容

报错信息:

csharp 复制代码
WARN  Ignoring broken lockfile at /.../pnpm-lock.yaml not compatible with current pnpm

原因 :当前 pnpm@8.15.0 无法解析由 pnpm@10+ 生成的 lockfile。

✅ 解决方案 :

升级 pnpm:

bash 复制代码
pnpm add -g pnpm@10.15.0

并在 package.json 中声明:

json 复制代码
"packageManager": "pnpm@10.15.0"

❌ 4. Configuring Next.js via 'next.config.ts' is not supported

报错信息:

vbnet 复制代码
Error: Configuring Next.js via 'next.config.ts' is not supported.

原因 :Next.js 不支持 next.config.ts。

✅ 解决方案 :

重命名为 next.config.js,并使用 JSDoc 类型提示:

js 复制代码
/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
}

module.exports = nextConfig

❌ 5. Module not found: Can't resolve 'tailwindcss'

报错信息:

rust 复制代码
Module not found: Can't resolve 'tailwindcss'
Import trace for requested module: ./src/app/globals.css

原因 :tailwindcss 未正确安装或未被 PostCSS 找到。

✅ 解决方案 :

在根目录安装构建工具:

bash 复制代码
pnpm add -D -w tailwindcss postcss autoprefixer

❌ 6. Unknown font 'Geist'

报错信息:

go 复制代码
`next/font` error: Unknown font `Geist`

原因 :Geist 不是 Google Fonts 字体,而是本地 .woff 文件。

✅ 解决方案 :

使用 next/font/local 加载本地字体:

ts 复制代码
import localFont from 'next/font/local'

const geistSans = localFont({
  src: './fonts/GeistVF.woff',
  variable: '--font-geist-sans',
})

❌ 7. turbo_json_parse_error: Found an unknown key 'tasks'

报错信息:

sql 复制代码
turbo_json_parse_error
× Found an unknown key 'tasks'.

原因 :$schema URL 有空格或旧版 turbo 无法解析 schema。

✅ 解决方案 :
升级 turbo 到 2.5.6,并使用稳定 URL:

json 复制代码
{
  "$schema": "https://turborepo.com/schema.v2.json",
  "tasks": {
    "dev": {
      "persistent": true
    },
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "dist/**"]
    }
  }
}

✅ 升级后可安全保留 $schema,支持 VS Code 智能提示。


❌ 8. 后端服务未启动,无日志

现象 :pnpm dev 执行,但后端无 console.log("🚀 Backend server running...")

原因 :apps/backend/package.json 缺少 dev 脚本。

✅ 解决方案 :

添加 dev 脚本:

json 复制代码
"scripts": {
  "dev": "npm run start:dev",
  "start:dev": "ts-node-dev --respawn --transpile-only src/main.ts"
}

✅ 最终配置总结

turbo.json(推荐)

json 复制代码
{
  "$schema": "https://turborepo.com/schema.v2.json",
  "tasks": {
    "dev": {
      "persistent": true
    },
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "dist/**"]
    }
  }
}

apps/backend/package.json

json 复制代码
"scripts": {
  "dev": "npm run start:dev",
  "start:dev": "ts-node-dev --respawn --transpile-only src/main.ts"
}

.gitignore

gitignore 复制代码
node_modules/
.pnpm/
.next/
dist/
.turbo/
.env.local
.env.development
!.env.example

相关推荐
To_OC10 小时前
同样是让 AI 写全栈,为什么别人一句话就够了
前端·前端框架·next.js
FungLeo5 天前
成为全栈·Next.js 网站前台篇·响应式、可访问性与错误状态:内容站不能只验桌面首页
react.js·响应式设计·next.js·移动端适配·成为全栈·web 可访问性
FungLeo6 天前
成为全栈·Next.js 网站前台篇·站点设置如何驱动页头、页脚与 SEO
react·isr·next.js·metadata·成为全栈·站点配置
FungLeo8 天前
成为全栈·Next.js 网站前台篇·同源 BFF 代理:API、附件、Cookie 与跨站写入保护
react·csrf·next.js·bff·成为全栈·route handler
FungLeo8 天前
成为全栈·Next.js 网站前台篇·评论系统:叠楼、回复、删除与内容审核如何落到前台
react.js·内容审核·next.js·评论系统·树形数据·成为全栈
cindershade11 天前
一条请求的接力赛:用运行时责任重画 RSC 边界
性能优化·next.js
zach12 天前
前端落地实战:Next.js 项目 Nginx + PM2 生产部署全流程(附踩坑总结)
前端·pm2·next.js
zach12 天前
Vue/React SPA 打包部署后,子路由刷新 401 未登录问题彻底解决
前端·nginx·next.js
FungLeo14 天前
成为全栈·Next.js 网站前台篇·数据获取与缓存:60 秒再验证背后到底发生了什么
react·isr·next.js·成为全栈·react cache·opennext
名字还没想好☜22 天前
React 文件上传实战:预览 URL 回收、多文件逐个进度与拖拽放置区踩坑
前端·react·next.js