搞定 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源码 去了解具体的实施细节。

书洞笔记

相关推荐
杭州杭州杭州11 分钟前
实验3 微服务介绍以及开发环境搭建
微服务·云原生·架构
on_pluto_17 分钟前
【debug】关于如何让电脑里面的两个cuda共存
linux·服务器·前端
r***869823 分钟前
springboot三层架构详细讲解
spring boot·后端·架构
r***F26231 分钟前
Go-Gin Web 框架完整教程
前端·golang·gin
chilavert31833 分钟前
技术演进中的开发沉思-220 Ajax:XMLHttpRequest 对象
前端·javascript
IT_陈寒1 小时前
Python开发者必看:5个被低估但能提升200%编码效率的冷门库实战
前端·人工智能·后端
g***78911 小时前
鸿蒙NEXT(五):鸿蒙版React Native架构浅析
android·前端·后端
q***71851 小时前
Webpack、Vite区别知多少?
前端·webpack·node.js
千里念行客2401 小时前
国产射频芯片“小巨人”昂瑞微今日招股 拟于12月5日进行申购
大数据·前端·人工智能·科技
小杨快跑~2 小时前
Vue 3 + Element Plus 表单校验
前端·javascript·vue.js·elementui