使用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的了解还不够,不知道这是否是个好主意。
要求是:
node_modules
应仅包括所选包的生产依赖项- 依赖关系版本应由
package-lock.json
确定
node_modules
和server/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=peer
从server
工作区中删除peerDependencies
。
注意:根据依赖关系图的不同,这可能仍然会留下多个node_modules
目录,这些目录需要组合才能创建工件,即--install-strategy=nested
似乎无法正确用于npm工作区。但是,已安装的dep应该正确地与--workspace
中传递的工作区隔离。下面是一个示例repo,展示了如何组合这些依赖关系。