npm: когда использовать --force и --legacy-peer-deps

Я новичок в npm и пытаюсь понять, как работает воссоздание каталога node_modules для развертывания.

Мы используем npm ci вместо npm install, чтобы обеспечить чистый лист во время развертывания. Однако, когда мы запускаем его без каких-либо флагов, мы получаем следующую ошибку:

Устраните конфликт зависимостей восходящего потока или повторите эту команду с помощью --force или --legacy-peer-deps, чтобы принять неправильное (и потенциально нарушенное) разрешение зависимостей.

документация для npm install для --force выглядит следующим образом (нет флагов на страница):

Аргумент -f или --force заставит npm извлекать удаленные ресурсы, даже если на диске существует локальная копия.

Между тем, в документации для --legacy-peer-deps говорится:

--legacy-peer-deps: игнорировать все peerDependencies при установке в стиле npm версии 4 - версии 6.

Кажется, что оба флага позволят npm ci без проблем сгенерировать каталог node_modules, но я все еще не понимаю, в чем разница между ними.

Насколько я понимаю, --force звучит так, как будто он будет работать по принципу last-dependency-loaded-wins и перезапишет все ранее загруженные зависимости. Между тем, --legacy-peer-deps звучит так, как будто он всегда будет пропускать зависимости одноранговых узлов (какими бы они ни были) во время установки, даже если нет никаких проблем.

В чем разница между двумя флагами и когда их следует использовать?


person Floating Sunfish    schedule 03.02.2021    source источник


Ответы (2)


В новой версии npm (v7) по умолчанию npm install завершится ошибкой при обнаружении конфликтующих peerDependencies. Раньше такого не было.

Взгляните здесь для получения дополнительной информации о зависимостях пиров в npm v7.

Различия между ними ниже -

  • --legacy-peer-deps: игнорировать все peerDependencies при установке в стиле npm версий 4–6.

  • --strict-peer-deps: сбой и прерывание процесса установки для любых конфликтующих peerDependencies при обнаружении. По умолчанию npm аварийно завершает работу только из-за конфликтов peerDependencies, вызванных прямыми зависимостями корневого проекта.

person Eduardo Almeida    schedule 03.02.2021
comment
и что из --force на OP? Есть ли преимущества в производительности одного по сравнению с другим или в целом с дедупликацией пакетов и т. Д.? - person jflay; 10.02.2021

В статье https://github.blog/2021-02-02-npm-7-is-now-generally-available/

У вас есть возможность повторить попытку с --force, чтобы обойти конфликт, или командой --legacy-peer-deps, чтобы полностью игнорировать зависимости одноранговых узлов (это поведение аналогично версиям 4-6).

Я согласен, что это предложение не совсем ясное, но полностью игнорировать взаимозависимости не звучит хорошо. Возьмем реальный пример:

Вот ошибка взаимозависимости, с которой я столкнулся, когда 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: [email protected]
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/[email protected]
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 [email protected]
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/[email protected]
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
"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"
      }
    }
  }
},
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
"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"
      }
    }
  }
},
33_860Z-debug.log

Ниже показана разница в package-lock.json между --legacy-peer-deps и --force.

  1. Если я запустил npm install --legacy-peer-deps, он добавит это в мой 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. Если вместо этого я использую npm install --force, он добавляет
"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"
      }
    }
  }
},

Как видите, npm install --force по-прежнему связывает многие версии зависимостей, что является более строгим.

Итак, для npm 7, если npm install выйдет из строя из-за проблемы взаимозависимости, npm install --force - это первое, что вы можете попробовать.

person Hongbo Miao    schedule 13.03.2021