NodeJS package management - node.js

I wanted to run this simple line of code (using Node.js 8.0.0) :
time node -e "console.log(require('bcrypt').hashSync(process.argv[1], 8));" your-password-here
to compare bcrypt to bcryptjs on my RaspberryPi running Linux Alpine.
At first it gave me :
module.js:487
throw err;
^
Error: Cannot find module 'bcrypt'
at Function.Module._resolveFilename (module.js:485:15)
at (...)
at evalScript (bootstrap_node.js:432:27)
So I tried to install bcrypt with this command :
npm install -g --production bcrypt
which worked (after a fallback to compile from sources since the linux depencies were not found for my armv7 processor).
BUT when trying the test command again, I had exactly the same error (cannot find module 'bcrypt').
It's only after doing what I think is a "project local" install without the "-g" option (even if I had no project) it finally worked and bcrypt was found when running my test command.
npm install bcrypt
Could some someone familiar with NodeJS explain me this strange mechanism ?

Globally installed packages are not automatically available everywhere. Installing one like you did is a great idea on a platform where clearly you want to compile as little as possible given how long it takes; however, you still need to link globally-installed packages in your local project:
# install globally
npm install -g --production bcrypt
# link locally (you must run this in your project's directory)
npm link bcrypt
This will create symlink(s) that will simply make the globally-installed module available in the node_modules directory of your local project - a much faster operation than recompiling the module once for every project that requires it.
Make sure, however, to remember to update bcrypt running npm install -g --production bcrypt again when a new version you need is released. Running npm update in your project won't suffice.
npm link documentation, well worth a read. Note that the behavior of this command is completely different if run without a package name as its argument.

Related

Argon2 is difficult to get working with Angular 8 on MacOS: actually not working at all

I am working with:
MacOS Mojave
Angular 8
node v12.12.0
npm v6.13.4
and trying to make Argon2 to work in my Angular 8 app.
In order to use Argon2 it is required to install gcc and node-gyp globally.
I did install them as indicated on the npm pages of Argon2. GCC v9 was installed. But, I had repeatedly problems executing:
CXX=g++-9 npm install
I kept getting errors about stdlib++ . I tried using Apple's CLang++ and got a successful build with:
CXX=clang++ npm install
I imported argon2 in my angular project in order to do password hashing and verification. Hashing seems to be working well (no errors) but as soon as I import argon2.verify() and use it in my code (by making a verify-call) I will get an error when trying to execute npm run start. Just trying to start the httpserver secured (ssl/tls) with corresponding private key and certificate.
The error I get is some mysterious error:
ERROR in ./node_modules/node-gyp-build/index.js
Module not found: Error: Can't resolve 'fs' in '/Users/[username-deleted]/WebstormProjects/my-app/node_modules/node-gyp-build'
I have seen comments and complaints on probably similar problems on internet and people referring to some adjustment in a Webpack config file but at this point I dont have this config file in my project. I tried other versions of node-gyp-build but not resolved.
Apparently argon2.hash() (its usage) is working without causing problems, but as soon as I introduce argon2.verify() in my code and run my app with npm run start I get the above error.
Any one with similar problem and how this problem was resolved?
I had the same issue and fixed it by installing the Xcode Command Line Tools:
xcode-select --install
npm upgrade
npm install argon2 --save-dev
Hope it helps.
Installing a new version (0.28.0 and up) fixed it for me

Doesn't npm install check for a global version first?

