cli icon indicating copy to clipboard operation
cli copied to clipboard

[BUG] Dependency alias breaks local `npm install`

Open NfNitLoop opened this issue 8 months ago • 6 comments

Is there an existing issue for this?

  • [x] I have searched the existing issues

This issue exists in the latest npm version

  • [x] I am using the latest npm

Current Behavior

I have two local packages, foo and bar, packed into separate .tgz files. bar depends on foo.

  • I install foo
  • I install bar
  • ✅ Success. npm just uses the already-installed foo.

Now I update bar to depend on foo with a package alias:

  • I install foo
  • I install bar
  • ❌ Error loading bar from npmjs.org. (It is not, and will not be, there)

Expected Behavior

I would expect both of the above scenarios to result in a successful package install.

Steps To Reproduce

Bug reproduction and instructions here: https://github.com/NfNitLoop/bug-npm-alias-breaks-local-install

Environment

  • npm: 11.3.0
  • Node.js: v23.7.0
  • OS Name: Darwin Kernel Version 24.3.0: Thu Jan 2 20:24:22 PST 2025; root:xnu-11215.81.4~3/RELEASE_ARM64_T6041 arm64
  • System Model Name: Macbook pro
  • npm config:
; "builtin" config from /opt/homebrew/lib/node_modules/npm/npmrc

prefix = "/opt/homebrew"

; node bin location = /opt/homebrew/Cellar/node/23.7.0/bin/node
; node version = v23.7.0
; npm local prefix = /Users/codycasterline/code/bug-npm-alias-breaks-local-install
; npm version = 11.3.0
; cwd = /Users/codycasterline/code/bug-npm-alias-breaks-local-install
; HOME = /Users/codycasterline
; Run `npm config ls -l` to show all defaults.

NfNitLoop avatar Apr 10 '25 19:04 NfNitLoop

During my initial bug search, I found a similar issue: #6108

But in this case I'm not using any registry, I'm just trying to install packages I have on-disk.

NfNitLoop avatar Apr 10 '25 19:04 NfNitLoop

Based on your code it looks like you are mixing pnpm and npm both since they are different package managers it works differently.

npm alias format is different https://docs.npmjs.com/cli/v11/using-npm/package-spec#aliases

milaninfy avatar Apr 17 '25 20:04 milaninfy

Sorry for the confusion. I discovered this bug while testing a different bug with pnpm, so re-using that example was the quickest way for me to get to a reproduction.

I think pnpm pack translates pnpm's workspace/alias format into the standard expected by npm(js.com).

There are instructions and pre-built .tgz files in that repo for reproducing with npm only.

Let me go grab the generated package.json and include it here. …

NfNitLoop avatar Apr 17 '25 20:04 NfNitLoop

Ah yeah, I'd already included it in the README over there:

"dependencies": {
    "@my_private_scope_example/myFooAlias": "npm:@my_private_scope_example/[email protected]"
  },

This appears to be valid npm syntax. For example, I can create a new package.json with:

"dependencies": {
    "@myFakeScope/example": "npm:@preact/signals@^2.0.3"
  }

And npm install will place it in node_modules/@myFakeScope/example.


Update: Additionally, I think the docs for the npm aliasing format on that page are incorrect.

If I understand the intent correctly, the format is name[@<version>], and the aliased package name goes in the version as npm:<aliasedPackage>[@<itsVersion>]

However, the doc example semver:@npm:[email protected] doesn't work in npm 11.3.0:

> npm install semver:@npm:[email protected]
npm error code EUNSUPPORTEDPROTOCOL
npm error Unsupported URL Type "semver:": semver:@npm:[email protected]
npm error A complete log of this run can be found in: /Users/codycasterline/.npm/_logs/2025-04-17T20_49_42_108Z-debug-0.log

There's an extra : before the [@<version>]. Removing it allows npm to work:

> npm install semver@npm:[email protected]

added 1 package, and audited 5 packages in 1s

3 packages are looking for funding
  run `npm fund` for details

1 high severity vulnerability

To address all issues, run:
  npm audit fix --force

Run `npm audit` for details.

NfNitLoop avatar Apr 17 '25 20:04 NfNitLoop

when using alias, as far as i know it will look for that package in configured registry. as long as your package is there in registry it should pick it up. I feel that you are using the package from your workspace as a local linked dependency through alias then packing it and installing again so while installing it tries to find that package in registry.

milaninfy avatar Apr 22 '25 16:04 milaninfy

Sorry, just saw your last response:

when using alias, as far as i know it will look for that package in configured registry.

IMO, that's the core of this bug.

Without using aliases: it would just use the dependency that had been previously installed into node_modules. ✅

With using aliases: It always checks the repository first, even though the alias target is already installed into node_modules. ❌

I'd just like the same behavior for both – If I install a package, and its dependency is already present in node_modules, it shouldn't go try to look it up in a repository.

as long as your package is there in registry it should pick it up.

I don't want this package to be available in a registry, it is proprietary software that I am building and deploying locally.

I feel that you are using the package from your workspace as a local linked dependency through alias then packing it and installing again so while installing it tries to find that package in registry.

Correct. And it works if I don't use aliases, but fails if I use aliases. I would just like it to work in both cases. 😊

NfNitLoop avatar May 15 '25 21:05 NfNitLoop