Open jeff-an opened 1 month ago
I am getting expected behaviour
~/workarea/rep/test $ npx -ddd momentic@1.0.12 init
Need to install the following packages:
momentic@1.0.12
Ok to proceed? (y) y
~/workarea/rep/test $ npx momentic@^1 init
Need to install the following packages:
momentic@1.0.13
Ok to proceed? (y)
Thanks for the responses folks! --no-cache
and prefer-online
both do not seem to help this case:
We know that it works on some people's machines but not others. How can we debug why? At this point we are thinking of just hitting npm's registry programmatically at startup to figure out what the latest version is.
you don't need to do that; do npx foo@latest
and you'll get the latest no matter what's locally available.
We are aware of that, but we don't want to use @latest
because it will automatically install versions that may be backwards incompatible with what the user is currently using.
Besides, it seems like a bug that this behavior is a) non-deterministic across machines and b) different from what is advertised in the official docs:
Package names with a specifier will only be considered a match if they have the exact same name and version as the local dependency.
@jeff-an what's the output of npm -v
and npm config ls -a
I put it in the environment section:
version: 10.9.0
npm config:
auto-install-peers = true
public-hoist-pattern = ["*eslint-plugin*","*prisma*","*bull*"]
npx
will first check in local project/workspaces from where you are running the command to see if matching range version is found, if not then check globally and then pull from registry. So if you are running npx
command in a folder where this package is already installed or part of node_modules then it would use that if it's matching.
What constitutes a local project or workspace? We have not installed this package (momentic
) anywhere - it is only invoked as a CLI. It never appears as an entry in any package.json
in our working tree or above.
Project with package.json and dependencies installed or this cli tool installed globally. unless it's installed locally on project from where you are running the command or globally installed. it should get the correct version based on range or version specified. However at my end it's not reproducible even with node 20.9.0 and npx 10.9.0. It does fetch correct values Please provide verbose logs of these runs if possible.
My output
~/workarea/rep $ node -v
v20.9.0
~/workarea/rep $ npm -v
10.9.0
~/workarea/rep $ npx -v
10.9.0
~/workarea/rep $ npx turbo@2.1.0 -V
Need to install the following packages:
turbo@2.1.0
Ok to proceed? (y)
ERROR unexpected argument '-V' found
tip: to pass '-V' as a value, use '-- -V'
Usage: turbo [OPTIONS] [COMMAND]
For more information, try '--help'.
~/workarea/rep $ npx turbo@^2 -V
Need to install the following packages:
turbo@2.2.3
Ok to proceed? (y)
ERROR unexpected argument '-V' found
tip: to pass '-V' as a value, use '-- -V'
Usage: turbo [OPTIONS] [COMMAND]
For more information, try '--help'.
~/workarea/rep $ npm config ls
; "project" config from /Users/milaninfy/workarea/rep/.npmrc
auto-install-peers = true
public-hoist-pattern = "[\"*eslint-plugin*\",\"*prisma*\",\"*bull*\"]"
~/workarea/rep $
What kind of debug logs can we provide? Unfortunately it does not appear npx
has a --debug
or --verbose
mode that prints more information about how its resolving. A colleague of ours running on windows just encountered the problem again yesterday. Here's the information from his machine:
We confirmed that there is no package.json
in the current directory where he was running the command. Will try to get npm list -g
information as well.
npm list -g
showing nothing installed globally
you can use command this way npx -ddd turbo@^2 -V
to enable silly
logs
Here's the output from my laptop and a repro of the bug
also repros in my tmp
folder, where there is no package.json
:
any other information I can provide here @milaninfy ? only thing that seems to definitively fix the issue for the next invocation is npx clear-npx-cache
friendly bump...
Some possibly related weird behavior. Here npx
asks me if I want to install the same package version twice. And invoking npx momentic@1.0.35-alpha.0 -V
does not work in a folder that contains a package.json
with the name momentic
, but invoking npx momentic@alpha -V
in that same folder does work.
npx momentic@1.0.12 init
npx momentic@^1 init
These are different entries in the npx cache. The npx cache is indexed by the entire package arg.
Within a given npx cache entry, if the spec (everything after the @) is a range it will look to see if a newer version exists. It will not consider other entries in its cache.
In order to get the behavior you want you need to give npx the same package arg each time. If you want latest, just give it the package name with no spec. If you want a version, use that version every time. You can also use a dist-tag.
Thanks for the response! A few questions:
npm-package-arg
, these two things seem to have the same "name". What field from the na
result is used for the cache key?> na("momentic@1.0.12")
Result {
type: 'version',
registry: true,
where: undefined,
raw: 'momentic@1.0.12',
name: 'momentic',
escapedName: 'momentic',
scope: undefined,
rawSpec: '1.0.12',
saveSpec: null,
fetchSpec: '1.0.12',
gitRange: undefined,
gitCommittish: undefined,
gitSubdir: undefined,
hosted: undefined
}
> na("momentic@^1")
Result {
type: 'range',
registry: true,
where: undefined,
raw: 'momentic@^1',
name: 'momentic',
escapedName: 'momentic',
scope: undefined,
rawSpec: '^1',
saveSpec: null,
fetchSpec: '^1',
gitRange: undefined,
gitCommittish: undefined,
gitSubdir: undefined,
hosted: undefined
}
If 1.0.12
and ^1
are different cache "scopes", how can a range ever be useful? Wouldn't it only be applied if the user does not have an existing matching installation?
If the separate scopes is the intended behavior, why does the behavior I assume to be the expected behavior sometimes happen on my machine and others' machine as well (e.g. in @milaninfy 's examples)?
The entire argument as given on the cli is used. If multiple packages are given (i.e. with the -p
flag) they are all combined and used.
No cli commands are going to be able to clear the npx cache. It's isolated from npm's normal cache. There is also no way to inspect the npx cache. It's located at ~/.npm/_npx/
and its existence is probably the reason for perceived inconsistencies.
OK, but that doesn't seem to explain the original issue, where running npx package@^range
did not look for the latest entry against npm
's registry? Your comment would seem to imply that would happen:
Within a given npx cache entry, if the spec (everything after the @) is a range it **will look to see if a newer version exists**. It will not consider other entries in its cache.
It does for me locally. We're back to the point where we can't reproduce this locally
$ npx momentic@1.0.12 init
Need to install the following packages:
momentic@1.0.12
Ok to proceed? (y)
Welcome to the Momentic project setup wizard!
$ npx momentic@^1 init
Need to install the following packages:
momentic@1.0.37
Ok to proceed? (y) n
Yes, we know it works on some people's machines and not on others'. But as you can see from earlier in this thread, I've provided logs and screenshots from multiple sources that say this doesn't work (I can still in fact reproduce on my laptop). So is there some additional information we can provide to narrow down the problem? Or if you want to point us to where this code is, we're happy to look ourselves as well.
when using a range, npm is supposed to use whatever it finds, but ONLY if it's present in local or global. The npx cache inspection is supposed to look only at the resolved version.
This line is likely where the bug is. It's supposed to make npm NOT match by range or tag if we're checking the npx cache, and fall through to an identical version
Is there an existing issue for this?
This issue exists in the latest npm version
Current Behavior
When using the syntax
npx <package>@<semvar> <command>
,npx
is always using a local cached version instead of fetching the latest available version that falls within the semvar from the npm registry and prompting for an upgrade.Running
npm cache clean --force
does not seem to help.The issue only seems to be reproducible on some machines. One user even reported that with momentic@1.0.12 installed locally,
npx momentic^1
was still invoking1.0.11
instead of the newer version.Expected Behavior
I expect
npx
to issue a prompt like the one below:rather than proceeding with the locally cached version of momentic@1.0.12, for example.
Steps To Reproduce
npx momentic@1.0.12 init
and accept the install prompt. Ignore the output of the program (the program in this case doesn't matter and can be substituted with any other).npx momentic@^1 init
. This should be expected to prompt to install1.0.13
or whatever the latest version is. However, it does not and instead prints the same output as step 1.Screenshot of what I mean on the
turbo
repo (the latestturbo
version is2.1.3
at time of writing):Environment
auto-install-peers = true public-hoist-pattern = ["eslint-plugin","prisma","bull"]
which npx /Users//.nvm/versions/node/v20.9.0/bin/npx