Skip to content

Global node_modules binaries are preferred to local #86

@iiroj

Description

@iiroj

Hello,

I recently released lint-staged@16.3.0 and replaced nano-spawn with tinyexec. An issue arose where it looks like the node_modules/.bin resolution of tinyexec prefers globally-installed executables to locally installed ones: lint-staged/lint-staged#1736

Both the npx and nano-spawn have an algorithm which prefers a locally installed node_modules/.bin/eslint to a globally installed one (eg. via npm install --global eslint), so I would have assumed tinyexec works the same way.

I believe the issue is that tinyexec adds the node_modules/.bin/ entries to the end of the current PATH, instead of in front. For example, when running tinyexec my process.env.PATH looks like this when split from ::

/opt/homebrew/bin # npm install --global goes here
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
/Users/iiroj/Documents/Git/lint-staged/node_modules/.bin # npm install goes here
/Users/iiroj/Documents/Git/node_modules/.bin
/Users/iiroj/Documents/node_modules/.bin
/Users/iiroj/node_modules/.bin
/Users/node_modules/.bin
/node_modules/.bin

To work like npx, it should probably look like this instead:

/Users/iiroj/Documents/Git/lint-staged/node_modules/.bin # npm install goes here
/Users/iiroj/Documents/Git/node_modules/.bin
/Users/iiroj/Documents/node_modules/.bin
/Users/iiroj/node_modules/.bin
/Users/node_modules/.bin
/node_modules/.bin
/opt/homebrew/bin # npm install --global goes here
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin

Would you consider changing the order directly in tinyexec?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions