npm:何时使用“--force”和“--legacy-peer-deps”

t2a7ltrp  于 2022-11-14  发布在  其他
关注(0)|答案(3)|浏览(525)

我是npm的新手,正在尝试理解如何为部署重新创建node_modules目录。
我们使用npm ci而不是npm install来确保在部署过程中有一个干净的记录。但是,当我们在没有任何标志的情况下运行它时,我们会得到以下错误:
修复上游依赖关系冲突,或使用--force或--legacy-peer-deps重试此命令以接受不正确(可能已损坏)的依赖关系解析。
--forcenpm install的***documentation如下所示(npm cipage***上没有标志):
-f或--force参数将强制npm获取远程资源,即使磁盘上存在本地副本。
与此同时,--legacy-peer-deps的文档说明:
--传统对等部署:安装时忽略所有peerDependencies,采用npm版本4到版本6的样式。
看起来这两个标志都可以让npm ci生成node_modules目录,而不会出现任何问题,但是我仍然不清楚两者之间的区别。
据我所知,--force听起来像是基于最后下载的依赖项,并将覆盖任何以前下载的依赖项。同时,--legacy-peer-deps听起来像是在安装过程中总是跳过对等依赖项(无论那些是什么),即使没有问题。
这两个标志之间有什么区别,我们应该在什么时候使用它们?

yacmzcpb

yacmzcpb1#

在npm(v7)的新版本中,默认情况下,npm install在遇到冲突的 peerDependencies 时会失败,以前不是这样的。
在这里查看更多关于npm v7中对等依赖关系的信息。
两者的区别如下-

  • --legacy-peer-deps:安装时忽略所有 peerDependencies,使用npm版本4到版本6的样式。
  • --strict-peer-deps:如果遇到任何冲突的 peerDependencies,则会失败并中止安装过程。默认情况下,npm仅会在根项目的直接依赖项导致 peerDependencies 冲突时崩溃。
  • --force:将强制npm获取远程资源,即使磁盘上存在本地副本。
2w2cym1i

2w2cym1i2#

In the article npm 7 is now generally available!,
You have the option to retry with --force to bypass the conflict or --legacy-peer-deps command to ignore peer dependencies entirely (this behavior is similar to versions 4-6).
I agree this sentence is not really clear, but "ignore peer dependencies entirely" does not sound good. Let's use a real example:
Here is a peer dependency error I met when I npm install :

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: mobile@undefined
npm ERR! Found: react@17.0.1
npm ERR! node_modules/react
npm ERR!   react@"17.0.1" from the root project
npm ERR!   peer react@">=16.0.0" from @testing-library/react-native@7.2.0
npm ERR!   node_modules/@testing-library/react-native
npm ERR!     dev @testing-library/react-native@"7.2.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"16.13.1" from react-native@0.63.2
npm ERR! node_modules/react-native
npm ERR!   react-native@"https://github.com/expo/react-native/archive/sdk-39.0.4.tar.gz" from the root project
npm ERR!   peer react-native@">=0.59" from @testing-library/react-native@7.2.0
npm ERR!   node_modules/@testing-library/react-native
npm ERR!     dev @testing-library/react-native@"7.2.0" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See /Users/me/.npm/eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/me/.npm/_logs/2021-03-13T00_10_33_813Z-debug.log
npm ERR! code 1
npm ERR! path /Users/me/my-app
npm ERR! command failed
npm ERR! command sh -c sh ./bin/setup.sh

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/me/.npm/_logs/2021-03-13T00_10_33_860Z-debug.log

Below is the package-lock.json difference between --legacy-peer-deps and --force .

  1. If I run npm install --legacy-peer-deps , it adds this in my package-lock.json:
"node_modules/@unimodules/react-native-adapter": {
  "version": "5.7.0",
  "resolved": "https://registry.npmjs.org/@unimodules/react-native-adapter/-/react-native-adapter-5.7.0.tgz",
  "integrity": "sha512-L557/+sc8ZKJVgo1734HF1QNCxrt/fpqdmdNgySJT+kErux/AJNfPq3flsK0fyJduVmniTutYIMyW48cFoPKDA==",
  "dependencies": {
    "invariant": "^2.2.4",
    "lodash": "^4.5.0"
  },
  "peerDependencies": {
    "react-native": "*",
    "react-native-web": "~0.13.7"
  }
},

...

"@unimodules/react-native-adapter": {
  "version": "5.7.0",
  "resolved": "https://registry.npmjs.org/@unimodules/react-native-adapter/-/react-native-adapter-5.7.0.tgz",
  "integrity": "sha512-L557/+sc8ZKJVgo1734HF1QNCxrt/fpqdmdNgySJT+kErux/AJNfPq3flsK0fyJduVmniTutYIMyW48cFoPKDA==",
  "requires": {
    "invariant": "^2.2.4",
    "lodash": "^4.5.0"
  }
},
  1. If I use npm install --force , instead, it adds
