https://yarnpkg.com/en/docs/cli/upgrade says for yarn upgrade
that it
updates all dependencies to their latest version based on the version range specified in the
package.json
file
But it says for yarn upgrade [package]
that it
upgrades a single named package to the version specified by the
latest
tag (potentially upgrading the package across major versions)
Why don't these commands behave equivalently as far as their strategy for choosing package versions? I would expect yarn upgrade [package]
to do exactly what yarn upgrade
does, just for a single package vs. all packages.
Put differently, why isn't there a command for upgrading just a single package to the latest version based on the range in package.json
?
This has been puzzling me too. Also I'd expect a command to be a bit more explicit if it's jumping major versions.
I don't know, I think it is a bug, feel free to send a PR to make them the same
I find having a command which upgrades a specific package to lateset
quite useful. I hope this feature isn't removed.
It would _also_ be useful to be able to upgrade a specific package the the latest allowed by the packages.json specified version range.
In my opinion:
yarn upgrade
should behave the same for a single package as well as all packages.npm update
.@bhouser we could potentially add a flag to upgrade
to make it upgrade to latest
(potentially across major versions). However I don't think we need to do that because you can just rerun yarn add [package]
and that will install latest
.
Personally, I would expect yarn update [optional package]
to update to the latest version matching the version range (also updating the lockfile if needed) while yarn upgrade [optional package]
would go to the latest version, ignoring the version ranges. Keeps it nicely separated, too.
To add to @wearhere:
Whatever happens, the behaviour should indeed be the same, whether you're providing a specific package or not. However, with my proposed change above upgrade
has one distinct advantage over re-running add
: it can fail if you try to upgrade a package that is not a dependency of the project, whereas add
would simply add it.
In case it's useful to anyone finding/participating in this discussion, I've just found there's a currently undocumented upgrade-interactive
command. Which is brilliant.
$ yarn upgrade-interactive
yarn upgrade-interactive v0.23.4
? Choose which packages to update. (Press <space> to select, <a> to toggle all, <i> to inverse selection)
devDependencies
❯◯ postcss 5.2.17 ❯ 6.0.1 http://postcss.org/
◯ postcss-cli 3.2.0 ❯ 4.0.0 https://github.com/postcss/postcss-cli#readme
◯ sugarss 0.2.0 ❯ 1.0.0 https://github.com/postcss/sugarss#readme
j
and k
navigate through the packages.
While working on PR #3510 I discovered why this happens.
When you don't specify a package name, it loads the list of dependencies from your package.json
file, including the version ranges.
When you specify a package name, it doesn't load package.json
and instead uses what you passed in as the dependency list.
So upgrade
is actually expecting something like: yarn upgrade foo@^1.2.3
But most people don't add that version range with the (false) assumption that Yarn will pick up the version range from package.json. It does not.
Under the covers the upgrade
command actually passes the package list to the add
command, and add
does the actual work of resolving and installing the packages.
This means that yarn upgrade foo
is roughly equivalent to yarn add foo
which will go find the version tagged latest
of foo
(since no version range was specified) and install it.
I don't really like that behavior, but it made sense once I looked at the code.
I tried to start some discussion in #3384 about adding a flag to upgrade <package_name>
that would tell it to use the version range in package.json, but didn't see much feedback, so haven't put together a PR for that yet.
I'm going to mark this issue closed because the original question (why does it behave like this) is answered.
I'd like to move the discussion about making a breaking change to redefine how upgrade and upgrade-interactive determine version ranges to #3603
Most helpful comment
In case it's useful to anyone finding/participating in this discussion, I've just found there's a currently undocumented
upgrade-interactive
command. Which is brilliant.j
andk
navigate through the packages.