看某个教程时用到了 Lerna,就搞个 monorepo demo 试一下,很早之前就听说过 Lerna,但是没有使用的场景,个人也觉得这种方案比较奇怪。
翻了下文档和 Github,发现两个月前还有一个更换维护人的事件 Announcement: Passing the torch,然后看了下 Vue 用的是 pnpm workspace,React 用的是 yarn workspace,真是“太有意思”了。
What‘s Monorepo
一个仓库管理多个项目,优势是抽离公共组件很方便,劣势是权限控制,是否还记得一九年的 B 站源码泄漏事件?
比如 Google 也是一个巨大的仓库,但是有内部自研工具的支持,Monorepo 更像是后端的构建理念来到了前端,因为前端越来越复杂。
Lerna
npx lerna init
生成了一个 lerna.json 文件,按照通俗的做法,使用 packages 目录来存放项目。
├── README.md
├── lerna.json
├── package.json
└── packages
# lerna.json
{
"packages": [
"packages/*"
],
"useNx": false,
"version": "0.0.0"
}
然后分别新增了一个 Header 组件,一个 Web 项目 Hello,然后 Web 项目引用这个 Header 组件。
# Hello/package.json
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"header": "*"
},
# Header.tsx
export function Header({ children }) {
return (
<header style={{ height: 80, backgroundColor: 'white', boxShadow: '0 0 3px black'}}>
{children}
</header>
)
}
├── README.md
├── lerna.json
├── package.json
└── packages
├── header
│ ├── package.json
│ ├── rollup.config.js
│ ├── src
│ │ ├── Header.tsx
│ │ └── index.tsx
│ └── tsconfig.json
└── hello
├── index.html
├── package.json
├── src
│ ├── App.jsx
│ └── main.jsx
└── vite.config.js
以上准备工作完成后,即可运行
npx lerna bootstrap # 安装 dependencies
npx lerna run build # build 所有 package
npx lerna run dev --scope=hello # 启动 Web 项目,也可使用 cd packages/hello && npm run dev
启动效果如图
Yarn workspace
yarn 配置放在 package.json 里面
"workspaces": [
"packages/*"
]
目录结构就不说了,跟上面的 Lerna 一样就行了,不同的也就是启动命令不一样。
yarn install
yarn workspace header run build # build 被依赖的仓库
yarn workspace hello run dev # 启动 Web 项目
Summary
Yarn 官网其实有说明两者的差异,所以随心选择即可。
Despite the appearances, the Yarn workspaces and Lerna don't compete. In fact, Lerna will use Yarn's workspaces if possible. In a sense, you can see Lerna as a high-level layer on top of the low-level Yarn implementation.
不过被接手的新版 Lerna 得到了 Nx 的加持,Nx 是 Google 开发者做的,去试用了下,果然风格很 Angular,集成的非常棒,功能大而全,既是优势也是劣势啊。在现在流行零配置,开发者已经被层出不穷的新框架新技术折磨的年代,感觉很难流行起来,但他们接手了 Lerna 倒是可以期待下,希望能给出简单的配置强大的功能。