【问题标题】:NPM 7 workspaces - how to install new package in workspace?NPM 7 工作区 - 如何在工作区中安装新包?
【发布时间】:2021-03-22 01:19:44
【问题描述】:

如果我有这样的NPM 7 workspace

root
   - submodule0
   - submodule1
   - submodule2

然后我导航到 submodule0 目录并运行 npm i somepackage 它似乎通过在 submodule0 目录中创建一个新的 package-lock.json 并在那里安装所有依赖项来“破坏”工作区。换句话说,它只是执行我创建工作区之前存在的旧行为。 我希望有一个类似于lerna 的命令,我可以从 root 在 submodule0 中安装一个新包。比如:

npm i somepackage --scope submodule0

到目前为止,我能找到的唯一解决方法是编辑 submodule0 package.json 并手动添加 somepackage。然后从根目录运行npm i。显然这并不理想,因为我需要查找 @latest 版本、导航到子目录、打开 package.json 等等等,而不是只在根目录中键入一行。

【问题讨论】:

  • 我也有同样的问题
  • 您是否尝试进入工作空间的根目录并进行 npm 更新?

标签: node.js npm npm-install


【解决方案1】:

在 npm v7.14.0 中添加了对 npm installnpm uninstall 的工作区支持。你现在可以这样做:

npm i somepackage --workspace=submodule0

卸载模块一直是最大的痛苦,所以这真的很令人兴奋。 npm 团队似乎在慢慢地一一添加对命令的支持。在此处关注更新:https://github.com/npm/cli/blob/latest/CHANGELOG.md

【讨论】:

    【解决方案2】:

    我也很困惑为什么 npm 工作区发布时没有此功能。

    我当前的解决方法是使用add-dependencies 包,它将依赖项添加到已声明的 package.json 文件中,同时跳过安装过程。

    npm i add-dependencies -g
    

    然后,从 monorepo 的顶层,您可以运行:

    npx add-dependencies ./submodule0/package.json somepackage && npm i
    

    希望--workspace 参数很快会添加到npm i 以避免这个问题。

    【讨论】:

    • 这是一个非常有用的建议。我想我可以通过使用它来将它归结为根目录中的一个 npm 脚本(尽管我可能必须使用 JS 使其与操作系统无关)。如果我这样做,我会返回并包含在此处。
    【解决方案3】:

    如果你有NPM v7.14.0或以上版本请参考上面mattwad的回答

    原答案

    我对这些建议不太满意,但将所有建议结合起来,在没有任何依赖关系的 npm 脚本中使用它:

    {
       "add": "npm install --package-lock-only --no-package-lock --prefix",
       "postadd": "npm install"
    }
    

    这可以像下面这样使用:npm run add -- submodule0 somepackage

    【讨论】:

    • 我现在最喜欢这种方法——没有依赖关系。
    【解决方案4】:

    只添加到 package.json

    你可以使用它只将包安装到 package.json 中(你不需要外部依赖)

    npm i --prefix packages/test --save --package-lock-only --no-package-lock express
    

    随后 npm i 将指定的依赖项安装到单存储库根节点模块中

    勒纳

    也可以使用lerna来使用工作区名来安装依赖

    package.json

    {
      "name": "mono",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
         "wsi": "function workspaceinstall() { ( scope=$1; shift; lerna exec --scope \"$scope\" -- npm install --package-lock-only --no-package-lock \"$@\") }; workspaceinstall"
      },
      "author": "",
      "license": "ISC",
      "workspaces": {
        "packages": [
          "packages/**"
        ]
      }
    }
    
    

    lerna.json

    {
      "version": "1.0.0",
      "npmClient": "npm",
      "packages": ["packages/**"]
    }
    
    
    npm run wsi [workspace name] [dependency name to install]
    npm run wsi @workspace/test express
    npm run wsi @workspace/test express --save-prod 
    npm run wsi @workspace/test @types/express --save-dev 
    

    wsi 脚本只为提供的工作区名称修改 package.json,要实际安装依赖项,您必须运行 npm i

    【讨论】:

      【解决方案5】:

      在我的情况下,与你的情况类似,我从所有内部项目中删除了所有依赖项,还删除了 package-lock.json,并将所有内容安装在根目录中。

      /
        node_modules
        package.json >> all dependencies
        package-lock.json >> the only lock file that exists in the repo
        /packages
          /A
            package.json >> no dependencies
            -- no package-lock.json
          /B
            package.json >> no dependencies
            -- no package-lock.json
          /C
            package.json >> no dependencies
            -- no package-lock.json
      

      这样,node_modules 文件夹只在根目录下,package-lock.json 文件也在根目录下。

      如果我允许每个项目都有自己的 package-lock.json,我开始看到安装和运行时错误(因为每个项目都可以有自己的 node_modules 和自己的依赖版本)。

      这是我认为最有效的方式。

      【讨论】:

      • 如果您这样做,您介意我问一下您使用工作区的目的吗?您的建议会起作用,但除非我错过了什么,否则在我看来,您将工作区视为不是工作区?
      • 当然,C 是一个通用包,我拥有我所有的服务类,而 A 和 B 是具有 koa 端点路由器配置的 API,可重用用 C 编写的服务。之前,我不得不重新发布C 每次到私有 npm 安装在 A 和 B。现在,我可以在没有任何安装的情况下引用 C。
      【解决方案6】:

      在尝试使用 npm install--prefix --save --package-lock-only --no-package-lock 选项后,npm 总是为我自己的尚未发布到注册表的 monorepo 包提供错误 E404 - Not Found。因此,即使尝试安装外部软件包,由于我当前在 package.json 中的依赖关系,它也会失败。

      为了解决这个问题,我最终混合了之前的建议:

      "scripts": {
          "add": "add-dependencies $npm_config_scope/package.json",
          "postadd": "npm i",
      },
      "devDependencies": {
          "add-dependencies": "^1.1.0"
      },
      

      那我可以做:

      npm run add --scope=packages/app express
      npm run add --scope=packages/core eslint jest -D
      

      这适用于安装外部软件包。要安装我自己的位于 monorepo 中的包,我仍然需要手动编辑 package.json,否则我会得到 package not found error

      【讨论】:

      • 如果你能添加一些关于它如何以及为什么工作的解释会更好,而其他人没有。
      猜你喜欢
      • 2018-10-18
      • 2021-09-23
      • 2021-06-02
      • 2023-03-24
      • 2014-12-06
      • 1970-01-01
      • 1970-01-01
      • 2022-11-02
      • 2022-07-26
      相关资源
      最近更新 更多