【pnpm、npm】各种命令详解

296 阅读4分钟

一、pnpm -F mock-server start

// 跟目录下执行如下命令 
pnpm -F mock-server start

pnpm -F mock-server start 里的 -F--filter 的简写,意思是:只在名为 mock-server 的工作区(package)中执行命令


🔍 分解这条命令:

pnpm -F mock-server start

相当于:

pnpm --filter mock-server start

🧠 它的作用是:

在 monorepo 项目中,可能有多个包(比如 frontend、backend、mock-server 等)。pnpm --filter 允许只对某个特定的包执行命令。

📌 举例:

假设有这样的 pnpm workspace

root/
├── packages/
│   ├── frontend/
│   ├── backend/
│   └── mock-server/

如果在根目录运行:

pnpm -F mock-server start

PNPM 会跳过 frontend、backend,只进入 mock-server/ 目录,执行这个包的 start 命令(定义在它自己的 package.json 中的 "scripts" 部分)。


🧩 其他常见的 --filter 用法:

命令作用
pnpm -F frontend install只在 frontend 包中安装依赖
pnpm -F "mock-*" build对所有以 mock- 开头的包执行 build
pnpm -F ./packages/backend test使用路径过滤执行 backend 的 test

✅ 总结:

-F--filter 的简写
作用指定只对某个工作区包执行命令
使用场景Monorepo 多包管理下的精准操作

如果不在用 monorepo,而这个命令出现在你项目里,那就可能是你项目结构中引入了多个 package(例如使用了 pnpm-workspace.yaml)。

为了更加清楚,接下来举个pnpm-workspace.yaml的例子:

🔧 pnpm-workspace.yaml 文件内容:

packages:
  # all packages in direct subdirs of apps/
  - "apps/*"

  # all packages in any subdirs of libs/
  - "libs/**"

  # exclude packages that are inside test directories (目前被注释掉了)
  # - '!**/test/**'

文件配置说明这个项目是一个标准的 pnpm monorepo 结构,


✅ 含义详解:

packages:

这是 pnpm 工作空间中需要被管理的包目录列表


- "apps/*"

匹配 apps/ 目录下的一级子目录

例如:

apps/
├── frontend/
├── backend/

这两个都会被识别为工作区包(前提是它们的子目录里有 package.json)。


- "libs/**"

匹配 libs/ 目录下的任意深度的子目录

比如:

libs/
├── ui/
│   └── button/
└── utils/

只要这些目录下有 package.json,都会被识别为工作区包。


# - '!**/test/**'

这行是排除规则,目前被注释掉了。

如果取消注释,它的意思是:

不要把任何路径中包含 /test/ 的目录当作 workspace 包。

比如:

apps/frontend/test/
libs/utils/test/

这些路径将会被忽略。


🧠 小结一下

配置项作用
"apps/*"匹配一级子包(前后端、服务等)
"libs/**"匹配所有深层次的共享库模块
"!**/test/**"排除所有 test 目录(目前注释掉了)

📌 结合前面的命令(pnpm -F mock-server start

假设项目里有:

apps/
├── frontend/
├── mock-server/
libs/
├── shared/

执行:

pnpm -F mock-server start

pnpm 就会在 apps/mock-server/ 目录中查找 package.json,并执行其中定义的 start 脚本。

🗂️ 目录结构:

apps/
├── api/
├── cardui/
└── mock-server/

每个子目录都应该长这样:

apps/
  └── mock-server/
       └── package.json  ✅

只要这些子目录 都有 package.json 文件,它们就会被 pnpm-workspace.yaml 中的:

- "apps/*"

成功识别为 workspace 成员。


✅ 所以结论:

包名是否被识别条件
api✅ 是package.json
cardui✅ 是package.json
mock-server✅ 是package.json

🧪 如何验证?

可以运行这个命令:

pnpm list -r

如果配置正确,它会列出所有 workspace 内的包,比如:

apps/api
apps/cardui
apps/mock-server

如果只想看有哪些 workspace 包可以用这个命令查看:

pnpm -r exec -- pwd

🧠 提示:

项目已经完全是一个 pnpm monorepo,所以 pnpm -F mock-server start 的含义就是:

进入 apps/mock-server 目录,执行它 package.json 中定义的 start 命令。


如果想让这些包之间互相依赖(比如 mock-server 依赖 cardui),你可以用:

pnpm add cardui --filter mock-server

pnpm 会自动在 workspace 内做依赖绑定。


二、 pnpm add、 pnpm install 区别

虽然这两行命令最终效果很相似,但还是有点细节区别,一一解释:


🧾 命令一:pnpm add axios -D

这是 推荐的标准方式,用于安装并将依赖添加到 package.json 中。

✅ 它做了这些事:

  1. 下载并安装 axios(如果已经安装则跳过)
  2. 将其记录到当前包的 devDependencies 中(因为加了 -D
  3. 自动更新 pnpm-lock.yaml

📦 等价于:

pnpm install axios --save-dev

🧾 命令二:pnpm install axios -D

这是一个 不推荐 的写法。原因如下:

  • pnpm install 通常用于安装项目中已有依赖(即根据 package.json 安装依赖)
  • 你在后面加了 axios -D,虽然 pnpm 能猜出来你的意思是“顺便装 axios 并作为 devDependency”,但这不是 install 的主用途

🆚 区别对比

项目pnpm add axios -Dpnpm install axios -D
是否推荐✅ 推荐❌ 不推荐(容易混淆)
会写入 package.json✅ 是✅ 是(但语义上不清晰)
主用途安装并添加新依赖安装已有依赖
使用语义清晰度✅ 高⚠️ 容易误导

✅ 正确的使用场景总结:

目的推荐命令
安装并添加依赖(默认 dependencies)pnpm add axios
添加开发依赖pnpm add axios -D
添加依赖到某个工作区包pnpm -F <pkg-name> add axios
安装所有依赖(不新增)pnpm install

如果你是在 monorepo 项目中开发数据同步脚本,想在某个子包里使用 axios,建议这样用:

pnpm -F <your-pkg-name> add axios -D

比如:

pnpm -F mock-server add axios -D

这样会把 axios 安装并挂到 mock-serverdevDependencies 下,清晰又安全。