You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This issue relates to the augmentation of the PATH environment variable to allow easy use of bin scripts provided by npm packages, i.e. for use inside dev commands.
It does not affect the resolution of the right dev_cmds directory.
I had previously assumed that npm, npx, and yarn would search for bin scripts in the .bin directories of all node_modules directories up the path hierarchy. This is not the case.
Instead, only the node_modules/.bin directory next to the current package.json file (i.e. the closest package.json going up the path hierarchy) is considered. (Or some more, if the CWD is inside nested node_modules directories, but that's not very relevant for DevCmd).
This is most clearly recognizable (though still not obvious IMO) in the npm-path package, which has extracted npm's lookup/path augmentation algorithm. See getPath in timoxley/npm-path#src/index.js
We should keep this behavior in mind, because it differs significantly to how plain node modules (import/require) are resolved.
And we should consider well whether we want to stick to this behavior or make custom additions to $PATH.
And either way, document the behavior.
To illustrate, consider the following setup (which is a situation we want to support according to our design goals):
Let's talk about running a dev command, i.e. starting a script in dev_cmds/ with the CWD also set to dev_cmds/.
The npm PATH augmentation (as implemented by npm and npm-path, and implemented sufficiently similarly by yarn, when running scripts) produces an augmented NPM_PATH as follows, where $PATH is the non-augmented (i.e. OS-provided) PATH:
If the inner package.json (A) exists, we get roughly export NPM_PATH = $(realpath dev_cmds/node_modules/.bin):$PATH. The outer bin dir (node_modules/.bin/) is not on the augmented PATH.
If the inner package.json (A) does not exist, we get roughly export NPM_PATH = $(realpath node_modules/.bin):$PATH. The inner bin dir (dev_cmd/node_modules/.bin/) is not on the augmented PATH.
This has the following effects:
If (A) does not exist and all dependencies (devcmd, ts-node, etc.) are included in (B), everything works fine.
If (A) does exist, and all all dependencies (devcmd, ts-node, etc.) are included in (A), anything available in (A) works fine (e.g. running other dev commands). Bin-dependencies included only in (B) cannot be directly executed.
If (A) does exist and includes the devcmd dependency, but the ts-node dependency is included only in (B) (e.g. because the project itself uses it), dev commands cannot be run. (At the moment, it fails silently, see Devcmd fails silently when ts-node is not available #17, but even if an error is emitted, this failure seems unexpected to me.)
The text was updated successfully, but these errors were encountered:
This issue relates to the augmentation of the PATH environment variable to allow easy use of bin scripts provided by npm packages, i.e. for use inside dev commands.
It does not affect the resolution of the right dev_cmds directory.
I had previously assumed that
npm
,npx
, andyarn
would search for bin scripts in the.bin
directories of allnode_modules
directories up the path hierarchy. This is not the case.Instead, only the
node_modules/.bin
directory next to the currentpackage.json
file (i.e. the closestpackage.json
going up the path hierarchy) is considered. (Or some more, if the CWD is inside nestednode_modules
directories, but that's not very relevant for DevCmd).This is most clearly recognizable (though still not obvious IMO) in the
npm-path
package, which has extracted npm's lookup/path augmentation algorithm. SeegetPath
in timoxley/npm-path#src/index.jsWe should keep this behavior in mind, because it differs significantly to how plain node modules (
import
/require
) are resolved.And we should consider well whether we want to stick to this behavior or make custom additions to
$PATH
.And either way, document the behavior.
To illustrate, consider the following setup (which is a situation we want to support according to our design goals):
Let's talk about running a dev command, i.e. starting a script in dev_cmds/ with the CWD also set to dev_cmds/.
The npm PATH augmentation (as implemented by
npm
andnpm-path
, and implemented sufficiently similarly byyarn
, when running scripts) produces an augmentedNPM_PATH
as follows, where$PATH
is the non-augmented (i.e. OS-provided) PATH:If the inner
package.json
(A) exists, we get roughlyexport NPM_PATH = $(realpath dev_cmds/node_modules/.bin):$PATH
. The outer bin dir (node_modules/.bin/) is not on the augmented PATH.If the inner
package.json
(A) does not exist, we get roughlyexport NPM_PATH = $(realpath node_modules/.bin):$PATH
. The inner bin dir (dev_cmd/node_modules/.bin/) is not on the augmented PATH.This has the following effects:
The text was updated successfully, but these errors were encountered: