搭建简易版monorepo + turborepo

背景

  • 项目结构:pnpm Monorepo
    • packages/ui:React 组件库(使用 Vite + TS 打包)
    • apps/react-demo:React 应用,依赖 @my-org/ui
  • 目标:
    • ✅ 开发环境:修改 ui 源码 → 自动热更新到 react-demo
    • ✅ 生产构建:react-demo 能正确打包 @my-org/ui

遇到的问题 & 解决方案

❌ 问题 1:生产构建时报错 ------ @my-org/ui 无法解析

arduino 复制代码
// 错误信息
[vite]: Rolldown failed to resolve import "@my-org/ui" ...

🔎 根本原因:

  • react-demo 的 node_modules/@my-org/ui/ 中 没有 ****dist/ ****目录
  • 导致 Vite 找不到 JS 入口文件(如 ui.js)

✅ 解决步骤:

  1. 确认 ****packages/ui/package.json ****包含 ****"files": ["dist"]
    → 否则 pnpm 不会把 dist 链接到 consumer 的 node_modules
  2. 先构建 UI 库
css 复制代码
pnpm --filter @my-org/ui build
  1. 确保 ****react-demo ****声明了依赖
sql 复制代码
pnpm add @my-org/ui@workspace:* --filter react-demo
  1. 强制刷新链接
css 复制代码
pnpm install --force

💡 关键认知:pnpm workspace 链接 ≠ 实时目录映射 ,它只链接 package.json 中声明的文件(通过 files),且需在 dist 存在后执行 install。

❌ 问题 2:package.json 入口文件名与实际输出不一致

  • 配置写的是:
json 复制代码
"main": "./dist/index.js"
  • 但 Vite 默认输出:
bash 复制代码
dist/ui.js
dist/ui.mjs

🔎 后果:

  • 即使 dist 被链接,Vite 仍尝试加载不存在的 index.js → 模块解析失败

✅ 解决方案(二选一):

方案 操作
A(推荐) 修改 package.json指向真实文件: "main": "./dist/ui.js"
B 修改 vite.config.ts强制输出 index.js: fileName: (format) => index.${format === 'es' ? 'mjs' : 'js'}``

✅ 最终选择 方案 A,避免改构建配置,更简单直接。

❌ 问题 3:即使 files 正确,dist 仍不出现

运行 pnpm install --force 后,node_modules/@my-org/ui/dist 依然不存在。

🔎 深层原因:

  • react-demo/package.json 未声明对 ****@my-org/ui ****的依赖
  • pnpm 不会自动链接未声明的 workspace 包

✅ 解决:

sql 复制代码
pnpm add @my-org/ui@workspace:* --filter react-demo

→ 显式建立依赖关系,pnpm 才会创建 symlink 并包含 dist/。

📌 这是 Monorepo 的核心规则: "未声明 = 不存在"

✅ 问题 4:开发环境如何实现热更新?

生产构建成功后,需支持开发时实时编辑 ui 组件。

✅ 解决方案:

  1. 在 ****react-demo/vite.config.ts ****中添加 alias:
css 复制代码
resolve: {
  alias: {
    '@my-org/ui': path.resolve(__dirname, '../../packages/ui/src')
  }
}
  1. 启动开发服务器:
css 复制代码
pnpm --filter react-demo dev

💡 原理:Vite 直接编译 ui/src 源码(而非 dist),天然支持 HMR 和 TSX。


🧪 验证清单(最终状态)

检查项 命令 预期结果
UI 库已构建 ls packages/ui/dist 有 ui.js, ui.mjs, *.d.ts
依赖已声明 grep "@my-org/ui" apps/react-demo/package.json 有 "@my-org/ui": "workspace:*"
链接已同步 ls apps/react-demo/node_modules/@my-org/ui/dist 文件存在
生产构建成功 pnpm --filter react-demo build 无报错,生成 dist/
开发热更新 修改 ui/src/Button.tsx→ 浏览器自动刷新 ✅ 实时生效

📚 经验总结

场景 关键配置
生产构建 package.json的 main/module必须匹配真实文件名 + "files": ["dist"]
依赖链接 Consumer 必须在 package.json中显式声明 workspace:*依赖
开发体验 通过 Vite alias指向 src,绕过 dist,实现 HMR
构建顺序 先 build ui→ 再 pnpm install→ 最后 build app
相关推荐
仿生狮子3 小时前
OpenAI 攻下千禧年难题之后,开发者似乎无动于衷
前端·数学·vibecoding
夏幻灵6 小时前
JavaScript this 面试:五种绑定规则、优先级与常见面试陷阱
开发语言·javascript·面试
Lvan的前端笔记6 小时前
docker:每个前端项目一个 Nginx 容器还是只有一个Nginx容器
前端·nginx·docker
三天不学习7 小时前
Egg.js 4 突然爆火,原因是否归结于AI 原生落地需求爆发?
前端·javascript·全栈·egg.js
xcs194057 小时前
前端 vue 的前端页面debugger 进不去
前端·javascript·vue.js
明月_清风8 小时前
Deno 终局来了:从挑战 Node 到被 Cloudflare 收编
前端·后端·node.js
Csvn9 小时前
框架性能优化
前端
回眸&啤酒鸭11 小时前
【回眸】OpenSwarm 多智能体协作系统实战指南
大数据·前端·人工智能
用户693717500138411 小时前
2026,程序员的时代拐点到了
android·前端·后端
大龄秃头程序员11 小时前
一次 iBeacon + BLE 无感解锁方案的实现记录
前端