yarn icon indicating copy to clipboard operation
yarn copied to clipboard

yarn run node version different than npm

Open aikar opened this issue 6 years ago • 15 comments

Do you want to request a feature or report a bug? Bug

What is the current behavior? When using yarn run/yarn start, the nodejs binary used does not match behavior of NPM, when using with NVM.

If the current behavior is a bug, please provide the steps to reproduce. install NVM (if not already present) create .nvmrc with 8.12.0 Have node 10 installed as default Have node 8.12 installed add to package.json scripts: "ver": "~/.nvm/nvm-exec node --version"

Run npm run ver and yarn run ver

>>> yarn ver
yarn run v1.15.2
$ ~/.nvm/nvm-exec node --version
v10.13.0
>>> npm run ver
> ~/.nvm/nvm-exec node --version
v8.12.0

We want to be able to require NVM on our developers machines and ensure every developer is using the same node version.

What is the expected behavior? That Node version 8 was used.

Please mention your node.js, yarn and operating system version. Linux Mint 18.3 yarn 1.15.2 nodejs 8.12.0 and 10.13.0

aikar avatar Apr 12 '19 16:04 aikar

Issue stems from yarn injecting into PATH: /tmp/yarn--1555088632779-0.744028615818612

aikar avatar Apr 12 '19 17:04 aikar

I was able to hack around it by stripping yarns package in a shell script

    # strip yarn - it injects node that overrides
    NEW_PATH=$(echo "$PATH" | sed -e "s/\\/tmp\\/yarn\d*-[^\:]*://g")
    export PATH="$NEW_PATH"
    ~/.nvm/nvm-exec "$@"

but this is obviously not the cleanest to need to do this....

aikar avatar Apr 12 '19 22:04 aikar

I filed an issue with NVM too, as it may be worthwhile for them to fix it, but it also begs to ask, how many other things are impacted by this altering behavior besides nvm?

Why is yarn injecting into path? when invoking 'yarn', it's already going to be using the top most node version anyways.

The only thing I can think of at this time that this yarn behavior would 'help' is if you were setup like this:

node 10 is at /usr/bin/node node 8 is at /opt/mycustomnode/bin/node path is /usr/bin/:stuff

you invoke /opt/mycustomnode/bin/node /path/to/yarn.js start

this would invoke yarn with your custom node, which would cause children to then go to /usr/bin/node

but is this a real world scenario? Wouldn't PATH="/opt/mycustomnode/bin/:$PATH" yarn start still be the recommendation?

aikar avatar Apr 12 '19 22:04 aikar

per discussion on https://github.com/creationix/nvm/issues/2027 - this isn't solvable at the nvm level. nvm can not hoist itself to top of PATH as that can impact the users choice of other binaries with the same name.

yarn needs to stop injecting itself into path as it is doing.

aikar avatar Apr 12 '19 23:04 aikar

Yarn enforces the node binary to be exactly the same one as the one used to run Yarn itself. If you want it to run with Node 8, call Yarn with Node 8.

arcanis avatar Apr 19 '19 22:04 arcanis

That’s incorrect tho - if node_modules/.bin has a node binary, that’s supposed to take precedence, for example.

ljharb avatar Apr 20 '19 03:04 ljharb

Which is what we do as well, I don't think that's the problem here? If there was a literal dependency on node we would have to respect it (and that would be unfortunate because it would just hide issues), but here the OP uses nvm within a script and nvm refuses to update the PATH, which is entirely different.

To clarify, this behavior is expected and fixes numerous issues that got reported in the past. The problem described in the op is caused by using a specific Node release from within your package configuration - this is a bug in the application.

To give you an example, if Yarn wasn't enforcing the Node version, it would cause native packages to be compiled against a different Node version than the one used by your scripts (since their build scripts would have no idea whatsoever about nvm).

arcanis avatar Apr 20 '19 04:04 arcanis

nvm does set the PATH, though - everything inside nvm-exec has the PATH set such that the given node version is available under node. However, if yarn alters the PATH (beyond adding node_modules/.bin, like npm run does) then that can supersede nvm-exec's choice.

Put another way, this isn't behavior npm has, and it works fine with npm, so if it's not working with yarn, I'm not clear on why that's a bug in the application.

ljharb avatar Apr 20 '19 06:04 ljharb

Put another way, this isn't behavior npm has, and it works fine with npm, so if it's not working with yarn, I'm not clear on why that's a bug in the application.

Npm putting a gun on the coffee table doesn't require Yarn to do so. The value we provide is as a stable package manager with reproducible builds. That means we're ready to push against patterns that npm never cared to teach why they were problematic (similar to how we're working to enforce package boundaries).

Said another way, solutions should be implemented at the right layers. It's more work - especially for us -, but it's the right thing. The fact that npm should do something but doesn't is no reason why Yarn should suffer from the same bug.

arcanis avatar Apr 20 '19 06:04 arcanis

Note that in most (all?) such cases, the problem is that the application is using an unsafe pattern when a safe alternative is available.

Of course if there was absolutely no way to achieve the same user story safely then I would consider the sub-par solutions, but in this case I believe it would do more harm than not.

arcanis avatar Apr 20 '19 06:04 arcanis

Why is using nvm-exec in a run-script an unsafe pattern?

ljharb avatar Apr 20 '19 07:04 ljharb

Because everything that Yarn spawns must use the same Node release, otherwise some dependencies will work and others won't, cf the case I mentioned above with native dependencies.

By contrast I don't have anything against calling Yarn via nvm-exec; you can even use the yarn-path settings to make it transparent (just make the target a shellscript that shells out to nvm-exec + the real path to yarn).

arcanis avatar Apr 20 '19 08:04 arcanis

I solve that easy with

yarn add -D [email protected]
PATH=$(pwd)/node_modules/node/bin:$PATH yarn compile-web

installing the needed nodejs version as npm dependency solves a lot of problems when you want to incremental switch away from nodejs and npm yarn hope that helps you too and you will not need such workarounds the good thing is this is also electron compatible and any other engine.

lemanschik avatar Mar 29 '23 10:03 lemanschik

I was able to solve this by running yarn in the following way:

`which node` `which yarn` # ... insert any yarn arguments here ...

It uses both node and yarn on the path and does the right thing.

vjeux avatar Sep 18 '24 18:09 vjeux

I was able to solve this by running yarn in the following way:

`which node` `which yarn` # ... insert any yarn arguments here ...

It uses both node and yarn on the path and does the right thing.

Sorry to tell you that but when you write yarn you will automatically use the versions from the path that is default behavior your which makes zero sense less then zero sorry for the down vote.

lemanschik avatar Sep 27 '24 06:09 lemanschik