I am trying to follow along with this Beginner's Guide to NPM and having trouble in the "Changing the Location of Global Packages" section. The goal in this section is to alter the location to which global Node packages are installed from root to $HOME/.node_modules_global.
Everything seems to work until I need to add .node_modules_global/bin to my $PATH environment variable, so that I can run global packages from the command line.
After including the following command to my .bash_profile file in $HOME...
export PATH="$HOME/.node_modules_global/bin:$PATH"
... I don't see the updated local path when running which npm.
Pictures of my previous output and my .bash_profile where I export the PATH: img1, img2
To clarify, I'm expecting the output of which npm to output /Users/mlongoria/.node_modules_global/bin/npm instead of /usr/local/bin/npm since I included the export PATH statement in my .bash_profile located in my /Users/mlongoria/ directory. Anybody know what I'm doing wrong here? I'm running OSX Catalina if it matters.
can you make sure npm is in your global npm/bin?
you can try ls $HOME/.npm_global and verify?
if you want to move npm there, you can install npm again by npm install npm -g, this will use the global npm folder and then after that, it will be picked up (try closing session and open new tab)
Related
I had a system crash. While trying to fix it, I deleted a few files and (I may be wrong here), I deleted ~/.profile file among them.
After system restore, my globally installed npm packages are not working.
I uninstalled npm and node and installed the latest version of nodejs 16.x, and then reinstalled globally required npm packages, however, they are still not working. Somewhere the environment variables (in .profile file?) have gone missing.
How can I get the globally installed packages to run?
You are missing the path to the globally installed npm modules in your PATH. There are multiple fixes described on this page, one of which:
Open or create a ~/.profile file and add this line:
export PATH=~/.npm-global/bin:$PATH
Back on the command line, update your system variables:
source ~/.profile
I have a package (package-a) that depends on another package (package-b) which is not published to npm but is on my file system. When I run npm install from package-a, package-b's dependencies are not installed. I have to navigate to package-b's directory and run npm install manually. Is there a way to install both packages' dependencies with a single npm command?
Here's my directory structure:
/
...
shared/
...
javascript/
...
package-b/
package.json
package-a/
package.json
Per the docs, I placed the following in package-a/package.json. (I'm using npm 5+)
dependencies: {
package-b: "file:../shared/javascript/package-b",
}
When I navigate to /package-a and run npm install, it installs all of package-a's dependencies like normal and also copies the package-b directory to package-a/node_modules. This is presumably what lets me type require('package-b') instead of require('../shared/javascript/package-b') .
However, as I stated before, package-bs dependencies are not installed, so if I try to use package-a, I get an error when package-b is required because it is trying to use dependencies that do not exist locally.
Once again, to solve this, I can navigate to package-b and run npm-install, but I'm hoping there's a better solution as I may have many such sub packages and I'd like to avoid having to write a shell script to go install all my dependencies if I can do this with an npm command. (perhaps I just did something wrong and npm install should be working?)
Follow up question: when I run npm install from package-b's directory, the packages are installed there, but not in the version of package-b that got copied to /package-a/node_modules during the first npm install, yet everything still works. So now it seems like when I require('package-b') it is actually resolving to /shared/javascript/package-b and NOT /package-a/node_modules/package-b. So what's the point of copying the file in the first place?
Update
It turns out this is a bug in npm 5. It only occurrs when installing from a package-lock.json file. (Github Issue)
The files are (probably) not being copied, they're being symbolically linked (symlink). This essentially creates an alias/shortcut that looks like a real directory, but points to another path.
This is how the older npm link feature worked. The reason is the code stays "live"; Changes in the linked module are reflected whenever you run the module that's referencing them, meaning you don't have to npm update all the time.
I'm quite new to the whole NPM-stuff, however, I would like to create a new package that should be able to run as a console-app (like gulp and grunt).
So basically what I would like to do is making it possible to run
npm install -g mypackage
and then
mypackage
and that would then kick off the console application.
I have been using npm init to init my new package, I have also created the entry point (in my case app.js), and node app.js runs fine.
I have also used npm pack to create a package and npm install {path to my .tgz}.
This is my app.js:
console.log('Hi from NodeJS');
Nothing fancy so far.
The package is called "mypackage"
The problem is that when I type:
mypackage in my console the console application doesn't run.
Any ideas?
Br,
Inx
You're looking for bin.
To install one or more executable files to PATH, you shoul supply a
bin field in your package.json which is a map of command name to
local file name. On install, npm will symlink that file into
prefix/bin for global installs, or ./node_modules/.bin/ for local
installs.
For example, grunt-cli has this:
"bin": {
"grunt": "bin/grunt"
},
Where bin/grunt is a js file (yet without an extension defined).
P.S. If you're planning to ship this as a global package, don't forget to set preferGlobal.
Lets say I develop a global npm module called mytool that registers a env variable through "bin" in package.json with the name mytool.
So after I install it globally by typing
npm install mytool -g
then I can type mytool --someOption in terminal and handle the CLI input in javascript. Now lets assume that mytool works a lot with the current working directory of the CLI, so to just
node index.js --someOption
is a bad idea.
However to test for bugs I don't want to push a new version of "mytool" to npm and then install it globally from npm. Rather I want to be able to test this all locally.
Question: What is the best way to do test global npm modules without publishing to npm?
npm link
Contrary to what it seems, npm link can also be used in your case, too.
Just run it on the root folder of your project. No additional arguments are necessary.
Using it in you package folder will create a symlink in the global folder {prefix}/lib/node_modules/<package> that links to the package where the npm link command was executed.
It will also link any bins in the package to {prefix}/bin/{name}.
Lets say im working on an app, MyApp, and I want to build an NPM module for it, MyModule. Right now I can think of two ways to develop it:
Makes changes -> save -> npm install /path/to/module in MyApp
Same as 1, except run npm install /path/to/module then editing it directly in node_modules then copying the changes over.
What I'd like is an easier workflow. One where I can simply save the file, refresh the page, and my changes are there. Is that possible? For example, I know in Gemfiles I can just link to another directory as the path. Pretty sure I can't do that with npm tho.
You're looking for the npm link command, which is a two steps process:
Run npm link from your MyModule directory: this will create a global package symlinked to the MyModule directory
Run npm link MyModule from your MyApp directory: this will create a MyModule folder in node_modules, symlinked to the global symlink (and thus to the real location of MyModule).
To add on to Paul's answer, you can also do a shortcut for the above by doing the following from within your MyApp directory:
npm link ../MyModule