"node_modules/expo/node_modules/@unimodules/react-native-adapter": {
  "version": "5.7.0",
  "resolved": "https://registry.npmjs.org/@unimodules/react-native-adapter/-/react-native-adapter-5.7.0.tgz",
  "integrity": "sha512-L557/+sc8ZKJVgo1734HF1QNCxrt/fpqdmdNgySJT+kErux/AJNfPq3flsK0fyJduVmniTutYIMyW48cFoPKDA==",
  "dependencies": {
    "invariant": "^2.2.4",
    "lodash": "^4.5.0"
  },
  "peerDependencies": {
    "react-native": "*",
    "react-native-web": "~0.13.7"
  }
},
"node_modules/expo/node_modules/inline-style-prefixer": {
  "version": "5.1.2",
  "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-5.1.2.tgz",
  "integrity": "sha512-PYUF+94gDfhy+LsQxM0g3d6Hge4l1pAqOSOiZuHWzMvQEGsbRQ/ck2WioLqrY2ZkHyPgVUXxn+hrkF7D6QUGbA==",
  "peer": true,
  "dependencies": {
    "css-in-js-utils": "^2.0.0"
  }
},
"node_modules/expo/node_modules/react-native-web": {
  "version": "0.13.18",
  "resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.13.18.tgz",
  "integrity": "sha512-WR/0ECAmwLQ2+2cL2Ur+0/swXFAtcSM0URoADJmG6D4MnY+wGc91JO8LoOTlgY0USBOY+qG/beRrjFa+RAuOiA==",
  "peer": true,
  "dependencies": {
    "array-find-index": "^1.0.2",
    "create-react-class": "^15.6.2",
    "deep-assign": "^3.0.0",
    "fbjs": "^1.0.0",
    "hyphenate-style-name": "^1.0.3",
    "inline-style-prefixer": "^5.1.0",
    "normalize-css-color": "^1.0.2",
    "prop-types": "^15.6.0",
    "react-timer-mixin": "^0.13.4"
  },
  "peerDependencies": {
    "react": ">=16.5.1",
    "react-dom": ">=16.5.1"
  }
},

...

  "dependencies": {
    "@unimodules/react-native-adapter": {
      "version": "5.7.0",
      "resolved": "https://registry.npmjs.org/@unimodules/react-native-adapter/-/react-native-adapter-5.7.0.tgz",
      "integrity": "sha512-L557/+sc8ZKJVgo1734HF1QNCxrt/fpqdmdNgySJT+kErux/AJNfPq3flsK0fyJduVmniTutYIMyW48cFoPKDA==",
      "requires": {
        "invariant": "^2.2.4",
        "lodash": "^4.5.0"
      }
    },
    "inline-style-prefixer": {
      "version": "5.1.2",
      "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-5.1.2.tgz",
      "integrity": "sha512-PYUF+94gDfhy+LsQxM0g3d6Hge4l1pAqOSOiZuHWzMvQEGsbRQ/ck2WioLqrY2ZkHyPgVUXxn+hrkF7D6QUGbA==",
      "peer": true,
      "requires": {
        "css-in-js-utils": "^2.0.0"
      }
    },
    "react-native-web": {
      "version": "0.13.18",
      "resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.13.18.tgz",
      "integrity": "sha512-WR/0ECAmwLQ2+2cL2Ur+0/swXFAtcSM0URoADJmG6D4MnY+wGc91JO8LoOTlgY0USBOY+qG/beRrjFa+RAuOiA==",
      "peer": true,
      "requires": {
        "array-find-index": "^1.0.2",
        "create-react-class": "^15.6.2",
        "deep-assign": "^3.0.0",
        "fbjs": "^1.0.0",
        "hyphenate-style-name": "^1.0.3",
        "inline-style-prefixer": "^5.1.0",
        "normalize-css-color": "^1.0.2",
        "prop-types": "^15.6.0",
        "react-timer-mixin": "^0.13.4"
      }
    }
  }
},

As you see, npm install --force still pins many dependency versions which is stricter.

q8l4jmvw

q8l4jmvw3#

对于那些想知道哪个更安全的人来说,答案是--force
--legacy-peer-deps完全忽略对等依赖项,这可能会破坏依赖项解析。
另一方面,--force简单地为冲突的依赖性设置不同的对等依赖性版本
但是使用强制并不总是理想的,因为每个依赖项版本都会占用额外的空间。对许多依赖项使用强制会增加你的总空间需求。

相关问题