搞定 Monorepo,工程能力升级,升职加薪快人一步

背景

随着前端工程越来越大,模块越来越多,代码复用性越来越强,模块之间的依赖关系也越来越复杂,导致开发效率低下,维护成本高,代码质量难以保证。因此,我们需要一种能够有效管理这些模块的工具,以便更好地组织和管理我们的代码。

monorepo 是一种将多个模块放在同一个代码仓库中的管理方式。它可以将多个模块之间的依赖关系清晰地展示出来,使得模块之间的协作更加高效。同时,monorepo 还可以方便地进行模块的发布和更新,使得整个项目的管理更加简单。

multirepo vs monorepo

multirepo

优点:

  • 每个模块独立,互不影响
  • 模块可以独立发布和更新
  • 模块可以独立部署

缺点:

  • 模块之间的依赖关系复杂,难以管理
  • 模块之间的协作效率低
  • 模块之间的发布和更新需要手动处理

monorepo

优点:

  • 模块之间的依赖关系清晰,易于管理
  • 模块之间的协作效率高
  • 模块之间的发布和更新可以自动化处理

缺点:

  • 模块之间的耦合度高,难以独立发布和更新
  • 模块之间的部署需要统一处理

方案选型

multirepomonorepo 各有优缺点,选择哪种方式取决于项目的具体需求和团队的技术栈。如果项目规模较小,模块之间的依赖关系简单 ,可以选择 multirepo;如果项目规模较大,模块之间的依赖关系复杂 ,可以选择 monorepo

常见 monorepo 管理工具

  • pnpm
  • npm
  • yarn
  • lerna
  • nx
  • rush
  • ...

目录结构

shell 复制代码
├── packages # 模块目录
│   ├── package-a
│   │   ├── src
│   │   ├── package.json
│   ├── package-b
│   │   ├── src
│   │   ├── package.json
|------ apps  # 应用目录
│   ├── app-a
│   │   ├── src
│   │   ├── package.json
│   ├── app-b
│   │   ├── src
│   │   ├── package.json
├── packages.json # 项目根目录的 package.json
├── pnpm-workspace.yaml # pnpm 工作区配置文件
├── pnpm-lock.yaml
├── package.json
├── README.md

pnpm-workspace.yaml

pnpm-workspace.yamlpnpm 的工作区配置文件,用于指定工作区中的模块和应用的目录。

yaml 复制代码
packages:
  - "packages/*"
  - "apps/*"

环境版本锁定

monorepo 项目中,我们需要确保所有模块使用相同的环境版本,以避免出现环境不一致的问题。我们可以通过在 package.json 中指定 engines 字段来实现环境版本锁定。

json 复制代码
// packages.json
"engines": {
  "node": ">=14.0.0",
  "pnpm": ">=7.0.0"
}

严格模式,确保安装不符合要求的版本报错显示。

yaml 复制代码
#.npmrc
engine-strict=true

规范的统一化管理

TypeScript

monorepo 项目中,我们可以使用 TypeScript 来提高代码的可维护性和可读性。我们可以通过在 tsconfig.json 中指定 compilerOptions 字段来实现 TypeScript 的配置。

shell 复制代码
pnpm -Dw add typescript @types/node

根目录下创建 tsconfig.json 文件,子包统一配置 TypeScript 编译选项。

json 复制代码
// tsconfig.json
"compilerOptions": {
  "module": "esnext",
  "target": "esnext",
  "strict": true,
  "skipLibCheck": true,
  "baseUrl": "",
}

每个子包下创建 tsconfig.json 文件,子包独立配置 TypeScript 编译选项。

json 复制代码
{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "outDir": "dist",
    "rootDir": "src",
    "declaration": true,
    "declarationDir": "dist/types"
  },
  "include": ["src"]
}

prettier

prettier 是一个代码格式化工具,可以自动格式化代码,使其符合指定的代码风格。

shell 复制代码
pnpm -Dw add prettier

根目录下创建 prettier.confiig.js 文件,子包统一配置 prettier 格式化选项。

js 复制代码
module.exports = {
  semi: true,
  trailingComma: "es5",
  singleQuote: true,
  printWidth: 80,
  tabWidth: 2,
};

排除文件,避免格式化不必要的文件。

