如何将 NPM 命令过滤为工作区模式(如过滤、包含、排除、glob、grep 或子目录)?

How to filter NPM commands to a pattern of workspaces (like filter, include, exclude, glob, grep or subdirectory)?

我想组织一个大型 NPM monorepo,这样我就可以 运行 根据类别或模式在许多(但不是全部)工作区上执行命令。

这可能是通过子目录,或者通过工作区名称中的模式(如前缀或后缀),但我看不出有任何方法可以单独在 NPM 中执行。


Yarn >= 2 中,可以使用 --include--exclude 标志以及 yarn workspaces foreach 上的 glob 模式,例如:

yarn workspaces foreach --include "@namespace/plugin-*" --include "@namespace/preset-*" run build

...这会使用该命名空间和 plugin-preset- 前缀构建所有工作区。


lerna中,--scope标志也采用了允许模式的globs,例如:

lerna run --scope "@namespace/plugin-*" --scope "@namespace/preset-*" run build

但在 NPM 中,据我在 NPM 的工作区文档 for v7 and for v8 中所见,它似乎没有相同的功能:

...但是我看不到任何方法可以 运行 目录中的所有工作区或匹配模式的所有工作区。我真的不想在每个脚本中按名称列出每个工作区,因为它们会很多。

它没有记录(在询问时),但是 NPM 可以 将工作区命令过滤到 子目录 的工作空间,方法是给 --workspace 标志一个路径作为其值。例如:

npm run --workspace packages/presets --workspace packages/plugins build

这将找到直接位于 $project_root/packages/presets/$project_root/packages/plugins/ 中的工作区,但不会找到这些子目录的子目录中的工作区。

Deeper-nested 可以使用 /** 包含子目录,例如:

npm run --workspace packages/** build

以上示例适用于组织成子目录的工作区,在 package.json 中定义如下:

  "workspaces": [
    "packages/plugins/*",
    "packages/presets/*",
    ...more
  ],

...或 catch-all 如:

  "workspaces": [
    "packages/**",
    ...more
  ],

虽然指向 --workspace 工作区的子目录而不是像这样的单个工作区,但在撰写本文时似乎没有在任何地方记录,它似乎是一个有意的、有计划的、受支持的功能。我发现了一条提议 deep in one of the rfcs:

Note: Globs are not supported as a valid --workspace argument value, the proposed alternative is to use npm --workspace= in which is a folder containing multiple workspaces.

我找不到任何明确说明该提案已实施的内容,但我尝试将我的 monorepo 重新组织到子目录中并使用带有 --workspace 标志的子目录,并且成功了。

他们在工作区名称中选择路径而不是 glob 模式的原因(就像 yarn 和 lerna 所做的那样)似乎是因为:

many pitfalls of supporting globs in the variety of supported shells and operational systems

非常完整。只是一些对我有用的调整:

我需要在 --workspace 标志之前使用 npm command/script,而我不需要在最后使用 /**

npm run <script-name> --workspace parent/directory/

示例:

npm publish --workspace packages/public/
npm run build --workspace packages/helpers/

npm 的其他部分对此进行了记录,因此需要进行一些挖掘。各个地方的信息一般都是一样的,因为--workspace标志是多个npm命令的配置:

Valid values for the workspace config are either:

Workspace names
Path to a workspace directory
Path to a parent workspace directory (will result in selecting all workspaces within that folder)

我发现它记录在案 here and here

不幸的是,似乎没有办法使用 glob。对事物进行分组的唯一方法是按父目录。

免责声明:我本来打算在 中添加评论,但它变得太长了,可能会遗漏细节。我认为这是正确的答案。