pnpm 管理 monorepo

本文介绍了如何使用pnpm在monorepo结构中管理项目,包括初始化、安装全局和局部依赖、设置子项目间的依赖以及执行子包命令等步骤,帮助开发者高效组织多个相关项目。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用 pnpm workspace 管理 monorepo 项目

安装 pnpm

pnpm 中文文档

什么是 monorepo

Monorepo 是项目管理代码的方式之一,指的是一个大项目中包含了需要小项目或者模块,大概的样子

├── packages
|   ├── pkg1
|   |   ├── package.json
|   ├── pkg2
|   |   ├── package.json
├── package.json

初始化项目

pnpm init

初始化一个项目,创建 package.json

.
└── package.json

在根目录中创建 pnpm-workspace.yaml

packages:
  - 'packages/**'

在根目录中创建 packages 文件夹,并且在 packages 中创建子项目

mkdir packages
mkdir packages/core
mkdir packages/browser

.
├── package.json
└── packages
    ├── browser
    └── core

安装全局依赖

-D 表示安装到开发依赖,即 devDependencies, -w 表示在根目录安装

pnpm install typescript -Dw

.
├── node_modules
│   └── typescript -> .pnpm/typescript@4.7.4/node_modules/typescript
├── package.json
├── packages
│   ├── browser
│   └── core
├── pnpm-lock.yaml
└── pnpm-workspace.yaml

局部依赖

首选在每个子项目中初始化 package.json

.
├── node_modules
│   └── typescript -> .pnpm/typescript@4.7.4/node_modules/typescript
├── package.json
├── packages
│   ├── browser
│   │   └── package.json
│   └── core
│       └── package.json
├── pnpm-lock.yaml
└── pnpm-workspace.yaml

packages/browser 中的 package.json

{
  "name": "@test/browser",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

packages/core 中的 package.json

{
  "name": "@test/core",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

这里需要给每个子项目指定命名空间和包名,即 @test/core

通过 filter 可以给指定的包安装依赖

pnpm install loadsh -r --filter @test/core
{
  "name": "@test/core",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "lodash": "^4.17.21"
  }
}

两个包之间相互依赖

browser 依赖 core

pnpm i @test/core -r --filter @test/browser

browser 中就依赖上了 core,版本前面有 workspace 字样,表示本地引用,发布的时候就会被剔除掉

{
  "name": "@test/browser",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@test/core": "workspace:^1.0.0"
  }
}

运行子包命令

根目录 package.json

