pnpm workspace如何调试本地包

5,404 阅读3分钟

目标

现在,我们准备两个包,toolsmini-cli,我想在不发布包的情况下调试tools

调试准备

我们可以通过在mini-cli包中安装的tools来调试。

这里通过选择使用node命令运行引入了依赖包的文件(这里是mini-clisrc/index.ts)来查看结果,为了支持ts文件的运行,需要做一些准备工作:

  1. 安装ts-node

pnpm add ts-node @types/node -Dw

  1. 修改tsconfig.json配置ts-node的编译项 compilerOptions.module
{
 "ts-node": {
    "compilerOptions": {
      "module": "CommonJS" // 将ts-node的使用的模块系统设置为CommonJS
    }
  }
  }

否则会报如下错误

image.png
  1. 确保tools提供正确的模块供外部使用(不同环境使用不同的模块系统commonjs/modules)

关于模块文件入口的配置可参考packages_package_entry_points

这里我们做如下配置:

{
"exports": {
    "require": "./dist/tools.cjs.js", // require的方式引入使用commonjs规范
    "import": "./dist/tools.esm-bundler.js" // import的方式使用modules的规范
  },
}

借助workspace安装本地包

现在,我直接在mini-cli包中安装tools包,执行

pnpm -F mini-cli add @baosisi07/tools

这时打开mini-clipackage.json发现安装的依赖包如图:

image.png

我们发现:在workspace中默认安装包的方式是使用workspace协议。

关于workspace协议,根据官网的介绍,我们可以了解到:

1. workspace协议默认行为

如果dependencies中的某个依赖包版本存在于workspace中,那么会从workspace中关联包,如果依赖包的版本超出workspace的版本,那么会从registry去下载安装

比如我将当前tools的版本改为1.0.0registry中的最新版本为1.0.1 那么我指定安装1.0.0版本的结果是这样的:

image.png

直接安装的结果是这样的:

image.png

2. 仅从workspace安装某个包

使用workspace协议即可

比如安装tools包,在dependencies中定义依赖,以"tools": "workspace:*"这种形式,使用这个协议,在发布包的时候会直接将workspace直接替换成版本号,所以请大胆使用。

例如: "tools": "workspace:^1.0.1" 会被转换为 "tools": "^1.0.1"

注: 使用wrokspace:的相对路径,会替换为link:,最终发布包的时候不会被换成正式版本号。

3. 仅从registry安装某个包

link-workspace-packages

对于新安装的包,如果这个包存在workspace中,做如下配置即可实现仅从registry安装

  • workspace的根目录下新建.npmrc文件
  • 增加link-workspace-packages=false这一行

但是,对于依赖包已经使用了workspace的协议,那么还是只从workspace中关联包

4. 从registry安装所有包

save-workspace-protocol

save-workspace-protocol=false添加到.npmrc文件即可

这时候即使依赖包使用了workspace协议,也会从registry下载安装

5. 从workspace安装所有包

prefer-workspace-packages

prefer-workspace-packages=true添加到.npmrc文件即可 从前面分析的workspace协议默认行为,我们知道超出workspace本地包版本的会从registry下载,这个配置可以避免这个情况的发生。

保证即使在registry中有更高的版本,也依然从workspace安装本地包

源码地址