• 作者:老汪软件技巧
  • 发表时间:2024-10-15 11:04
  • 浏览量:

前言

在现代前端开发中,Vue 3 已经成为构建高效、可维护用户界面的首选框架之一。随着项目规模的扩大,如何有效地管理多个相关项目成为一个重要课题。Monorepo(单一代码库)作为一种解决方案,允许我们在一个代码库中管理多个项目,从而提高代码复用性和开发效率。

本文将带你一步步使用 Vue 3 和 pnpm 搭建一个 Monorepo 项目。pnpm 是一个快速、节省磁盘空间的包管理器,特别适合在 Monorepo 环境中使用。通过本文的学习,你将掌握如何在一个代码库中管理多个 Vue 3 项目,并利用共享库来提高代码复用性。

准备工作

在开始搭建 Vue 3 + pnpm 的 Monorepo 项目之前,我们需要确保环境已经准备好。以下是准备工作的步骤:

安装 Node.js首先,确保你已经安装了 Node.js。你可以通过以下命令检查 Node.js 是否已经安装:

node -v

如果你还没安装 node ,需要到官网安装一下,基本上是傻瓜式安装,不过考虑到我们要使用到 pnpm ,建议安装node18版本及以上, 我们后续安装 pnpm 时,需要确保 Node.js 的版本至少为 18 ,因为 pnpm9 需要使用 node18 才能正常工作。‌不过也可以使用 nvm 对 node 版本进行管理,方便使用,node 和 nvm 官网如下,可根据自己的需要下载:

安装 pnpm

npm i pnpm -g

效果如下:

为什么选择 pnpm 作为包管理器?Workspace 支持

pnpm 原生支持 Monorepo 项目,通过pnpm-workspace.yaml文件,你可以轻松地配置多个子项目。pnpm 的 workspace 功能使得在多个子项目之间共享依赖变得更加容易,并且可以自动处理依赖的安装和更新。

在 Monorepo 项目中,pnpm 的 workspace 功能允许你在多个子项目之间共享依赖。例如,你可以使用workspace:*来引用本地 workspace 中的包,而不需要发布到 npm 仓库。

性能优势

pnpm 使用了一种称为“内容寻址存储”(Content-Addressable Storage)的技术,这意味着相同的依赖包只会被下载和存储一次。这大大减少了安装时间,尤其是在大型 Monorepo 项目中,多个子项目共享相同的依赖时,pnpm 的性能优势尤为明显。

由于 pnpm 只存储每个依赖包的一个副本,因此它可以显著减少磁盘空间的占用。这对于 Monorepo 项目尤为重要,因为多个子项目可能会共享大量的依赖包。

依赖管理

pnpm 使用了一个严格的依赖解析算法,确保每个包的依赖版本都是一致的。这减少了由于依赖版本不一致而导致的潜在问题,特别是在 Monorepo 项目中,多个子项目共享相同的依赖时。

pnpm 的node_modules结构是扁平化的,这意味着每个包都有自己的依赖目录,而不是将所有依赖放在根目录下。这种结构减少了依赖冲突的可能性,并且使得依赖关系更加清晰。

安全性

pnpm 的node_modules结构避免了“幽灵依赖”(Phantom Dependency)问题。幽灵依赖是指在node_modules中意外地引入了未在package.json中声明的依赖包。pnpm 通过严格的依赖解析和扁平化的node_modules结构,减少了这种问题的发生。

灵活性初始化项目创建项目目录

首先新建一个文件夹,名为vue3-pnpm-monorepo

进入vue3-pnpm-monorepo文件夹,初始化一个默认的package.json文件,执行命令:

mkdir vue3-pnpm-monorepo
cd vue3-pnpm-monorepo
pnpm init

2.配置 pnpm workspace

为了在 Monorepo 中管理多个项目,我们需要配置 pnpm workspace。在项目根目录下创建一个pnpm-workspace.yaml文件,并添加以下内容:

packages:
  - 'packages/*'

这表示所有位于packages目录下的子目录都将被视为独立的包(项目)。这个文件可以帮助我们在安装公共依赖的情况下,也将packages下的项目所需要的依赖也同时进行安装。

创建子项目目录

mkdir packages

初始化三个vue3 + ts的项目进行演示

cd packages
npm init vite vue-demo1
npm init vite vue-demo2
npm init vite vue-demo3

当前项目结构如下:

├── packages
|  ├── vue-demo1
|  ├── vue-demo2
|  └── vue-demo3
├── package.json

项目内部结构如下:

├── packages
|  ├── vue-demo1
|  |  ├── .vscode
|  |  ├── public
|  |  ├── src
|  |  ├── .gitignore
|  |  ├── index.html
|  |  ├── package.json
|  |  ├── README.md
|  |  ├── tsconfig.json
|  |  ├── tsconfig.node.json
|  |  └── vite.config.ts
|  ├── vue-demo2
|  └── vue-demo3
├── package.json

每个子项目的 package.json 内容应该如下:

{
  "name": "vue-demo1",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc -b && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "vue": "^3.5.10"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.1.4",
    "typescript": "^5.5.3",
    "vite": "^5.4.8",
    "vue-tsc": "^2.1.6"
  }
}

经过分析不难发现,目前这三个项目是完全一样的,需要的依赖也是完全一样的,所以这些依赖项就可以直接抽离出来,变成公共的依赖项,添加上版本号,另外调试的话也不需要在这里进行调试,也直接删掉,稍加修改这个文件,最后如下:

vue-demo1:

{
  "name": "vue-demo1",
  "private": true,
  "version": "0.0.0"
}

vue-demo2:

{
  "name": "vue-demo2",
  "private": true,
  "version": "0.0.0"
}

vue-demo3:

{
  "name": "vue-demo3",
  "private": true,
  "version": "0.0.0"
}

创建公共依赖配置

配置好之后,就可以在根目录执行:

pnpm i

安装好了之后,我们就会发现,在项目的根目录中,有了node_modules文件夹。接下来可以通过命令启动一下项目:

pnpm run dev:vue-demo1
pnpm run dev:vue-demo2
pnpm run dev:vue-demo3

局部安装依赖项

当然,我们也会遇到一种情况就是,我们的,某个子项目需要某个依赖,但是其他项目没有使用,所以这个时候最好就是单独为这个子项目安装依赖,比如说,我的vue-demo1的项目中需要安装element-plus,而其它的两个项目是不需要的,那么这样的话,就可以将element-plus单独安装到vue-demo1的项目中,而另外两个项目是不需要的,所以就没必要安装到全局,直接安装到vue-demo1内部,安装的方式有两种:

进入到指定目录去安装

可以直接进入到指定需要安装的目录进行安装,那么进入到packages/vue-demo1中,执行:

cd packages/vue-demo1
pnpm i element-plus

--filter安装使用--filter修饰符可以实现在根目录指定某个目录进行安装,具体命令为:

pnpm i element-plus --filter vue-demo1

总结

Monorepo 的优势在于它能够在一个代码库中管理多个相关项目,从而提高代码复用性和开发效率。以下是 Monorepo 的一些主要优势:

代码复用统一依赖管理简化开发流程更好的版本控制提高团队协作


上一条查看详情 +6个月时间,我放弃一人企业又去打工了
下一条 查看详情 +没有了