# FLY 哥万字长文带你入门 monorepo 多包实践
# 前言
大家好,我是 Fly 哥, 之前写博客的仓库,还是用的原生的 html 和 js 也没有引入 ts , 和一些工程化的东西, 所以自己从新搭建了一套前端项目架构 基于 lerna + yarn 的 monrepo 的仓库, 主要是后面会学习输出的一些东西, 整个架子先搭建起来。
1. 2d 和 3d 公共 util 的封装
2. 个人 npm 包的发布 **(rollup)**
3. 2d react 项目 搭建**(vite)**
4. 3d react 项目 搭建 **(webpack)**
5. 搭建一套基于**webpack 5** 的 cli
每个项目都有一些特定的依赖, 但是也会有一些相同的依赖。 比如 eslint、 babel 的一些基础配置,或者一些通用的脚本文件。读完本篇文章你可以学到 **从 0 到 1 搭建 monorepo 前端工程化项目** 如下图所示:
![项目架构图](https://ztifly.oss-cn-hangzhou.aliyuncs.com/image-20220330210009155.png)
# 为什么使用 monorepo
monorepo 是一种将多个项目代码存储在一个仓库里的软件开发策略("mono" 来源于希腊语 μόνος 意味单个的,而 "repo",显而易见地,是 repository 的缩写)。将不同的项目的代码放在同一个代码仓库中,这种「把鸡蛋放在同一个篮子里」的做法可能乍看之下有些奇怪,但实际上,这种代码管理方式有很多好处,无论是世界一流的互联网企业 Google,Facebook,还是社区知名的开源项目团队 Babe、都使用了 monorepo 策略管理他们的代码。 **这是 Taro 的官方源码库:**
![taro](https://ztifly.oss-cn-hangzhou.aliyuncs.com/image-20220330204513476.png)
至于他的优点如下:
1. 代码重用将变得非常容易:由于所有的项目代码都集中于一个代码仓库,我们将很容易抽离出各个项目共用的业务组件或工具,并通过 TypeScript,Lerna 或其他工具进行代码内引用;
2. 赖管理将变得非常简单, 可以轻松的做到版本依赖管理 和版本号自动升级
3. 发布 npm 包 也很特别简单, 提取公共方法 直接公共包,可以快速发布到 npm 上
4. 还有一个 最大的 优点 就是 **避免重复安装包, 减少的磁盘空间, 降低了构建时间**
这两项好处全部都可以由一个成熟的包管理工具来完成,对前端开发而言,即是 yarn(1.0 以上)或 npm(7.0 以上)通过名为 workspaces 的特性实现的(⚠️ 注意:支持 workspaces 特性的 npm 目前依旧不是 LTS 版本)。
# yarn
这里的话 我们全局安装 yarn
```js
npm install yarn -g
```
然后新建一个文件夹 进入到目录中执行
```js
yarn init
```
会在项目的根目录生成 package.json
这时候我们在项目根目录
新建 packages 目录
在 package.json 新增下面字段 **workspace**
```json
{
"name": "yarn-test",
"version": "1.0.0",
"private": true,
"workspaces": ["packages/*"],
"main": "index.js",
"license": "MIT"
}
```
表示工作区是 packages 下的所有子目录,
**private: true** 表示项目的根目录 不会被发布出去
假设项目中有 foo 和 bar 两个 package:
```text
mono-demo/
|--package.json
|--packages/
| |--foo/
| | |--package.json
| |--bar/
| | |--package.json
```
### **yarn workspace <workspace_name> <command>**
在指定的 package 中运行指定的命令。
```text
# 在foo中添加react,react-dom作为devDependencies
yarn workspace foo add react react-dom --dev
# 移除bar中的lodash依赖
yarn workspace bar remove lodash
# 运行bar中package.json的 scripts.test 命令
yarn workspace bar run test
```
### **yarn workspaces run <command>**
在所有 package 中运行指定的命令,若某个 package 中没有对应的命令则会报错。
```text
# 运行所有package(foo、bar)中package.json的 scripts.build 命令
yarn workspaces run build
```
### **yarn workspaces info [--json]**
查看项目中的 workspace 依赖树。
例如我的 bar 依赖了 foo,如下:
```text
// bar/package.json
{
"name": "bar",
"version": "1.0.0",
"dependencies": {
"foo": "^1.0.0"
}
}
```
在项目中的依赖结构是这样的(假设 foo/package.json 的版本匹配 bar 的依赖版本,否则会另外安装一个匹配的 foo):
```text
/package.json
/yarn.lock
/node_modules
/node_modules/foo -> /packages/foo
/packages/foo/package.json
/packages/bar/package.json
```
那么运行`yarn workspaces info`会得到如下输出:
```text
yarn workspaces
{
"bar": {
"location": "packages/bar",
"workspaceDependencies": [
"foo"
],
"mismatchedWorkspaceDependencies": []
},
"foo": {
"location": "packages/foo",
"workspaceDependencies": [],
"mismatchedWorkspaceDependencies": []
}
}
```
比如我的一些依赖是所有 package 通用的 比如 eslint、babel... 我们就使用下面的这个命令 加一个 -W 就可以了
### **yarn <add|remove> <package> -W**
- -W: --ignore-workspace-root-check ,允许依赖被安装在 workspace 的根目录
管理根目录的依赖。
```text
# 安装eslint作为根目录的devDependencies
yarn add eslint -D -W
```
# lerna
**[Lerna](https://link.zhihu.com/?target=https%3A//github.com/lerna/lerna%23readme)**是社区主流的 monorepo 管理工具之一,集成了依赖管理、版本发布管理等功能。
使用 Learn 管理的项目的目录结构和 yarn workspace 类似。
我们根目录安装
```js
yarn add lerna -D -W
```
然后执行
```js
npx lerna init
```
然后项目中就会生成 lerna.json
我们进行下面配置
```tsx
{
"packages": ["packages/*"],
"command": {
"run": {
"npmClient": "yarn"
},
"publish": {
"ignoreChanges": ["ignored-file", "*.md"],
"message": "chore(release): publish",
"registry": "https://npm.pkg.github.com"
}
},
"version": "independent",
"useWorkspaces": true,
"npmClient": "yarn"
}
```
这里 同样使用 workspace, 指定项目 使用 yarn 进行包管理
这里有一个很重要的字段 **"version": "independent"**,
这是表示使用 独立模式 Lerna 项目允许维护人员彼此独立地增加包版本。每次发布时,您都会收到有关已更改的每个包的提示,以指定它是补丁、次要、主要还是自定义更改。 独立模式允许您更具体地更新每个包的版本,并且对一组组件有意义。这里搭配 [semantic-release](https://github.com/semantic-release/semantic-release) 这个 npm 包 感兴趣的可以去了解下。
下面我介绍一些 lerna 的一些命令: 大家可以去[github lerna](https://github.com/lerna/lerna) 看的更多
**lerna bootstrap**:等同于 lerna link + yarn install,用于创建符合链接并安装依赖包;
**lerna run:**会像执行一个 for 循环一样,在所有子项目中执行 npm script 脚本,并且,它会非常智能的识别依赖关系,并从根依赖开始执行命令;
**lerna exec**:像 lerna run 一样,会按照依赖顺序执行命令,不同的是,它可以执行任何命令,例如 shell 脚本;
**lerna publish:**发布代码有变动的 package,因此首先您需要在使用 Lerna 前使用 git commit 命令提交代码,好让 Lerna 有一个 baseline;
**lerna add:**将本地或远程的包作为依赖添加至当前的 monorepo 仓库中,该命令让 Lerna 可以识别并追踪包之间的依赖关系,因此非常重要
# tsconfig
作为一个 ts 项目, 在项目根目录安装 ts
```
yarn add typescript -D -W
```
首先在项目中生成 tsconfig.json
```tsx
npx tsc --init
```
然后在项目根目录生成 tsconfig.json 这里 划重点 我们把基础的 tsconfig.json 放在这里 ,然后 新建一个项目 生成 tsconfig.json 都是继承根目录的 tsconfig.json 类似于这样
```tsx
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"target": "es2018",
"module": "ESNext",
"o
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
【项目资源】: 包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。 包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。
资源推荐
资源详情
资源评论
收起资源包目录
基于webpack 5 + lerna 的 可视化学习仓库.zip (84个子文件)
资料总结
yarn.lock 468KB
babel.config.js 961B
.eslintcache 8KB
.prettierrc 127B
.github
workflows
deploy.yml 845B
src
index.ts 124B
.husky
commit-msg 70B
pre-push 55B
pre-commit 59B
commitlint.config.js 69B
CHANGELOG.md 19KB
.idea
fly.iml 458B
vcs.xml 180B
inspectionProfiles
Project_Default.xml 251B
modules.xml 258B
.gitignore 104B
tsconfigs
cmj.json 84B
tsup.config.ts 151B
.cz-config.js 2KB
package.json 4KB
public
index.html 292B
package-lock.json 1.37MB
types
index.d.ts 210B
.eslintrc.json 2KB
index.html 492B
lerna.json 338B
.gitignore 168B
.eslintignore 22B
tsconfig.json 1KB
learn.ts 3KB
test.ts 2KB
.npmrc 37B
README.md 27KB
.yarnrc 43B
postcss.config.js 672B
packages
esbuild-import-loader
src
index.ts 2KB
package.json 1KB
package-lock.json 12KB
tsconfig.json 278B
README.md 2KB
3d
src
pages
canvas
index.tsx 346B
image-diff
index.tsx 922B
test
seqAnimate
index.tsx 166B
index.scss 412B
index.tsx 338B
entry.tsx 520B
index.tsx 209B
assets
gree.png 684B
grape.png 684B
baner.png 40KB
index.scss 131B
router
index.ts 208B
package.json 348B
tsconfig.json 298B
.npmrc 40B
utils
src
cur1.png 519KB
diff2.png 534KB
imageDiff.ts 217B
diff.png 940KB
cur.png 710KB
target1.png 521KB
target.png 648KB
index.ts 85B
package.json 139B
tsconfig.json 304B
ui-count-plugin
src
main.ts 3KB
.eslintrc.yml 36B
.babelrc 71B
package.json 1KB
rollup.config.js 944B
tsconfig.json 263B
README.md 880B
fly-ui
button
index.tsx 0B
index.scss 0B
index.ts 0B
fly-cli
src
tsconfig.json 165B
index.ts 61B
code
flatten.ts 490B
debounce.ts 917B
arr2tree.ts 2KB
scripts
ts-transformers
index.tsx 0B
webpack.base.js 5KB
webpack.dev.js 722B
webpack.prod.js 257B
共 84 条
- 1
资源评论
妄北y
- 粉丝: 1w+
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功