0. 使用 pnpm 创建一个 monorepo

本系列文章以开发 JavaScript 全栈项目作为撰文背景,将进行多次的修正。希望大家能多多提建议,如有不足之处,欢迎评论讨论。

项目地址:

pnpm 是一个快速、节省磁盘空间的 Node.js 包管理器,它可以创建 workspace 来实现 monorepo

monorepo 是一种方便管理同一个项目下不同包和依赖的项目实现方式:例如,我们的全栈项目中有服务端客户端管理端还有文档,这些包相互关联也彼此独立,它们会用到相同的依赖,也有各自独有的依赖。那么为了使依赖能最大程度的复用,在这个项目里安装一次依赖,就可以在每个包中使用,这是 monorepo 最大的优势。

Tip: monorepo 的另一大优势就是每个独立的包之间可以相互引用,但在此项目中暂时还没有涉及。

初始化创建

bash 复制代码
# 创建项目目录
$ mkdir full-stack-from-scratch

# 进入目录
$ cd full-stack-from-scratch

# 初始化 git
$ git init

# 初始化 package
$ pnpm init -y

此时的目录里,应该只有一个 package.json 文件。一般情况下,作为项目的主包是不需要发布的,因此需要对该文件进行以下修改,以防主包误发布:

json 复制代码
// package.json

{
  //... 其他配置
  "private": true
}

要启用 pnpmworkspace 需要在目录下创建一个 pnpm-workspace.yaml 文件,内容如下:

yaml 复制代码
# pnpm-workspace.yaml

packages:
  - 'packages/*'  # 指定在 packages 目录下的包
  - docs      # 指定根目录下 docs 包

依据以上配置,创建一些包,结构如下:

bash 复制代码
.
|-- docs  # 文档:使用 vitepress 创建
|   `-- package.json
|-- packages
|   |-- admin  # 管理端:实现一个 CMS
|   |   `-- package.json
|   |-- client # 客户端:用户界面
|   |   `-- package.json
|   `-- server # 服务端:连接数据库和提供 API
|       `-- package.json
|-- package.json
`-- pnpm-workspace.yaml

依赖管理

monorepo 中,如果某个依赖是多个包都需要的,可以直接安装到主包中:

bash 复制代码
$ pnpm add -w <library name>

这样可以直接在子包中直接用,例如前后端都需要用到的 dayjs

如果某个依赖是子包独有的,可以直接安装到子包:

bash 复制代码
$ pnpm add -F <package name> <library name>

package name 对应每个 package.json 中的 name 字段。

scripts 管理

在分包中,可以以一般的方式进行 scripts 的定义,但需要将脚本暴露到主包中,则需要在主包做一些配置。例如,我们要将 full-stack-from-scratch-sever 中的 start 命令暴露到主包中,可以进行如下配置:

json 复制代码
// package.json
{
  "scripts": {
    "server:start": "pnpm -F full-stack-from-scratch-sever start"
  }
}

这样在主包目录下,我们可以通过 pnpm server:start 来执行对应包中的脚本。

至此,一个基于 pnpm workspacemonorepo 大体框架就已经搭建完毕。


created: 2023-11-17

last modified: 2023-11-17

相关推荐
YukiMori231 小时前
一个有趣的原型继承实验:为什么“男人也会生孩子”?从对象赋值到构造函数继承的完整推演
前端·javascript
摸鱼的春哥2 小时前
惊!黑客靠AI把墨西哥政府打穿了,海量数据被黑
前端·javascript·后端
小兵张健2 小时前
Playwright MCP 截图标注方案调研(推荐方案1)
前端·javascript·github
我叫黑大帅4 小时前
Vue3和Uniapp的爱恨情仇:小白也能懂的跨端秘籍
前端·javascript·vue.js
None3215 小时前
【NestJs】使用Winston+ELK分布式链路追踪日志采集
javascript·node.js
Qinana5 小时前
从代码到智能体:MCP 协议如何重塑 AI Agent 的边界
前端·javascript·mcp
Marshall1516 小时前
zzy-scroll-timer:一个跨框架的滚动定时器插件
前端·javascript
明月_清风7 小时前
打字机效果优化:用 requestAnimationFrame 缓冲高频文字更新
前端·javascript
明月_清风7 小时前
Markdown 预解析:别等全文完了再渲染,如何流式增量渲染代码块和公式?
前端·javascript
程序猿的程21 小时前
开源一个 React 股票 K 线图组件,传个股票代码就能画图
前端·javascript