当前位置: 首页 > news >正文

【实践】Monorepo 工程化:沉淀可复用的配置规则

一、背景介绍

在上次完成最小可用 Vue Monorepo 之后,我们遇到一个关键问题:配置一旦被复制成 N 份,就不再是统一规范,而是会各自独立演化的副本

Monorepo 提供了更优雅的方案:把配置本身当作 npm 包发布到 workspace 内部,其他包通过继承这些配置来生效。例如 TypeScript 的 extends、ESLint 的 import flat config、函数工厂(vitest 预设)。

这样可以做到:升级配置只改一个地方,所有包同步生效。这才是 Monorepo 真正的杠杆所在——不是更快地构建,而是更低成本地维护规范

二、方案分析

本次主要解决“好协作”问题,让多人/多包开发在同一套规则下进行,并把这些规则沉淀成可复用的 package。

将 ESLint、TypeScript、Vitest 三类配置从“每个包各复制一份”,改为“通过依赖一份共享包来继承”。

2.1 整体方案

  1. 新增 3 个内部基础包
    • @repo/tsconfig:所有包的 TS 配置基线
    • @repo/eslint-config:所有包的 ESLint 规则基线(flat config)
    • @repo/vitest-preset:所有包的 Vitest 预设工厂
  2. 为现有 3 个包接入基础设施
    • apps/webpackages/uipackages/utils从共享包继承配置
    • packages/utilspackages/ui补充单元测试
    • 提供统一脚本:pnpm lint/pnpm typecheck/pnpm test/pnpm format
  3. 根目录补充提交侧守护
    • Prettier + EditorConfig:统一代码格式
    • husky + lint-staged:commit 前自动 lint 改动文件
    • commitlint:约束提交信息风格

三、实操步骤

步骤 1:共享 TypeScript 配置(@repo/tsconfig)

1.1 包结构
packages/tsconfig/ ├── package.json ├── base.json # 通用基线 ├── vue.json # Vue 项目变体 └── node.json # Node 项目变体
1.2 package.json
{"name":"@repo/tsconfig","version":"0.0.0","private":true,"files":["base.json","vue.json","node.json"]}

注意:这个包没有任何代码入口,只是一组 JSON 文件的集合。pnpm 通过 workspace 链接将它放进消费者的 node_modules,TypeScript 的 extends 通过 Node resolution 找到。

⚠ 注意:files是发布/共享 npm 包时的白名单配置,用来精确指定哪些文件/文件夹会被包含在最终发布的包里,未在列表中的文件默认不会被打包发布。

1.3 base.json(通用基线)
{"$schema":"https://json.schemastore.org/tsconfig","compilerOptions":{"target":"ES2022","module":"ESNext","moduleResolution":"Bundler","lib":["ES2022"],"strict":true,"noUncheckedIndexedAccess":true,"noImplicitOverride":true,"esModuleInterop":true,"resolveJsonModule":true,"isolatedModules":true,"skipLibCheck":true,"verbatimModuleSyntax":true,"forceConsistentCasingInFileNames":true,"useDefineForClassFields":true}}

几个有意为之的选择:

  • strict: true+noUncheckedIndexedAccess:进一步收紧类型安全
  • moduleResolution: "Bundler":现代打包器(Vite/esbuild)通用方案
  • verbatimModuleSyntax: true:强制 import/export 语法精确,配合 ESLint 可以发现混用 type/value 的问题
  • isolatedModules: true:保证每个文件可被独立转译,是 esbuild/SWC 的前置条件
1.4 vue.json 与 node.json

vue.json(在 base 基础上加 DOM 相关 lib)

{"extends":"./base.json","compilerOptions":{"jsx":"preserve","lib":["ES2022","DOM","DOM.Iterable"]}}

node.json(在 base 基础上加 Node 类型)

{"extends":"./base.json","compilerOptions":{"lib":["ES2022"],"types":["node"]}}

步骤 2:共享 ESLint 配置(@repo/eslint-config)

ESLint 9 已经全面切到 flat config,这是当前主流,新建项目应直接使用 flat。

2.1 包结构
packages/eslint-config/ ├── package.json ├── base.js # 通用 TS/JS 规则 └── vue.js # 在 base 之上叠加 Vue 规则
2.2 package.json 关键设计
{"type":"module","name":"@repo/eslint-config","exports":{"./base":"./base.js","./vue":"./vue.js"},"dependencies":{"@eslint/js":"^9.13.0","eslint-config-prettier":"^9.1.0","eslint-plugin-vue":"^9.30.0","globals":"^15.11.0","typescript-eslint":"^8.12.0","vue-eslint-parser":"^9.4.3"},"peerDependencies":{"eslint":"^9.0.0"}}

关键点:

  • 把 ESLint 插件作为 dependencies:消费包不必各自安装一堆插件,只需依赖@repo/eslint-config即可
  • ESLint 本身放 peerDependencies:让消费方决定 ESLint 版本,避免多版本共存
  • 这是“配置即依赖”的核心模式:配置包负责规则版本管理,消费包只关心继承
2.3 base.js
importjsfrom"@eslint/js";importtseslintfrom"typescript-eslint";importprettierfrom"eslint-config-prettier";
http://www.jsqmd.com/news/717761/

相关文章:

  • #P4538.第2题-基于混淆矩阵,推导分类模型的核心评估指标
  • Git Folder Dashboard
  • 终极指南:如何利用checkm8漏洞解锁iOS设备的无限可能
  • AI剧本杀创建房间全流程界面设计报告
  • 【花雕学编程】Arduino BLDC 之差速驱动机器人运动学逆解分配
  • CSS布局实战技巧:从基础到高级
  • Phi-3.5-mini-instruct效果展示:256 tokens内精准归纳长文本,实测对比效果
  • D13: 文化建设:鼓励实验,容忍失败
  • 一套键鼠操作两台电脑
  • Phi-3.5-mini快速上手:小白友好的文本生成模型部署指南
  • SQL嵌套查询中常见报错排查_语法与权限处理
  • 代码随想录算法训练营第四十二天|LeetCode 188 买卖股票的最佳时机 IV、LeetCode 309 最佳买卖股票时机含冷冻期、LeetCode 714 买卖股票的最佳时机含手续费
  • bgp组网中同一层隔离一台设备怎么操作?
  • Flux2-Klein-9B-True-V2环境部署详解:从Git克隆到模型服务的完整流程
  • 传统企业应用集成
  • 企业宣传视频制作:Sonic数字人实战案例,低成本生成专业内容
  • 硬件模糊测试技术:GoldenFuzz框架解析与应用
  • Real Anime Z 网络通信优化:提升模型API响应速度实战
  • BeepBank-500:UI声音设计与心理声学研究的标准化数据集
  • real-anime-z多场景落地:同人创作、轻小说配图、社交平台头像批量生成
  • Convai平台:AI驱动的游戏NPC交互革命
  • 联邦学习框架整合:Flower与NVIDIA FLARE实践指南
  • 基于环境自适应架构的降低AIGC检测率系统
  • 2025-2026年天璐纺织电话查询:使用指南与功能性面料选购注意事项 - 品牌推荐
  • Delphi老项目福音:用PaddleOCRSharp封装DLL搞定验证码识别(附完整源码)
  • CSS三大选择器终极对决!谁才是新手写样式的“最优解”?
  • Leather Dress Collection多场景落地:社交媒体配图/产品目录/设计草稿三合一
  • Flutter状态管理深度解析
  • Flutter UI组件高级使用指南
  • AI智能文档扫描仪算法优势:相比深度学习更可控的处理逻辑