Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] npm no longer creating symlinks for local package installations #6033

Closed
2 tasks done
gauvion1 opened this issue Jan 8, 2023 · 17 comments
Closed
2 tasks done
Labels
Release 9.x work is associated with a specific npm 9 release

Comments

@gauvion1
Copy link

gauvion1 commented Jan 8, 2023

Is there an existing issue for this?

  • I have searched the existing issues

This issue exists in the latest npm version

  • I am using the latest npm

Current Behavior

currently when I install a local package, a symlink is not being created

Expected Behavior

I expect a symlink to be created for locally installed packages so I don't have to rebuild just to see changes during dev

Steps To Reproduce

I have installed a local npm package via:

npm i ./my_modules/mypackage

It shows up in my dependencies as:

  "dependencies": {
    "mypackage": "file:my_modules/mypackage"
  }

when I look at the node_modules folder, it shows up in there as well, but it is not symlinked

there is no arrow icon in the explorer indicating it is symlinked

which means I have to rebuild every single time I want to see changes inside the local package

this only just started happening today, I'm not sure why it's not symlinking all of the sudden

how do I resolve this issue so that it symlinks properly? it used to do this automatically and now it isn't. I've even tried re-installing everything on my dev machine and it is still doing this behaviour.

normally when I install a local npm package it will symlink it properly, automatically

now, for whatever reason, it is not symlinking

I've even tried using npm link

cd my_modules/mypackage
npm link
cd ../../
npm link mypackage
npm I ./my_modules/mypackage

still doesn't symlink.

Environment

  • npm: 9.2.0
  • Node.js: 19.4.0
  • OS Name: macOS ventura
  • System Model Name: m1 MacBook Pro
  • npm config:
; "builtin" config from /opt/homebrew/lib/node_modules/npm/npmrc

prefix = "/opt/homebrew" 

; node bin location = /opt/homebrew/Cellar/node/19.4.0/bin/node
; node version = v19.4.0
; npm local prefix = /Users/gauvion
; npm version = 9.2.0
; cwd = /Users/gauvion
; HOME = /Users/gauvion
; Run `npm config ls -l` to show all defaults.
@gauvion1 gauvion1 added Bug thing that needs fixing Needs Triage needs review for next steps Release 9.x work is associated with a specific npm 9 release labels Jan 8, 2023
@ima-antonio
Copy link

When you install a package locally using the npm install command, the package is added to your list of dependencies in the package.json file and is also copied to the node_modules directory. The path to the package is added to the package.json file as a local file path, starting with "file:".

However, the package is not created as a symbolic link in the node_modules directory. Instead, it is copied to the node_modules directory like a normal package. This means that if you make changes to the local package and want to see those changes reflected in the project, you will need to run the npm install command again to update the copied package in the node_modules directory.

To create a symbolic link to a locally installed package, you must use the npm link command in the package directory. This will create a symlink to the package in the Node.js global symlink directory and allow the package to be accessed from other projects.

However, there are a few possible reasons why the npm link command might not be creating a symbolic link to the package. Here are some things to check:

  • Make sure the package has a valid package.json file. The npm link relies on the package.json file for information about the package.

  • Make sure you are running the npm link command in the package directory. The command must be run in the directory of the package you want to install locally.

  • Make sure you have write permissions on the global Node.js symlinks directory. If you do not have write permissions, the symbolic link cannot be created.

Check if the Node.js global symlinks directory is corrupted or if an error occurred while creating the symbolic link. You can try deleting the global symlinks directory and running the npm link command again to see if that resolves the issue.

If you continue to have problems creating a symbolic link with the npm link command, try including the --force argument on the command line to force creation of the symbolic link. This can be useful if the symbolic link already exists and is corrupted.

I hope this helps!

@karikera
Copy link

karikera commented Jan 9, 2023

it seems this issue breaks my project.
if the locale package project has global d.ts files. TypeScript makes errors about multiple definitions.

@whirledsol
Copy link

I can confirm this behavior and it also breaks our projects.
Since this goes against previous behavior and the documentation for this version, I would consider it a bug.

@PhilipTrauner
Copy link

Chiming in with the observation that symlink imports are treated differently from non-symlink imports by TypeScript, which can cause confusing errors.
Not sure what the intended behavior is here, but because this caused unexpected breakage for me I'd really like for the old behavior (as in packages with a file: specified in package.json are symlinked instead of copied) to return.

@lukekarrys lukekarrys removed the Needs Triage needs review for next steps label Jan 13, 2023
@lukekarrys
Copy link
Contributor

