How to have environment-specific npm load paths? - node.js

I have some node.js libraries that I package as modules and install by npm install --save. This is a pain to debug, because I have to publish a module, then update to use the newer version.
I see on this SO question: how to specify local modules as npm package dependencies that I can specify my dependencies as paths, which is much better.
Is there a way I could create a debug environment that uses paths for mudule-loading, and then a release environment that will use the modules from npm?
In this case the 'release' is created by the command pkg -t win index.js. i.e.
I'd like to develop with relative paths to modules
I'd like to 'switch' to using modules from npm without changing strings anywhere.
Then. If the above is possible, I would like to NOT import the module file to node_modules, but run it in place (I'm trying to take advantage of VS Code debugging)

Related

Using local NPM dependencies in the PATH - is there a tool that does this?

Is there an NPM package/tool that can (automatically) add local NPM packages to the $PATH?
This would represent a local development env that was independent of other projects.
NVM allows us to switch Node.js versions, but that doesn't seem to be enough to create an independent development space for each project. By By putting the locally installed command line tools on the $PATH, and giving precedence to local NPM dependencies, this would allow for us to change their versions without affecting any other project.
NPX does this, which is bundled with NPM:
https://medium.com/#maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b
However, NPX looks like it does far too much.
I just wanted a simple tool that only adds the local executables to the path, if you are within an NPM project, so I wrote GMX:
https://github.com/ORESoftware/gmx

How to use global Node packages with VS Code

If Node.js packages are globally installed, they can be used by Node.js applications. But Visual Studio Code will not accept these packages and indicate an error, as long as these packages are not installed locally in the project directory (inside the subdirectory node_modules).
For example:
import * as net from 'net';
... 'net' is marked with a red underline as long as you do not install npm install --save #types/node. If you install that package globally via npm -g install #types/node, the package would be available, but code (V 1.17.1) will not recognize it.
So my question, is there a way to configure code to recognize global installed Node.js packages?
IntelliSense for global modules is not supported as of VS Code 1.18. Please file an new issue against TypeScript if you really need this feature
However you really should not need to install #types packages when working with JavaScript in VS Code. Automatic types acquisition should kick in and download these for you. There are also explicitly force these types to be downloaded by adding the following to your jsconfig.json
"typeAcquisition": {
"include": [
"node"
]
}
For TypeScript projects, you should install #types locally as dev dependencies.
This is rather a workaround/partial answer (and I cannot comment yet):
As long as all your scripts that you don't want to create a full package.json for (e.g., simple standalone scripts) have a common root directory in the filesystem, vscode seems to recognize a "global" package.json and node_modules directory at that root.
More concretely, you could run npm i -D #types/node in your home directory, and vscode finds the types for all scripts somewhere below the home directory (i.e., $HOME/**/*.ts).
(Only tested on Linux with a single file, and vscode 1.64.1.)

What is the difference between installing a package locally and globally using npm?

What is the difference between installing a package locally and globally using npm?
From my understanding:
Locally install: npm install <package>
This package/module will find on your local node_modules folder and
can only be usable for this project.
This package/module can be accessible in using require("package")
from code.
This package/module can't be accessible in command line interface.
Globally install: npm install <package> -g
This package/module will find on where node is installed in your machine like /usr/local and can be usable everywhere.
This package/module can't be accessible in using require("package")
from code.
This package/module can be accessible in command line interface.
Please let me know. If I could misunderstand anything here. Thanks!
You are correct except for 1 point.
The local packages exposing CLI utilities can be accessed from the command line. Newer versions of NPM create this .bin/ directory inside the local node_modules/.
Whenever you try to use a tool (let's take babel for example), if you use it from the command line and you have it installed in your project, npm will properly identify that package and run it's CLI for you.
Here's a useful article on the topic.
http://www.2ality.com/2016/01/locally-installed-npm-executables.html
Global modules are mostly tools like gulp, yoman or any other module you use in your daily work.
Local modules are the dependencies of your project. You should never depend on a global module in your project. Even dependencies as gulp should be a local dependency in your dev-dependency section.

Access globally installed package via require in node

I have a gulp based build system. Currently I have some tasks, e.g. a task that is accessing npm (require('npm')) programmatically. In order to achieve it I need to specify npm in my package.json dependencies, so that require can find it inside node_modules. However npm is obviously available along with node & I also have npm installed globally (latest 3.x version of npm).
Is there a way to require a global instance of npm? I do the same stuff e.g. with other npm packages (I mean I have global package installed but I duplicate it in package.json to make it available via require).
Yes you can do it by adding NODE_PATH to your environment variable eg:
export NODE_PATH=/usr/local/lib/node_modules/
After doing this you node should be able to find globally installed packages as well.
NOTE:your node module path may defer.
to make it permanent you can add the commmand to your ~/.bashrc file

Locally installed versus globally installed NPM modules

In my package.json file, I have bower listed as a dependency. After I run npm install, bower gets installed locally. When I try to run bower after installing it locally I get an error
"bower" is not recognized as an internal or external command
It seems the only way to resolve this is to install bower globally. Why should I have to do this? If my project contains a local copy of bower, why won't node use it?
Installing locally makes bower available to the current project (where it stores all of the node modules in node_modules). This is usually only good for using a module like so var module = require('module'); It will not be available as a command that the shell can resolve until you install it globally npm install -g module where npm will install it in a place where your path variable will resolve this command.
Edit: This documentation explains it pretty thorougly.
You can execute your local instance by typing the line below in cmd:
node_modules/bower/bin/bower <bower args>
We use both PHP and JavaScript, so we have composer and npm.
Each of the projects we work on have different packages both for runtime of the package as well as build/dev tools.
As there are version constraints in each project, installing version x of a package globally (that would be run from the command line), would cause us issues, we install all the tooling in each package. Much easier to define in the appropriate composer.json / package.json files.
But running the CLI tools is a pain if you have to constantly add an additional path to the command.
To that end, we have recommend to the team that the following paths are added to your $PATH in the appropriate .bashrc (or equivalent):
./vendor/bin:./node_modules/.bin
(EDIT: For Windows, the paths would be .\vendor\bin;.\node_modules\.bin;)
So, whilst in project X, we have access to the CLI tools for that project. Switch to project Y, and we get that projects tools.
Sure, you are going to get duplications, but each project is maintained by different teams (and some people are in multiple teams), so again, having 1 version in the global setup is an issue there.
Usually you install NPM modules globally if you want them included in your path to be ran from the command line. Since it is installed locally you will have to run it from the node_modules folder.

Resources