1️⃣ 项目结构
假设我们有一个 monorepo:
my-monorepo/
├── pnpm-workspace.yaml
├── packages/
│ ├── foo/
│ │ ├── package.json
│ │ └── index.js
│ └── bar/
│ ├── package.json
│ └── index.js
pnpm-workspace.yaml:
packages:
- "packages/*"
packages/foo/package.json:
{
"name": "foo",
"version": "1.0.0",
"type": "module",
"main": "index.js"
}
packages/foo/index.js:
export function hello() {
console.log("Hello from foo v1.0.0");
}
packages/bar/package.json:
{
"name": "bar",
"version": "1.0.0",
"type": "module",
"main": "index.js",
"dependencies": {
"foo": "workspace:*"
}
}
packages/bar/index.js:
import { hello } from "foo";
hello();
2️⃣ 安装依赖
在 monorepo 根目录执行:
pnpm install
发生了什么?
- pnpm 会在
bar/node_modules/foo下创建一个 符号链接,指向../foo。 - 也就是说,
bar使用的是本地开发的foo,而不是从 registry 下载的版本。
你可以在命令行验证:
ls -l packages/bar/node_modules
输出类似:
foo -> ../../foo
✅ 这就是一个符号链接,指向本地的 foo 包。
3️⃣ 修改本地包并测试
现在修改 packages/foo/index.js:
export function hello() {
console.log("Hello from foo v1.1.0"); // 修改内容
}
然后运行:
node packages/bar/index.js
输出:
Hello from foo v1.1.0
💡 说明:bar 立即使用了本地 foo 的最新修改,无需重新安装依赖。
4️⃣ 总结
- 符号链接的作用:让依赖指向本地包,修改立即生效,非常适合 monorepo 开发。
- 如果不是符号链接,而是普通复制安装的包,修改
foo就不会反映到bar,必须重新安装。