使用npm工作区时,如何为单个包安装依赖项



使用npm工作区,我有一个类似的文件夹结构

+-- package.json
+-- package-lock.json
+-- client
|   `-- package.json
+-- shared
|   `-- package.json
`-- server
`-- package.json

通常,在为nodejs应用程序创建生产构建时,我会运行npm ci --only=production,然后将node_modules复制到构建工件中。我不知道在工作空间中如何做到这一点。

如果我运行npm ci --only=production --workspace server,它会将依赖关系拆分为./node_modules./server/node_modules。也许我应该将两个node_modules复制(合并?(到一个构建工件中?

另一个选项可以是将./package-lock.json./server/package.json复制到新目录中并运行npm ci --only=production。它看起来确实有效,但我对npm的了解还不够,不知道这是否是个好主意。

要求是:

  1. node_modules应仅包括所选包的生产依赖项
  2. 依赖关系版本应由package-lock.json确定

node_modulesserver/node_modules之间的分裂是由于吊装造成的。如果有一种方法可以禁用提升,那么server的所有依赖项都将安装到server/node_modules。然而,当前版本的npm没有提供禁用工作空间吊装的方法。

在以下问题中有关于添加这样一个功能的讨论:

  • [RRFC]为工作区#287添加nohuist选项
  • 定义工作区项目之间共享的依赖项#375

我将使用install配置选项的组合。

使用Node v18.16.0和npm v9.7.2,这里是npm install --help的输出(需要npm>=v9.7.2才能正确省略dev依赖项(:

$ npm install --help
Install a package
Usage:
npm install [<package-spec> ...]
Options:
[-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle]
[-E|--save-exact] [-g|--global]
[--install-strategy <hoisted|nested|shallow|linked>] [--legacy-bundling]
[--global-style] [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]]
[--strict-peer-deps] [--no-package-lock] [--foreground-scripts]
[--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root] [--install-links]
aliases: add, i, in, ins, inst, insta, instal, isnt, isnta, isntal, isntall
Run "npm help install" for more info

在这种情况下,我建议使用

  • install-strategy(nested(
  • omit(dev(
  • workspace(server(

因此,从工作区根目录:

npm install --install-strategy=nested --omit=dev --workspace=server

您可能需要也可能不需要-install-strategy

这将使工作区根目录中的node_modules目录只包含server工作区的package.json文件中定义的依赖项,而忽略了devDependencies中定义的那些依赖项。您也可以使用--omit=peerserver工作区中删除peerDependencies

注意:根据依赖关系图的不同,这可能仍然会留下多个node_modules目录,这些目录需要组合才能创建工件,即--install-strategy=nested似乎无法正确用于npm工作区。但是,已安装的dep应该正确地与--workspace中传递的工作区隔离。下面是一个示例repo,展示了如何组合这些依赖关系。

最新更新