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

发布于 2025-01-11 15:28:18 字数 1146 浏览 0 评论 0 原文

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

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


Yarn >= 2 中,可以在 yarn 工作区 foreach 上使用带有 glob 模式的 --include--exclude 标志来实现这一点,例如:

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

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


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

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

但是在NPM中,据我在NPM的工作区中看到的文档 v7对于 v8,它似乎没有相同的功能:

  • 它有一个标志 --workspace 可以多次使用来创建数组,但似乎只接受确切的工作空间名称,
  • ...以及一个标志 --workspaces ,它似乎在所有工作区中运行,

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

I'd like to organise a large NPM monorepo such that I can run commands on many (but not all) workspaces according to a category or pattern.

This could be by subdirectory, or by a pattern in the workspace names like a prefix or suffix, but I can't see any way to do either in NPM alone.


In Yarn >= 2, this is possible using --include or --exclude flags with glob patterns on yarn workspaces foreach, for example:

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

...and that builds all your workspaces with that namespace and either the plugin- or preset- prefix.


In lerna, the --scope flag also took globs allowing patterns, for example:

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

But in NPM, as far I can see in NPM's workspaces documentation for v7 and for v8, it doesn't seem to have the same feature:

  • It has a flag --workspace which may be used multiple times to create an array but appears to only accept exact workspace names,
  • ...and a flag --workspaces which appears to run in all workspaces,

...but I can't see any way to either run on all workspaces in a directory or all workspaces matching a pattern. I really don't want to have to list every workspace by name in every script, as there's going to be a lot of them.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

晒暮凉 2025-01-18 15:28:18

它没有记录(在询问时),但 NPM 可以 通过提供 --workspace 将工作区命令过滤到工作区的子目录 将路径标记为其值。例如:

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

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

可以使用 /** 包含更深层次的嵌套子目录,例如:

npm run --workspace packages/** build

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

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

的包罗万象:

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

...或者像这样 在撰写本文时,将 --workspace 指向工作区的子目录而不是单个工作区似乎没有在任何地方记录,它确实似乎是一个有意的、计划的、受支持的功能。我发现了一条建议在其中一个 rfcs 深处的注释:

注意:不支持将 Glob 作为有效的 --workspace 参数值,建议的替代方案是使用 npm --workspace=,其中是包含多个工作空间的文件夹。

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

他们在工作区名称中选择路径而不是全局模式(如yarn和lerna)的原因似乎是因为:

在各种受支持的 shell 和操作系统中支持 glob 的许多陷阱

It's not documented (at time of asking), but NPM can filter workspace commands to subdirectories of workspaces by giving the --workspace flag a path as its value. For example:

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

This will find workspaces that are directly in $project_root/packages/presets/ or $project_root/packages/plugins/, but not workspaces in subdirectories of these subdirectories.

Deeper-nested subdirectories can be included using /**, like:

npm run --workspace packages/** build

The above examples would work with workspaces organised into subdirectories, defined in package.json like:

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

...or a catch-all like:

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

While pointing --workspace to subdirectories of workspaces instead of individual workspaces like this doesn't seem to be documented anywhere at time of writing, it does appear to be an intentional, planned, supported feature. I found a note proposing it 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.

I couldn't find anything explicitly stating that this proposal was implemented, but I tried reorganising my monorepo into subdirectories and using a subdirectory with the --workspace flag, and it worked.

Their reason for choosing paths rather than glob patterns in workspace names (like yarn does and lerna did) appears to be because of the:

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

最单纯的乌龟 2025-01-18 15:28:18

这个答案非常完整。只需进行一些对我有用的调整:

我需要在 --workspace 标志之前使用 npm 命令/脚本,并且最后不需要使用 /**

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)

我发现它记录在案 此处此处

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

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

This answer is very complete. Just a couple of tweaks that worked for me:

I needed to use the npm command/script before the --workspace flag, and I did not needed to use the /** at the end.

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

Examples:

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

This is documented in other parts of npm so it took a bit of digging. The information is generally the same in all places, because the --workspace flag is a configuration for multiple npm commands:

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)

I found it documented here and here.

Unfortunately there does not seem to be a way to use globs. Only way to group things would be by parent directory.

Disclaimer: I was going to add a comment to this answer but it was becoming too long and details might have been missed. I think that is the right answer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文