sample-monorepo 代码质量防线:ESLint 9 + TypeScript strict 模式配置全攻略
【免费下载链接】sample-monorepoSample monorepo setup with npm workspaces and typescript project references项目地址: https://gitcode.com/gh_mirrors/sa/sample-monorepo
sample-monorepo是一个基于 npm workspaces 和 TypeScript project references 的 monorepo 示例工程,它把 ESLint 9 与 TypeScript strict 模式深度结合,为代码质量设下了双重防线。本文将从零拆解这套配置方案,带你掌握 ESLint 9 配置、TypeScript strict 模式开启方法,以及 monorepo 多包场景下的质量管控技巧,无论你是新手还是想改造自家工程的老手,都能快速上手。
为什么 monorepo 更需要 ESLint 9 与 strict 模式?
单体仓库(monorepo)把 app、components、server 等多个包放进同一个仓库,依赖共享、版本统一,但代码质量管控也更容易失控:包与包之间互相引用,任何一个包写出"隐患代码",都可能顺着引用链传导到整个系统。
因此,ESLint 9 配置负责拦截"坏味道"(未使用变量、误提交的 only 测试、console 泄漏),TypeScript strict 模式负责在编译期掐灭类型隐患(隐式 any、空值越界)。两者一前一后,构成完整的代码质量防线。
ESLint 9 配置实战:扁平化配置的新写法
ESLint 9 最大的变化是扁平化配置(flat config)全面取代旧版 .eslintrc。在 sample-monorepo 中,全部规则集中在一个根级eslint.config.js文件里,仓库内所有包共用同一份质量基线。
第一步:引入核心依赖
根目录package.json的 devDependencies 中集中声明了 ESLint 相关依赖,这正是 monorepo 的优势:所有包共享同一套 lint 工具链,版本永远不会漂移。
eslint(^9.32.0):ESLint 9 本体typescript-eslint(^8.38.0):TS 语法分析与类型感知规则eslint-plugin-react-hooks:React Hooks 规则eslint-plugin-no-only-tests:拦截.only()误提交eslint-config-prettier:关闭与 Prettier 冲突的格式规则
第二步:读懂扁平化配置结构
eslint.config.js的骨架非常清晰,核心思路是"数组 + 对象"逐层叠加规则:
- 先用
ignores排除构建产物目录**/dist/ - 引入
@eslint/js的推荐规则(JS 基础规则) - 注册 react-hooks、no-only-tests 两个插件
- 叠加
typescript-eslint的recommendedTypeChecked(类型感知推荐配置) - 最后用
eslint-config-prettier收尾,避免与 Prettier 打架
其中有个细节值得学习:通过for...of循环把类型感知配置的files限定为**/*.{ts,tsx,mts,cts},确保它只作用于 TypeScript 文件,不影响纯 JS 配置。
第三步:关键规则逐一解读
这套配置里的每条规则都"话里有话",我们挑几个重点:
- no-console: error:禁止
console输出,倒逼开发者使用日志工具 - no-only-tests/no-only-tests: error:防止
it.only()、test.only()被误提交到 CI,这是测试翻车的经典元凶 - no-unused-vars:未使用变量直接报错,并允许
_前缀参数"豁免"(回调占位参数很常见) - react-hooks/rules-of-hooks + exhaustive-deps:React 19 项目中 Hooks 调用顺序与依赖数组的"双保险"
更贴心的是,**/*.test.{ts,tsx,mts,cts}测试文件中单独关闭了@typescript-eslint/no-floating-promises,因为 Node 原生测试运行器的describe()/it()会返回 Promise,避免了测试文件里"误报"。
TypeScript strict 模式配置:从零开启强类型防线
基础配置:tsconfig.base.json 是总闸
sample-monorepo 的所有类型约束都收敛在根级tsconfig.base.json,各包通过extends继承,保证全仓库配置一致。其中与代码质量直接相关的开关包括:
"strict": true:一键开启全部严格类型检查(noImplicitAny、strictNullChecks、strictFunctionTypes 等全部联动)"noUncheckedIndexedAccess": true:索引访问自动附加undefined,杜绝"数组越界不知道"的运行时崩溃"verbatimModuleSyntax": true:强制区分类型导入与值导入,配合import type使用更规范"composite": true:允许作为 project references 被其他项目引用"declaration"与"sourceMap":发布包自动生成.d.ts类型声明,让使用者获得完整的类型提示
项目引用:solution-style 的 tsconfig.json
根级tsconfig.json是一个"解决方案式"配置,files为空数组,只通过references指向三个子项目:
packages/app/srcpackages/components/srcpackages/server/src
各包的tsconfig.json则继承基础配置并声明自己的依赖关系,例如packages/app/src/tsconfig.json引用packages/components/src,packages/server/src/tsconfig.json引用packages/app/src。这样tsc --build就能按依赖顺序增量编译,类型检查也会自动覆盖整条引用链。
各包配置示例
以 components 包为例,packages/components/src/tsconfig.json只需要三行核心内容:
{ "extends": "../../../tsconfig.base.json", "compilerOptions": { "outDir": "../dist" } }依赖型包再加一个references字段即可。这种"一处定义、处处继承"的写法,让新增一个包的成本降到最低。
一键执行:lint 与构建的自动化脚本
配置写得再好,也要能一键跑起来。根package.json中的脚本设计很讲究:
npm run lint:执行 ESLint 检查整个仓库npm run build:执行tsc --build增量编译全部包npm run pretest:测试前自动先跑 lint 和 build
这意味着lint 和类型检查被硬编码进测试流程,任何一次npm test之前,代码质量防线都会先行生效,从流程上杜绝"带病上线"。
常见问题与最佳实践小结
- ESLint 9 升级后没有 .eslintrc 了?对,新版统一使用
eslint.config.js扁平配置,旧配置可用工具自动迁移 - 类型感知规则跑得慢?
recommendedTypeChecked需要额外做类型解析,建议像本项目一样限定files范围,并把dist排除在外 - 严格模式报错太多?建议新项目直接开启
strict: true,老项目则分批开启,先修noImplicitAny再逐步收紧 - 多包配置如何保持一致?牢记 monorepo 三件套:根级共享
tsconfig.base.json+ 根级eslint.config.js+ 根级统一 devDependencies,包内只保留差异项
动手实践:克隆仓库亲手体验
想要完整体验这套配置的威力,可以克隆仓库到本地跑一遍:
git clone https://gitcode.com/gh_mirrors/sa/sample-monorepo npm i npm run lint npm run build npm test亲自观察 lint 报错如何拦截隐患代码、strict 模式如何在你写错类型时第一时间"喊停"。这可能是你迈向高质量 TypeScript 工程管理的第一步,也是 monorepo 工程质量管控最值得借鉴的样板之一。
【免费下载链接】sample-monorepoSample monorepo setup with npm workspaces and typescript project references项目地址: https://gitcode.com/gh_mirrors/sa/sample-monorepo
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考