yarn run with bin in local node_modules

Created on 11 Oct 2016  ·  27Comments  ·  Source: yarnpkg/yarn

Do you want to request a _feature_ or report a _bug_?
Report a bug

What is the current behavior?
From npm with respect to npm run: In addition to the shell's pre-existing PATH, npm run adds node_modules/.bin to the PATH provided to scripts. Any binaries provided by locally-installed dependencies can be used without the node_modules/.bin prefix.

If the current behavior is a bug, please provide the steps to reproduce.

Add additional entry to the scripts section of the package.json without installing the dependency globally (in this case mocha).

  "scripts": {
    "test-api": "mocha test/api"
  },

What is the expected behavior?

If I run npm run test-api it will resolve mocha to the local copy. However yarn run test-api will produce:

$ "mocha test/api" 
sh: 1: mocha test/api: not found

Please mention your node.js, yarn and operating system version.
node: 6.7.0
yarn: 0.15
os: Ubuntu 16.04

cat-bug

Most helpful comment

Thanks for the bug report! This is pretty important. I'll try to take a look tonight.

All 27 comments

Thanks for the bug report! This is pretty important. I'll try to take a look tonight.

Duplicate with more info here: https://github.com/yarnpkg/yarn/issues/735

@notahat - That's actually a separate issue. This issue is saying that yarn run is not running executables in the node_modules/.bin directory (eg. mocha test/api in a script should essentially run node_modules/.bin/mocha test/api if mocha is an npm dependency of the app), whereas your issue #735 is about running shell commands (I think?)

@Daniel15 I think it's the same thing.

It's not that yarn isn't finding stuff in node_modules/.bin, it's that yarn is shelling out in such a way that the command is mocha test/api, rather than mocha with an argument of test/api. Not surprisingly, the shell can't find an executable called mocha test/api.

Ohh I see! That might be it. I'll take a look tonight 😄

@Daniel15 @notahat I think it's the root of the issue:

echo `npm bin` #path_to_the_project/node_modules/.bin
echo `yarn bin` #path_to_the_project/node_modules/.bin/node_modules/.bin

yarn duplicates /node_modules/.bin part.

Edit: see my next comment.

@slmgc I don't see that when I try it.

$ cd /path/to/project
$ yarn bin
/path/to/project/node_modules/.bin

BUT, if I do this:

$ cd /path/to/project/node_modules/.bin
$ yarn bin
/path/to/project/node_modules/.bin/node_modules/.bin

That definitely isn't right, but I don't think it's the source of the problem as I'm seeing it.

@slmgc I don't see that either. Both paths are identical

Both look identical for me as well.

➜  js git:(master) npm bin
/Users/justin/Sites/my-project/js/node_modules/.bin
➜  js git:(master) yarn bin
/Users/justin/Sites/my-project/js/node_modules/.bin

Though I am encountering this error _(see issue 782)_.

@notahat @f0rr0 sorry guys, you are correct: I was trying to figure out the difference and indeed pwd was path_to_the_project/node_modules/.bin. But, nevertheless, there is a difference between npm bin & yarn bin when you are inside of node_modules/.bin.

@notahat is correct https://github.com/yarnpkg/yarn/issues/733#issuecomment-253086168. Running commands with no arguments works like pwd or ls.

As long as your command script has no arguments, it runs fine. With arguments it will fail to find the files.

"scripts": {
    "start": "node app.js",
    "test": "./node_modules/.bin/mocha",
    "bdd":  "./node_modules/.bin/cucumberjs test"
  },
  • yarn test runs fine
  • yarn start and yarn run bdd fail.

If I remove the arguments for start and bdd script, it runs fine.

Hmm I'm having trouble replicating the issue on Windows.

package.json:

{
  "name": "yarntest_issue733",
  "version": "1.0.0",
  "devDependencies": {
    "jest": "^16.0.1"
  },
  "scripts": {
    "foo": "jest __tests__/hello-test.js"
  }
}

__tests__/hello-test.js is just a dummy Jest test suite:

test('foo', () => {});

Output:

C:\temp\yarntest12  ([email protected])
λ c:\src\yarn\bin\yarn run foo
yarn run v0.15.1
$ "jest hello-test.js"
 PASS  __tests__\hello-test.js
  √ foo (1ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.354s
Ran all test suites matching "hello-test.js".
Done in 2.08s.

I'll have to try it on Ubuntu again, once I figure out how to fix VirtualBox (or build a Docker image or something). It's no longer even opening on my desktop computer, and bluescreening when I start VMs on my work laptop 😕

I came across this issue as well, and I did a bit of digging. It looks like this line encases cmd in double quotes, eventually sending it to child.spawn() here with the quotes intact, which causes the error.

My test script is as follows:

  "scripts": {
    "start": "echo 'hello'"
  }

In child.js:

const proc = child.spawn(program, args, opts);
console.log('program:', program, 'args:', args);

Outputs:

program: sh args: [ '-c', '"echo \'hello\'" ' ]

Where it should be:

program: sh args: [ '-c', 'echo \'hello\'' ]

Removing the double quotes in run.js seems to make it work fine.

@AlicanC. Seems like it was intentional adding the double quotes. Found the commit using git blame.

Commit: https://github.com/yarnpkg/yarn/commit/e16953540bebbd42fe4a495ff2f6314568c972c1

It appears that npm doesn’t do the quoting e169535 introduced; seems like this feature should work the same as npm’s

Sorry I didn't get a chance to look into this more fully tonight. It looks like @ticky submitted a PR though - Thanks!

Yes, it's my mess. The only tested commands are currently "add", "install" and "self-update". I will add tests for "run" (and others if I have time) so this doesn't happen again.

Thanks to @billxinli for reporting and @ticky for fixing it 👍

Fixed via #809.

New release soon @kittens ?

I can confirm that it's still not fixed in yarn 0.19.1.. 😞
@Daniel15 @kittens any news ?

@mattieutu, the fix for this was released in 0.16.0, hope it hasn't regressed :(

I don't know, but I can reproduce exactly the same problem now with the last version.

With ayarn add laravel-mix which install webpack, cross-env, and others, there is no .bin folder, and I can't launch them with package.json scripts.

I had to remove the node_modules folder and reinstall it with npm :-/

Same here with laravel-mix

@mathieutu @dbpolito I suspect this is in fact an entirely separate issue where binstubs are not created for any dependency which isn’t top-level. Looks like #2758 might be your ticket?

Yeah, it seems to be exactly that thing.
I'm wondering why I thought it was this issue... I'll continue on the #2758.

Was this page helpful?
0 / 5 - 0 ratings