[前端工程化] 用 pnpm workspace 搭建 monorepo 工程

[前端工程化] 用 pnpm workspace 搭建 monorepo 工程

·

1 min read

最近在工作中看到了项目中使用了pnpmworkspace来搭建monorepo,于是就自己想搭建一个试一试

monorepo 简介

monorepo是指将一个项目中的模块划分为本地的包的形式进行管理,后面在主工程中使用的时候,就像npm包那样,安装并引入依赖,就可以使用其他的模块(本地的包)了

pnpm workspace 结构搭建

先来讲讲pnpm workspace的结构:

在不使用monorepo的情况下,subPkg1subPkg2都应该是mainProject文件夹下的子模块,但在使用了monorepo后,可以将这些模块每个独立出来成为一个本地工作区的包,可以像npm包那样installimport来使用

- pacakges // pacakges 文件夹就是 workspace 下的包
  - subPkg1 // 子包1
      - package.json
  - subPkg2 // 子包2
      - package.json
  - mainProject // 主工程
    - package.json
- pnpm-workspace.yaml // 工作区配置文件,pnpm workspace 的根目录必须包含这个文件
- package.json

搭建步骤

创建一个文件夹,执行pnpm init初始化项目,然后创建pnpm-workspace.yaml文件,添加如下内容:

// 声明包目录
packages:
  - 'packages/*'

然后创建packages文件夹,并在packages下创建docs文件夹,然后在docs文件夹内初始化项目:

pnpm init

随后在docs下的package.json中,你可以将name字段改为你喜欢的名字,最好要语义化一点,辨识度高一点,我改成了@mono/docs,然后main字段可以根据你的包的入口文件修改即可

然后我们在packages下用vite创建一个react的主工程,我们最后的目的就是要在这个react主工程中使用packages下的其他子包

在主工程中安装其他子包的依赖

进入到主工程,执行pnpm安装命令,注意这里安装的包名是你的子包的package.jsonname字段值:

pnpm add @mono/docs

随后我们就可以看到主工程的package.json的依赖项:

"dependencies": {
    "@mono/docs": "workspace:^", // 这里的 workspace 就表示这个包是从本地工作区安装的
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
},

然后子包必须给主工程提供它要用到的的东西,于是我们在子包的入口文件导出即可,一般都是创建一个index.js作为入口文件:

// 随便导出点东西测试一下,在主工程内就像 npm 包那样安装导入使用就好了
export const docs = "docs"

使用 typescript 编写项目

现在基本上是个项目都会用ts来编写了,所以仅有上面的js是不够的;在主工程中使用ts非常快捷,直接用vite创建一个react-ts模板的项目即可,但我们还要给子包配置ts的依赖,并且要进行编译,然后主工程安装子包,使用子包编译后的代码,并且还要有类型提示,我们先来理一理整个思路

npm 包是怎样工作的

当你安装了一个用ts编写的包时,它会把源码和ts编译后的目录一起安装到你的node_modules下,然后你是跟据这个包的package.jsonname字段来找到它的入口文件,然后引入使用

有的包编译后的产物会包含.d.ts类型声明文件,这就是你在你的项目下引入后会有类型提示的原因

了解 ts 编译

使用ts编写的项目,编译后会生成js文件,你也可以选择为这些js文件生成类型声明文件;ts的编译配置集中在tsconfig.json这个文件中,详情可以参考: https://aka.ms/tsconfig

搭建 ts 编译结构

我们先安装ts的依赖:

npm install typescript

然后使用tsc来初始化ts项目,生成tsconfig.json文件:

npx tsc --init

配置好tsconfig.json的编译配置后,我们就可以在这些子包中编写一些复用的代码了,例如工具函数,请求api

然后就是项目的编译,我们还是用tsc来进行编译,我们在子包的package.json添加如下脚本:

"build": "npx tsc",

随后我们执行npm run build,即可将编译好的ts代码输出到指定的目录