使用 pnpm -r --filter=@test/* run test 来批量执行子包中的 test 脚本

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "pnpm -r --filter=@test/* run test"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "typescript": "^4.7.4"
  }
}

@test/browser 中的 package.json

{
  "name": "@test/browser",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"test browser\""
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@test/core": "workspace:^1.0.0"
  }
}

@test/core 中的 package.json

{
  "name": "@test/core",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"test core\""
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "lodash": "^4.17.21"
  }
}

执行 pnpm test,即可得到输出结果

> pnpm -r --filter=@test/* run test

Scope: 2 of 3 workspace projects
packages/core test$ echo "test core"test core
└─ Done in 13ms
packages/browser test$ echo "test browser"test browser
└─ Done in 8ms

<think>好的,我现在需要帮助用户解决如何使用pnpmmonorepo模式构建包含Vue 3、TypeScript和UniApp的项目,并抽离公共组件的问题。首先,我得回忆一下pnpmmonorepo的基本概念。pnpm是一个包管理工具,通过硬链接节省磁盘空间,而monorepo则是在一个仓库中管理多个项目,共享代码和配置。 接下来,用户的需求涉及Vue 3、TypeScript和UniApp,这三个技术栈的结合。UniApp可能用于多端开发,比如小程序和H5,所以项目结构需要支持多平台。同时,用户希望抽离公共组件,这在monorepo结构下可以通过workspace来实现,把公共组件放在独立的包中,各子项目依赖这个包。 首先,我需要确定项目的基本结构。通常monorepo的根目录会有pnpm-workspace.yaml来定义工作空间,里面包含packages目录,里面可能有多个子项目,比如apps(存放各个应用)和libs(公共组件库)。这样,每个应用都可以引用libs中的组件。 然后,安装必要的依赖。Vue 3和TypeScript的基础配置,可能需要@vitejs/plugin-vue、vue-tsc等。UniApp部分可能需要使用Vite插件,比如@dcloudio/vite-plugin-uni,或者查看官方文档推荐的配置。这里可能需要查阅UniApp的官方文档,确认如何集成到Vite项目中。 接下来是初始化项目。用户提到使用pnpm,所以需要先确保pnpm已安装。然后创建项目结构,初始化各个子项目。每个子项目可能需要自己的package.json,并且在workspace中声明依赖关系,比如apps/h5和apps/miniprogram都依赖libs/components。 然后是配置共享。公共的TypeScript和Vue配置可以放在根目录,通过extends来继承,避免重复。ESLint、Prettier等工具也可以在根目录统一配置,各子项目继承这些配置,保持一致性。 抽离公共组件部分,需要在libs目录下创建组件库项目,导出组件,然后在子项目中通过workspace协议引用。可能需要配置构建工具,如Vite,确保能正确解析workspace的依赖。 在UniApp的集成方面,可能需要特别注意,因为UniApp有自己的构建流程和配置,可能需要调整Vite配置,添加必要的插件,并处理平台特定的代码。 最后是构建和运行命令,需要为每个子项目配置脚本,并且可能需要使用pnpm filter来指定运行哪个子项目的命令。 过程中需要注意的坑点可能包括:workspace依赖的正确声明,TypeScript路径别名的配置,UniApp与Vue 3的兼容性问题,以及公共组件的构建和导出方式。需要确保所有子项目能正确引用公共组件,并且在H5和小程序端都能正常运行。 可能还需要考虑测试和代码规范,比如在根目录统一设置ESLint、Prettier、Husky等工具,保证代码质量。此外,公共组件的版本管理和发布策略也是需要考虑的,但在monorepo中通常通过workspace协议自动处理。 总结步骤应该是:初始化monorepo结构,配置workspace,创建子项目,设置共享配置,抽离公共组件到libs,配置各子项目的依赖和构建脚本,处理UniApp的集成,最后测试整个项目运行。</think>### 使用 pnpmMonorepo 构建 Vue 3 + TypeScript + UniApp 项目的详细步骤 #### 一、环境准备 1. **安装 pnpm** ```powershell # 使用 PowerShell 安装 pnpm(需管理员权限) Invoke-WebRequest 'https://get.pnpm.io/v6.16.js' -UseBasicParsing -o pnpm.js node pnpm.js add --global pnpm Remove-Item pnpm.js ``` 2. **验证安装** ```bash pnpm -v # 输出版本号即成功 ``` --- #### 二、初始化 Monorepo 项目结构 1. **创建项目根目录** ```bash mkdir my-monorepo-project && cd my-monorepo-project ``` 2. **配置 pnpm workspace** 创建 `pnpm-workspace.yaml` 文件,定义工作区范围: ```yaml packages: - 'apps/*' # 存放应用(如 H5、小程序) - 'libs/*' # 存放公共组件/工具库 ``` 3. **初始化根目录 package.json** ```bash pnpm init -y ``` --- #### 三、创建子项目 1. **H5 应用(Vue3 + TypeScript)** ```bash # 使用 Vite 初始化 H5 项目 pnpm create vite apps/h5 --template vue-ts ``` 2. **UniApp 小程序应用** ```bash # 进入 apps 目录,使用 UniApp 官方模板 cd apps && npx degit dcloudio/uni-preset-vue#vite my-uniapp mv my-uniapp miniprogram && cd .. ``` 3. **公共组件库** ```bash mkdir -p libs/components/src cd libs/components && pnpm init -y ``` --- #### 四、配置依赖与共享 1. **安装全局依赖(根目录)** ```bash pnpm add -Dw vue@3 typescript @vitejs/plugin-vue unplugin-auto-import ``` 2. **关联子项目依赖** ```bash # H5 项目安装依赖 pnpm --filter h5 add vue-router axios # UniApp 项目安装依赖 pnpm --filter miniprogram add @dcloudio/uni-app @dcloudio/vite-plugin-uni # 公共组件库声明依赖 pnpm --filter components add vue@3 ``` 3. **共享 TypeScript 配置** 在根目录创建 `tsconfig.base.json`,子项目通过 `extends` 继承: ```json { "compilerOptions": { "target": "ESNext", "module": "ESNext", "strict": true, "baseUrl": ".", "paths": { "@/*": ["./src/*"], "@components/*": ["../../libs/components/src/*"] } } } ``` --- #### 五、抽离公共组件最佳实践 1. **组件库结构示例** ``` libs/components/ ├─ src/ │ ├─ Button/ │ │ ├─ index.vue # 组件实现 │ │ └─ index.ts # 导出组件 │ └─ index.ts # 统一导出所有组件 ├─ package.json # 声明 name: "@myorg/components" ``` 2. **在子项目中引用** 修改子项目的 `vite.config.ts`: ```typescript import { defineConfig } from 'vite' import uni from '@dcloudio/vite-plugin-uni' export default defineConfig({ plugins: [uni()], resolve: { alias: { '@components': 'libs/components/src' } } }) ``` 3. **通过 Workspace 协议声明依赖** 在 `apps/h5/package.json` 中添加: ```json { "dependencies": { "@myorg/components": "workspace:*" } } ``` --- #### 六、构建与运行 1. **全局命令配置(根目录 package.json)** ```json { "scripts": { "dev:h5": "pnpm --filter h5 dev", "build:h5": "pnpm --filter h5 build", "dev:mp": "pnpm --filter miniprogram dev:mp-weixin", "build:mp": "pnpm --filter miniprogram build:mp-weixin" } } ``` 2. **启动项目** ```bash # 启动 H5 项目 pnpm dev:h5 # 启动微信小程序项目 pnpm dev:mp ``` --- ### 关键问题与解决方案 1. **跨项目类型兼容性** - UniApp 需使用 `@dcloudio/vite-plugin-uni` 插件支持 Vue3[^2] - 公共组件避免使用平台特有 API,通过条件编译处理差异: ```vue <!-- 示例:H5 与小程序条件编译 --> <template> <!-- #ifdef H5 --> <div>H5 特有内容</div> <!-- #endif --> </template> ``` 2. **样式共享方案** 在根目录安装全局样式依赖: ```bash pnpm add -Dw sass ``` 通过 `@import "@/styles/variables.scss";` 在组件中引用 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值