「实战指南」从零构建 Monorepo 项目:基于 pnpm 的 TypeScript 与 ESLint 最佳实践
1. 为什么选择 pnpm 管理 Monorepo如果你曾经在多个前端项目之间切换肯定遇到过这样的场景每个项目都要重新安装一遍 node_modules硬盘空间被重复的依赖占满不同项目的依赖版本还不一致。这就是传统多仓库Multirepo的痛点而 Monorepo 正是为了解决这些问题而生。pnpm 的硬链接机制让它成为 Monorepo 的绝配。我实测过一个包含 10 个子项目的仓库相比传统 npm 安装磁盘空间节省 60% 以上依赖安装速度提升 3 倍所有子项目共享同一份依赖副本它的 workspace 功能更是把 Monorepo 管理简化到极致。比如你想在子项目之间建立依赖关系只需要一条命令pnpm add demo/core --filter demo/web-app --workspace这个命令会自动在 web-app 的 package.json 里生成demo/core: workspace:*的引用完全不需要手动处理文件路径。2. 五分钟快速搭建 Monorepo 骨架先确保你的环境满足node -v # 需要 16.17 pnpm -v # 需要 7.0.0创建项目骨架就像搭积木一样简单mkdir monorepo-demo cd monorepo-demo pnpm init关键是要创建这个目录结构├── package.json ├── pnpm-workspace.yaml # 工作区配置文件 ├── packages/ # 核心包目录 │ └── core/ # 工具库 └── apps/ # 应用目录 └── web-app/ # 前端应用pnpm-workspace.yaml 是这个仓库的中枢神经配置非常简单packages: - packages/* - apps/*3. TypeScript 配置的黄金法则在根目录安装公共 TS 配置pnpm add typescript types/node -D -w创建 tsconfig.base.json 作为所有子项目的基准配置{ compilerOptions: { target: ES2020, module: ESNext, strict: true, paths: { demo/*: [packages/*/src] // 路径别名 } } }子项目只需要继承并微调// packages/core/tsconfig.json { extends: ../../tsconfig.base.json, compilerOptions: { outDir: dist } }我特别推荐使用路径别名代替相对路径。比如原本的../../../utils可以简化为demo/utils代码可读性直接提升一个档次。4. ESLint 统一代码风格在根目录安装 ESLint 全家桶pnpm add eslint typescript-eslint/parser typescript-eslint/eslint-plugin -D -w创建 .eslintrc.cjs 配置module.exports { root: true, extends: [ eslint:recommended, plugin:typescript-eslint/recommended ], rules: { typescript-eslint/no-unused-vars: error, no-console: warn } }对于 React 项目可以在 apps/web-app 下创建扩展配置{ extends: [../../.eslintrc.cjs], plugins: [react-hooks], rules: { react-hooks/rules-of-hooks: error } }这样既保持了基础规则统一又能针对不同技术栈灵活调整。5. 依赖管理的三个段位青铜段位基础安装# 公共开发依赖 pnpm add jest -D -w # 子包专属依赖 pnpm add axios --filter demo/web-app白银段位版本控制// 根目录 package.json pnpm: { overrides: { react: 18.2.0, // 强制统一版本 typescript: ^5.0.0 } }黄金段位拓扑构建# 先构建依赖包 pnpm --filter demo/core run build # 再构建应用 pnpm --filter demo/web-app run build6. Vite 项目的特别处理对于使用 Vite 的前端应用需要特别注意路径映射// apps/web-app/vite.config.ts export default defineConfig({ resolve: { alias: { demo/core: path.resolve(__dirname, ../../packages/core/src) } } })推荐开启缓存共享提升构建速度cacheDir: ../../.vite, // 共享缓存目录 build: { outDir: ../../dist/web-app // 统一输出目录 }7. 幽灵依赖破解秘籍遇到Module not found报错时用这个命令快速定位问题pnpm why lodash解决方案分三步检查是否真的缺少声明在对应子包安装明确依赖更新类型声明文件8. 我的目录结构进化史经过多个项目迭代这个结构最实用monorepo-demo/ ├── .github/ # CI/CD 配置 ├── configs/ # 共享配置 │ ├── eslint/ │ └── jest/ ├── packages/ │ ├── core/ # 基础库 │ └── ui/ # 组件库 └── apps/ ├── web-app/ # 用户端 └── admin/ # 管理端9. 开发调试的终极技巧同时监控多个子包变更# 终端1监控工具包变更 pnpm --filter demo/core run build --watch # 终端2启动前端应用 pnpm --filter demo/web-app run dev这样修改 core 包的代码会实时触发重建web-app 会自动热更新。10. 发布私有包的最佳路径发布流程比想象中简单cd packages/core pnpm version patch # 更新版本号 pnpm publish --access public记得在根目录 .npmrc 配置私有仓库地址demo:registryhttps://your-private-registry
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2435935.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!