I just setup a test, and tried to npm install express even though express already exists globally on my system. To my surprise, instead of using the global version, it ended up re-installing a version locally!? Isn't it supposed to use the global version... Or am I suppose to use -g every time, even when I only want to use the existing global version. Otherwise, what's the point of installing anything locally!?
The answer is "NO". It isn't supposed to use your global version.
If you want to use your global version, then you doesn't need to execute npm install at all because it is already installed.
If you do it then, obviously, you are saying "I want to install it locally to my project". And more than that: "I want to install its latest version unless it is declared in my package.json with other explicitly specified version".
In fact, the actual question is: Why in the hell would you want to not install a dependency of your project locally? To have more version mismatch issues?
As #anshuman_singh says, best practice is to always do an npm install --save.
You are able to use globally installed packages, of course. It could be handy for fast testing code that you will drop just after a few hours or so.
But, anyway: If you doesn't have really hard disk or network bandwidth issues, installing all dependencies locally will avoid you too much trouble in the future.
On the other hand, uploading that modules to your code repository is also a bad idea (maybe that is what you were trying to avoid) because, with different versions of node, most native modules won't work if not rebuild. But most VCS support ignoring files and or directories that must not be uploaded.
For example, in git (.gitignore file):
**/node_modules
In summary:
npm init (if you didn't already it).
npm install --save for all your project dependencies.
npm install --save-dev for dependencies not needed in production (testing stuff).
Don't upload node_modules to your VCS.
After new checkout: npm install or npm install --production (to not install dev-dependencies).
npm install -g only for tools you will use in console.
This way, you are sure that you will have in production (or other dev environments) the exact same version of each package.
And, finally, if you ever want to upgrade some package to its latest version, simply run:
npm install --save <pagkage_name>#latest.
If you’re installing something that you want to use in your program, using require('whatever'), then install it locally, at the root of your project.
If you’re installing something that you want to use in your shell, on the command line or something, install it globally, so that its binaries end up in your PATH environment variable.
The first option is the best in my opinion. Simple, clear, explicit. The second is really handy if you are going to re-use the same library in a bunch of different projects
Install locally-
npm install moduleName
install locally and save in package.json-
npm install moduleName --save
install globally-
npm install moduleName -g

What does the -g option for npm install and npm list do?

The Node.js npm (Node Package Manager) has a -g command line argument, which I often see referenced. For example, the documentation for the Microsoft Azure x-plat (cross-platform) CLI tool says to install it by using npm install -g azure-cli.
Question: What does the -g option do?
What options do I have to install node modules?
After writing this I quickly found and old but still applicable post by Isaac (yes, the npm #isaacs). But I still think the below post is informational.
You can install npm modules globally or locally - you already know that, but why?
Globally: npm install -g some-module-a: This module is intended to be used as an executable (i.e. CLI, file watcher, code minifier, logger, etc.).
Locally: npm install some-module-b: To be imported and used in your app via import, var someModule = require('some-module)
global modules are one of the best ideas of npm. We can easily create executables using node/javascript. If your node app is meant to be run as an executable, then you will want others to install it globally. If it's a utility, helper, application, etc. then you usually don't want it installed globally. So, unless the module explicitly states that you should install it with -g, then don't.
One more time: if you are wanting to use some module called some-module in your node app - var someModule = require('some-module'), then npm install some-module from the root of your node app to pull it into your local node_modules directory. If you've installed some-module globally and not locally, it will usually not load and will show you an error about not finding the module (even though it can be made to load the global module - hint: just don't!)
So what exactly happens when you install globally?
npm install -g [some module] installs the specified node module in a directory higher up in your file system (i.e. usually /usr/local/lib/node_modules in unix systems). The biggest use case for global modules is for CLIs written using node (think npm, bower, gulp, grunt, et. al.).
Let's look at what happens when you install bower globally:
*follow these steps in your command line/terminal
step: npm install -g bower
explanation: the module - all of it's files and dependencies - are saved in your global directory (e.g. /usr/local/lib/node_modules/bower).
Something else happened here. Somehow you can now run bower in your command line. Awesome!
step: bower -v --> results in the installed bower version (i.e. 1.6.5)
explanation: It's now a fully executable node app using bower as the keyword. Inside bower's package.json file you'll find a bin property:
"bin": {
"bower": "bin/bower"
}
So how did that all work?
npm will create a symlink from where most executables live, /usr/local/bin/bower over to /usr/local/lib/node_modules/bower/bin/bower, where the module lives. That symlink makes it so when the executable runs, it can reference other files in the original module, including it's local node_modules. Pretty cool, huh?
*Note on executables: If you create a file called awesomeness in /usr/local/bin/ and chmod u+x (user + executable) it. Then write some scripting in it (in this case javascript using #!/usr/bin/env node at the top). Then you can run it anywhere in your command line/terminal just by typing awesomeness.
Hope that helped. I know doing a deeper dive into it helped me early on.
Node.js packages can be installed one of two ways:
Globally
Locally
The -g option instructs npm to install the package globally. You would install a Node.js package globally, if you want to be able to call the command directly from the terminal.
From the documentation:
There are two ways to install npm packages: locally or globally. You choose which kind of installation to use based on how you want to use the package.
If you want to use it as a command line tool, something like the grunt CLI, then you can want to install it globally. On the other hand, if you want to depend on the package from your own module using something like Node's require, then you want to install locally.
To download packages globally, you simply use the command npm install -g , e.g.:

Module async not found

I'm studying node.js
and I am making the exercises from a book
https://github.com/marcwan/LearningNodeJS/blob/master/Chapter05/05_series.js
I have a problem with an example in which you invoke the module async.js
when I go to run the example I get the error
"can not find module 'async'"
in the folder where you installed node
I checked that there is a module
I also downloaded this package
https://github.com/caolan/async
and launched the test file that works properly
the first question that you do, even if it seems correctly installed the module, there is a command to verify that a module is installed and that you can recall?
the second question is, why is this wrong example?
thanks
To install a package, use npm install package_name.
When that's done, you can easily require that package and use it in your application.
const package = require('package_name');
To install a package globally (so you don't have to install it in every project you create) add -g flag
npm install package_name -g
You should be using npm, not downloading packages from github manually: npm install async.
npm will install the module into a node_modules subdirectory of the directory that you run it in. That directory must be your examples folder, or an ancestor. See: https://nodejs.org/api/modules.html#modules_loading_from_node_modules_folders

Node.js modules installed through npm not recognized

So I've installed and reinstalled node.js many times and tried various installs of the npm. I am currently on node version 0.6.11. When I try to install a new module with npm I get several errors. I am extremely new to programming with node but I have tried researching this problem but haven't found a proper answer. When I install a module with npm and then try to use it in command prompt nothing happens. All I get is for example
'haraka' is not recognized as an internal or external command,
operable program or batch file.
This happens to every module I install. What am I missing here. Please help. I am getting really frustrated with node
By default, npm will install packages locally, in ./node_modules. So if you are in /home/foo:
user#host:/home/foo$ npm install Haraka
Haraka will be installed in /home/foo/node_modules/Haraka. If you want to install a module globally (by default in /usr/local/lib/node_modules), supply the -g switch:
user#host:/home/foo$ sudo npm install -g Haraka
Haraka will be installed in /usr/local/lib/node_modules/Haraka, and the command haraka will be symlinked to /usr/local/bin/haraka.
It's recommended that any dependencies be installed locally. This way, you never have to bother with different packages requiring different versions of their dependencies, aka "dependency hell". I have all my projects in ~/development/projects, and each node project has it's own node_modules folder.

Resources