Skip to content
This repository has been archived by the owner on Jan 20, 2022. It is now read-only.

Replace entire dep sets, so peer loops don't lock #182

Closed
wants to merge 2 commits into from

Conversation

isaacs
Copy link
Contributor

@isaacs isaacs commented Nov 12, 2020

Discovered an interesting issue with the following dependency set:

{
  "devDependencies": {
    "webpack-dev-server": "^3.11.0",
    "@pmmmwh/react-refresh-webpack-plugin": "^0.4.3"
  }
}

webpack-dev-server here has a peerDependency on webpack v4. But, the
dependencies of @pmmmwh/react-refresh-webpack-plugin have peer
dependencies on webpack at 4 || 5.

So, a resolution should be possible. Since the
@pmmmwh/react-refresh-webpack-plugin package is alphabetically first,
it loads its deps, and ends up placing webpack@5 to satisfy the dep with
the latest and greatest. Then when webpack-dev-server gets to its
eventual peer dep on webpack, it can't replace it, because webpack@5
has a dependency on terser-webpack-plugin@^5.0.3, which in turn has a
peer dependency on webpack@5.4.0.

When we check to see if webpack 5 can be replaced, we find it has a
dependent, and reject the replacement. But that dependent is only
present as a dependency of the thing being replaced, so should not be
considered.

Second, while the source of the terser-webpack-plugin is webpack, it
cannot be installed there, because it has peer deps that are also peer
deps of webpack. So, we must place it in the root node_modules, but
were not attempting the "source" location overrides, because the root is
not the source. This was a second issue resulting in ERESOLVE errors
even when --force was applied, with the following dependency set:

{
  "devDependencies": {
    "webpack-dev-server": "^3.11.0",
    "webpack": "^5.0.0"
  }
}

Fixes: #180
Fixes: npm/cli#2123

Discovered an interesting issue with the following dependency set:

```json
{
  "devDependencies": {
    "webpack-dev-server": "^3.11.0",
    "@pmmmwh/react-refresh-webpack-plugin": "^0.4.3"
  }
}
```

`webpack-dev-server` here has a peerDependency on webpack v4.  But, the
dependencies of `@pmmmwh/react-refresh-webpack-plugin` have peer
dependencies on webpack at `4 || 5`.

So, a resolution _should_ be possible.  Since the
`@pmmmwh/react-refresh-webpack-plugin` package is alphabetically first,
it loads its deps, and ends up placing webpack@5 to satisfy the dep with
the latest and greatest.  Then when `webpack-dev-server` gets to its
eventual peer dep on webpack, it can't replace it, because `webpack@5`
has a dependency on `terser-webpack-plugin@^5.0.3`, which in turn has a
peer dependency on `webpack@5.4.0`.

When we check to see if webpack 5 can be replaced, we find it has a
dependent, and reject the replacement.  But that dependent is only
present as a dependency of the thing being replaced, so should not be
considered.

Second, while the source of the `terser-webpack-plugin` is `webpack`, it
cannot be installed there, because it has peer deps that are also peer
deps of webpack.  So, we _must_ place it in the root node_modules, but
were not attempting the "source" location overrides, because the root is
not the source.  This was a second issue resulting in `ERESOLVE` errors
even when `--force` was applied, with this dependency set:

```json
{
  "devDependencies": {
    "webpack-dev-server": "^3.11.0",
    "webpack": "^5.0.0"
  }
}
```

Fixes: #180
Fixes: npm/cli#2123
Copy link
Contributor

@nlf nlf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 looks good, this makes sense!

isaacs added a commit that referenced this pull request Nov 13, 2020
Discovered an interesting issue with the following dependency set:

```json
{
  "devDependencies": {
    "webpack-dev-server": "^3.11.0",
    "@pmmmwh/react-refresh-webpack-plugin": "^0.4.3"
  }
}
```

`webpack-dev-server` here has a peerDependency on webpack v4.  But, the
dependencies of `@pmmmwh/react-refresh-webpack-plugin` have peer
dependencies on webpack at `4 || 5`.

So, a resolution _should_ be possible.  Since the
`@pmmmwh/react-refresh-webpack-plugin` package is alphabetically first,
it loads its deps, and ends up placing webpack@5 to satisfy the dep with
the latest and greatest.  Then when `webpack-dev-server` gets to its
eventual peer dep on webpack, it can't replace it, because `webpack@5`
has a dependency on `terser-webpack-plugin@^5.0.3`, which in turn has a
peer dependency on `webpack@5.4.0`.

When we check to see if webpack 5 can be replaced, we find it has a
dependent, and reject the replacement.  But that dependent is only
present as a dependency of the thing being replaced, so should not be
considered.

Second, while the source of the `terser-webpack-plugin` is `webpack`, it
cannot be installed there, because it has peer deps that are also peer
deps of webpack.  So, we _must_ place it in the root node_modules, but
were not attempting the "source" location overrides, because the root is
not the source.  This was a second issue resulting in `ERESOLVE` errors
even when `--force` was applied, with this dependency set:

```json
{
  "devDependencies": {
    "webpack-dev-server": "^3.11.0",
    "webpack": "^5.0.0"
  }
}
```

Fixes: #180
Fixes: npm/cli#2123

PR-URL: https://github.com/pull/182
Credit: @isaacs
Close: #182
Reviewed-by: @darcyclarke
@wraithgar wraithgar deleted the isaacs/node-replace-dep-set branch April 22, 2021 17:44
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ERESOLVE in force mode [BUG] npm 7 makes incorrect suggestion when encountering peer deps issues
2 participants