yaml 复制代码
#.prettierignore
node_modules
dist

git 提交规范

  1. 排除文件
yaml 复制代码
#.gitignore
node_modules
dist
  1. commitizen

commitizen 是一个用于规范 git commit 提交的工具,可以确保提交信息符合一定的规范,从而提高代码的可维护性和可读性。

shell 复制代码
pnpm -Dw add @commitlint/cli @commitlint/config-conventional commitizen cz-git
  • @commitlint/clicommitlint 的命令行工具,用于检查提交信息是否符合规范。
  • @commitlint/config-conventionalcommitlint 的规范配置,用于指定提交信息的格式。
  • commitizen 是一个用于规范 git commit 提交的工具,可以确保提交信息符合一定的规范。
  • cz-git 是一个用于规范 git commit 提交的工具,可以确保提交信息符合一定的规范。
json 复制代码
// package.json
"scripts": {
  "commit": "git-cz"
},
"config": {
  "commitizen": {
    "path": "./node_modules/cz-git"
  }
}

创建 commitlint.config.js 文件,去定义 i 一些 commitlint 提交规范。

js 复制代码
module.exports = {
  extends: ["@commitlint/config-conventional"],
  rules:{
    "type-enum":[2, "always",]
  }
};
  1. husky

husky 是一个用于规范 git commit 提交的工具,可以确保提交信息符合一定的规范,从而提高代码的可维护性和可读性。

shell 复制代码
# 安装 husky
pnpm -Dw add husky
# 初始化 husky
pnpx husky init

配置

yaml 复制代码
#!/usr/bin/env sh
pnpm run lint

以上是对整个工程做的一些统一的一些规范化管理,可以根据自己的项目需求,做更多的规范管理。

代码的统一化管理

统一打包

这个统一打包主要针对公共的库,比如 utilshookscomponents 等等,这些库是各个应用都会用到的,所以我们可以统一打包,然后发布到 npm 上,这样各个应用就可以直接安装使用了。

  • 创建打包文件

可以再根目录创建 scripts 文件夹,然后创建 build.js 文件,用于打包公共库。

具体参考vue3的打包方式,使用rollup进行打包。build.js

  • 添加脚本

package.json 中添加打包脚本。

json 复制代码
"scripts": {
  "build": "node scripts/build.js"
}
  • 执行打包
shell 复制代码
pnpm run build

建立包依赖

通过软链接的方式,将公共库链接到各个应用中,这样各个应用就可以直接使用公共库了。

json 复制代码
// package.json
"dependencies": {
  "package-a": "workspace:*"
}

发布

  • 登录
shell 复制代码
pnpm login
  • 发布
shell 复制代码
pnpm publish

总结

monorepo 是一种代码管理方案,是一个策略、思想,而不是一个工具。主要就是通过规范化、统一化的方式,来提高代码的可维护性和可读性,从而提高开发效率。以上只是简单的介绍了 monorepo 方案的实施,具体的实现还需要根据项目的需求和团队的技术栈来决定。Vue3 采用的就是 monorepo 方式进行项目代码管理。 有兴趣的可以对照 vue3源码 去了解具体的实施细节。

书洞笔记

相关推荐
小奋斗4 小时前
浏览器原理之详解渲染进程
前端·面试
猪哥帅过吴彦祖4 小时前
Flutter 系列教程:常用基础组件 (下) - `TextField` 和 `Form`
前端·flutter·ios
刘发财4 小时前
一行代码将html页面转成矢量PDF
前端·javascript·vue.js
Dorian_Ov04 小时前
GeoServer添加要素图层的SLD样式文件以及中文乱码相关解决方案
前端·gis
Holin_浩霖4 小时前
前端开发者的 Web3 全图解实战 一
前端
uhakadotcom4 小时前
deno在2025年新出了哪些api可供使用?
前端·面试·github
uhakadotcom4 小时前
2025年honojs提供了哪些新的基础能力与API可以使用?
前端·javascript·面试
Pluto5384 小时前
第一个成功在APP store 上架的APP
前端·后端·cursor
SWAYING4 小时前
每天不到1毛钱,用AI自动追踪GitHub热门项目并生成营销文案 | Cursor全程开发
前端·后端