This was a change from npm 8 -> npm 9. This behavior is controlled by the --install-links config, and in npm 8 it defaulted to false and in npm 9 it defaults to true. This means that npm will now attempt to install directories by default instead of symlinking them.

Note that workspaces will always be symlinked, so the latest workspaces changes will always be reflected in your package.

How to turn it off

You can run the following to set the previous behavior on a per-project basis:

npm config set install-links=false --location project

@lukekarrys lukekarrys added Awaiting Information further information is requested and removed Bug thing that needs fixing labels Jan 13, 2023
@whirledsol
Copy link

I can confirm that this workaround works. But would prefer it to be documented in some form of migration document.

@lukekarrys
Copy link
Contributor

@whirledsol good call, I'll add more info on this to v9 FAQ tracking issue #5844

@BobFrankston
Copy link

While I can try to remember to use "npm link" instead of "npm install", when I'm reinstalling a package using "npm install" on an existing package.json there is no information about which entries are supposed to be symlinks. There needs to be a way to preserve the nature of each installed module.

What is the reason for this change? When debugging it's very valuable to share the code for the modules in a workspace ... and I'm always debugging

@lukekarrys lukekarrys removed the Awaiting Information further information is requested label Jan 18, 2023
@lukekarrys
Copy link
Contributor

When debugging it's very valuable to share the code for the modules in a workspace ... and I'm always debugging

@BobFrankston Are you using npm workspaces? Those will always remain symlinked to enable the type of debugging you are talking about.

There needs to be a way to preserve the nature of each installed module.

This is a good point and I'm investigating what npm can do about this. link: true is stored in the package-lock.json file, but I think subsequent lockfile altering commands will overwrite that which is leading to confusion.

@BobFrankston
Copy link

I was referring to workspaces in VSC.

I wasn't aware of npm workspaces, so will try to learn more. The symlinks were working well enough (especially with preserve-symlinks in node) so I didn't search further. But using npm link may work well enough for now.

I appreciate the challenge of compatibility with tools that don't preserve side properties. And, I also find the copying functionality useful for some of my use cases.

@BobFrankston
Copy link

BobFrankston commented Jan 24, 2023

First, I do have a use case for linking -- I generate JS (OK, TS) class definitions for SQL database files. I want to have the latest definitions available in each application.

(I deleted my other comment because some of the problems seem to have been a side-effect of system problems)

@BobFrankston
Copy link

BobFrankston commented Feb 11, 2023

It seems the change has been reverted ... it's now back to installing as links. I did find the new behavior useful so it would be nice to have the copying as an option under a flag.

I found that out when trying to track down a problem with links>

I have

y:\dev\homecontrol\utils\dbdefs\package.json

with

    "miscassists": "file:../../../projects/NodeJS/miscassists"

When I do

cd y:\dev\homecontrol\jv\vdevice
npm install ../../utils/dbdefs

I get

npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path y:\dev\homecontrol\jv\projects\NodeJS\miscassists/package.json
npm ERR! errno -4058
npm ERR! enoent ENOENT: no such file or directory, open 'y:\dev\homecontrol\jv\projects\NodeJS\miscassists\package.json'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent

but if I use WSL and then run the command, it works just fine. It seems there is a problem in expanding links in Windows but not in Linux. Fortunately, I presume it is a simple bug, but I don't know where to start looking.

I am going to investigate more to see if there is any other reason for the problem.

@ljharb
Copy link
Collaborator

ljharb commented Feb 11, 2023

@BobFrankston you can set it to whichever behavior you like in npm 8 or 9 with install-links=false (or true) in your .npmrc.

@BobFrankston
Copy link

Thanks -- but that still leaves the issue of resolution bugs in Windows that don't happen in Linux

@BobFrankston
Copy link

Case in point.

[npm 9.4.2]

In Windows

npm instal ..\..\..\email\MailApps\mailit

ENOENT: no such file or directory, open 'Y:\dev\homecontrol\utils\dbtick\node_modules\mlconfig\package.json'

In WSL

npm install ../../../email//MailApps/mailit/

works fine

@lukekarrys
Copy link
Contributor

@BobFrankston interesting, would you be able to open a new issue for that specifically? seems like a different bug that was maybe highlighted with install-links but worth investigating on its own.

@BobFrankston
Copy link

FIled it as #6178. It seems to be related to links.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Release 9.x work is associated with a specific npm 9 release
Projects
None yet
Development

No branches or pull requests

8 participants