NPM Workspace 的基本概念
NPM Workspace 的基本概念
Owner: fredbrock
描述
工作区(Workspace)的概念
用于管理多个相互关联的包(子项目)在同一个代码仓库中的依赖和脚本,用于Monorepo 项目。
在 npm 工作区(Workspaces)的概念中,每个子项目(子包)通常对应一个工作区。换句话说,一个工作区就是一个独立的 npm 包,具有自己的 package.json
文件和独立的依赖管理。这些子项目(工作区)可以位于同一个 Monorepo 仓库中,并由顶层的 package.json
文件来统一管理。
作用:
- 集中管理依赖:在顶层执行一次安装,无需每个项目单独使用命令安装依赖。
- 共享依赖:将多个子项目的共享依赖提升到顶层,避免重复安装。
- 跨包脚本执行:在任意目录运行子项目的命令。
- 内部链接:本地的子包(比如组件库,工具库),可以通过符号链接并使用。
工作区的结构和关系
顶层项目:这是 Monorepo 项目的根目录,包含一个顶层的 package.json 文件,定义了整个项目的工作区结构。
子项目(工作区):这些是位于特定路径下的独立 npm 包,每个子项目都有自己的 package.json 文件,负责定义自己的依赖、脚本和其他配置,一般放在packages/
目录中。
基本结构示例
my-workspaces/
├── package.json // 顶层 package.json
├── packages/
│ ├── project-a/ // 子项目 A
│ │ ├── package.json // Project A 的 package.json
│ ├── project-b/ // 子项目 B
│ │ ├── package.json // Project B 的 package.json
│ └── project-c/ // 子项目 C
│ ├── package.json // Project C 的 package.json
创建工作区
mkdir my-workspaces
cd my-workspaces
npm init -y // 初始一个npm项目
npm init -w ./packages/project-a -y // 创建子项目,project-a
npm init -w ./packages/project-b -y // 创建子项目,project-b
根目录 package.json 将添加如下配置
"workspaces": [
"packages/project-a",
"packages/project-b"
]
...
表示定义了两个工作区(可以理解为子项目),project-a
和project-b
。
使用工作区
向工作区添加依赖项
比如:这里我要 project-a
工作区使用 lodash
这个包
npm install lodash -w project-a
-w
:是—workspace命令选项的简写,值是要添加的工作区的名称,如果不加-w参数,依赖包将添加到顶层依赖中,用于多个工作区共享。
向project-a工作添加一些基本代码
创建index.js文件,添加一些工具方法。
// project-a/index.js
const _ = require("lodash");
module.exports = {
add: (a, b) => a + b,
print(a) {
console.log(_.join(["Hello", a], " ~"));
},
};
解释:这里我导出了使用NodeJS CommonJS语法导出了两个工具函数。
add:一个用于计算两个值加法。
print:接收一个参数,使用lodash的join向控制台输入拼接的字符串。
向project-b工作添加一些基本代码
创建 index.js
文件, 导入project-a
工作区的模块,调用project-a
的print
方法,打印输出。
// project-b/index.js
const moduleA = require("project-a");
console.log(moduleA.print("World"));
测试功能能否运行
命令行定位到project-b工作区目录,运行如下命令
node index.js
在工作区上下文中运行命令
每个工作区都有自己的npm scripts 脚本,传统方式是定位到特定项目,然后在当前目录运行脚本。
通过npm workspace 可以在项目任意目录执行特定工作区的脚本。
现在我们要运行 project-b工作区的命令
在project-b/package.json,添加一条 npm 脚本。
"scripts": {
"dev": "node index.js",
},
...
在项目任意目录运行下面命令,比如我在 my-workspaces/packages
目录中运行如下脚本
npm run dev --workspace=project-b
输出如下结果
@fredbrock ➜ packages npm run dev --workspace=project-b
> [email protected] dev
> node index.js
Hello ~World
undefined
工作区上下文命令的其他方法
在特定工作区运行脚本
npm run test --workspace=project-b
在工作区内运行脚本
cd packages/project-b && npm run test
指定多个工作区运行脚本
npm run test --workspace=a --workspace=b
指定文件夹下的所有工作区运行脚本
npm run test --workspace=packages
所有定义的工作区中执行脚本。
npm run test --workspaces --if-present
完整代码:my-workspaces
总结
它利用 npm 的工作区功能,这使得在所有子项目中运行测试、构建、清理等操作变得非常简单,简化了Monorepo项目中的流程。
测试
什么是工作区?
Monorepo中的子项目。
如何在根 package.json 指定工作区?
"workspaces": [
...
]
}
如何在特定工作区安装依赖?
npm install lodash -w project-a
工作区之间如何相互使用依赖?
npm install project-b -w packages/project-a
如何添加依赖到顶层?
npm install react