monorepo 依赖提升 yarn、pnpm

在 Monorepo 中,依赖提升(dependency hoisting)并不会将每个子项目的依赖变成全局依赖,而是将相同版本的依赖提升到 Monorepo 根目录的 `node_modules` 中,以减少冗余的安装和磁盘空间占用。依赖提升的主要目的是优化依赖管理和安装速度,但每个子项目的依赖作用域仍然保持不变。

### 依赖提升的工作原理

1. **依赖提升**:相同版本的依赖会被提升到 Monorepo 根目录的 `node_modules` 中。
2. **符号链接**:子项目的 `node_modules` 中会创建符号链接,指向根目录的依赖。
3. **作用域保持**:每个子项目的依赖作用域仍然是局部的,即使依赖被提升到根目录,子项目只能访问其 `package.json` 中定义的依赖。

### 示例

假设你有一个 Monorepo 结构如下:

```
/monorepo
  /packages
    /project-a
      package.json
    /project-b
      package.json
  package.json
```

#### 根目录 `package.json`

```json
{
  "private": true,
  "workspaces": [
    "packages/*"
  ],
  "devDependencies": {
    "eslint": "^7.32.0"
  }
}
```

#### `project-a` 的 `package.json`

```json
{
  "name": "project-a",
  "version": "1.0.0",
  "dependencies": {
    "lodash": "^4.17.21"
  }
}
```

#### `project-b` 的 `package.json`

```json
{
  "name": "project-b",
  "version": "1.0.0",
  "dependencies": {
    "lodash": "^4.17.21",
    "axios": "^0.21.1"
  }
}
```

### 依赖提升后的结果

1. `lodash` 依赖会被提升到根目录的 `node_modules` 中,因为 `project-a` 和 `project-b` 都依赖于相同版本的 `lodash`。
2. `axios` 依赖会保留在 `project-b` 的 `node_modules` 中,因为只有 `project-b` 依赖它。

### 依赖作用域

- **根目录依赖**:根目录的 `devDependencies`(如 `eslint`)可以在整个 Monorepo 中使用,通常用于开发工具和共享依赖。
- **子项目依赖**:每个子项目的依赖(如 `lodash` 和 `axios`)仅在该子项目中使用,即使 `lodash` 被提升到根目录,`project-a` 和 `project-b` 仍然只能访问各自 `package.json` 中定义的依赖。

### 总结

依赖提升不会改变每个子项目的依赖作用域。每个子项目仍然只能访问其 `package.json` 中定义的依赖。依赖提升的目的是优化依赖管理和安装速度,而不是将所有依赖变成全局依赖。
如果 project-a 的 package.json 的 { "name": "project-a", "version": "1.0.0", "dependencies": { "lodash": "^4.17.21" } } 和 project-b 的 package.json { "name": "project-b", "version": "1.0.0", "dependencies": { "lodash": "^4.17.21", "axios": "^0.21.1" } } 后来 project-a 改为 { "name": "project-a", "version": "1.0.0", "dependencies": { "lodash": "^4.17.21", "axios": "^0.21.1" } } project-a 的node_modules的 axios 依赖会被删除,后提升到全局的node_modules?



如果你在 `project-a` 的 `package.json` 中添加了 `axios` 依赖,并且 `project-b` 也已经依赖了相同版本的 `axios`,那么在依赖提升的过程中,`axios` 依赖会被提升到 Monorepo 根目录的 `node_modules` 中。

### 具体步骤

1. **修改 `project-a` 的 `package.json`**:
   ```json
   {
     "name": "project-a",
     "version": "1.0.0",
     "dependencies": {
       "lodash": "^4.17.21",
       "axios": "^0.21.1"
     }
   }
   ```

2. **运行依赖安装命令**:
   在 Monorepo 根目录下运行 `yarn install` 或 `lerna bootstrap`(如果使用 Lerna)。

3. **依赖提升**:
   - Yarn 或 Lerna 会检测到 `project-a` 和 `project-b` 都依赖于相同版本的 `axios`。
   - `axios` 依赖会被提升到 Monorepo 根目录的 `node_modules` 中。
   - `project-a` 和 `project-b` 的 `node_modules` 中将不会单独安装 `axios`,而是通过符号链接指向根目录的 `axios` 依赖。

### 结果

- **根目录 `node_modules`**:
  - `lodash` 和 `axios` 都会被安装在根目录的 `node_modules` 中。
- **`project-a` 和 `project-b` 的 `node_modules`**:
  - `project-a` 和 `project-b` 的 `node_modules` 中不会单独安装 `axios`,而是通过符号链接指向根目录的 `axios` 依赖。

### 总结

通过依赖提升,`axios` 依赖会被提升到 Monorepo 根目录的 `node_modules` 中,从而减少冗余安装。`project-a` 和 `project-b` 的 `node_modules` 中将不会单独安装 `axios`,而是通过符号链接指向根目录的 `axios` 依赖。这样可以优化依赖管理和安装速度。


pnpm 支持依赖提升吗,类式yarn的功能

是的,pnpm 支持依赖提升(dependency hoisting),类似于 Yarn 的功能。pnpm 提供了一个名为 `pnpm-workspace.yaml` 的配置文件,用于管理 Monorepo 中的多个包,并且可以通过配置来启用依赖提升。

### 配置示例

1. **创建 `pnpm-workspace.yaml` 文件**:
   在 Monorepo 根目录下创建一个 `pnpm-workspace.yaml` 文件,用于定义工作区。

   ```yaml
   packages:
     - 'packages/*'
   ```

2. **配置 `package.json` 文件**:
   确保 Monorepo 根目录的 `package.json` 文件中包含以下内容:

   ```json
   {
     "private": true,
     "devDependencies": {
       "eslint": "^7.32.0"
     }
   }
   ```

3. **子项目的 `package.json` 文件**:
   在每个子项目的 `package.json` 文件中定义各自的依赖。

   例如,`project-a` 的 `package.json`:

   ```json
   {
     "name": "project-a",
     "version": "1.0.0",
     "dependencies": {
       "lodash": "^4.17.21",
       "axios": "^0.21.1"
     }
   }
   ```

   `project-b` 的 `package.json`:

   ```json
   {
     "name": "project-b",
     "version": "1.0.0",
     "dependencies": {
       "lodash": "^4.17.21",
       "axios": "^0.21.1"
     }
   }
   ```

4. **运行 `pnpm install`**:
   在 Monorepo 根目录下运行 `pnpm install`,pnpm 会自动处理依赖提升,并将相同版本的依赖提升到根目录的 `node_modules` 中。

### 依赖提升配置

pnpm 默认会进行依赖提升,但你也可以通过配置来控制提升行为。在 `pnpm-workspace.yaml` 文件中,可以使用 `hoist` 配置项来启用或禁用依赖提升。

```yaml
packages:
  - 'packages/*'
hoist:
  - '*'
```

### 总结

pnpm 支持依赖提升功能,类似于 Yarn 的 Workspaces。通过配置 `pnpm-workspace.yaml` 文件,你可以在 Monorepo 中高效地管理多个包,并减少冗余依赖的安装。pnpm 的依赖提升功能可以显著优化安装速度和磁盘空间使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值