Make NPM package dynamically install its own dependencies - node.js

I'm writing an NPM package that's going to support several databases. I'm working on a CLI at the moment that, passed a connection URI string, it will install the appropriate dialect for that database. e.g. if passed a URI that contains postgresql://... it will install the pg and pg-hstore packages with a command like npm install pg pg-hstore (or yarn depending on lock file).
I'm running into the issue where this will then install the package in the root projects package.json so now my package does not have access to the pg package.
How do I either:
A) get access to top-level packages that are NOT in my packages package.json
B) Have my package install the correct package for its own package.json

Related

Loading module installed directly from github repo with npm

I installed a public github repo using the syntax provided in the repository's readme:
npm install https://github.com/user_name/proj_name.git
However, I'm not sure how to load this module into my js code. I've tried:
const my_lib = 'proj_name';
Unfortunately, this is not working for me. How can I load a module that was installed directly from a github repository?
Currently you're just defining a constant as a string with value 'proj_name'.
To load a module from node_modules, you have to do the following:
npm install <package_name> --save, where --save write the package and version in your dependencies of package.json. You can also use --savedev to write the package in your devDependencies (both optional).
Use const packageName = require('packageName'); in your e.g. app.js to use the package in your code.
See here for more details about npm install in general, specifying-dependencies and here for ecma script require and import.

Does npm install exclude dev dependencies?

When I am in a Node.js project and run npm install, npm installs both, dependencies and dev dependencies. If I do not want to install the dev dependencies, I can run npm install --production.
Question 1: If I do not provide --production: Are the dependencies' dev dependencies installed, too, or only their actual dependencies?
Now, what if I am in a Node.js project and install a new dependency, something such as:
npm install foo
This installs foo's dependencies, of course.
Question 2: But what about its dev dependencies? Are they installed, too, or are they skipped?
Answers to your questions:
Yes dev dependencies will be installed in npm install only way it wont install dev dependencies is when NODE_ENV is set to production
No dev dependencies of your external modules won't be installed see here
When you run npm install by default both dependencies and devDependency dependencies are also installed. Because if once is going to develop a package, we would download it e.g. from git and go to root folder and run.
npm install
so you would expect to have devDependencies to.
npm install "$package"
doesn't install the devDependencies by default. But if you really want to install development packages in that case, you can set the dev config option to true:
npm install "$package" --dev
Node applications use multiple methods to maintain dependency versioning up to date but there are multiple dependency types that need to be considered. Dependencies are found in a node application's root directory within the package.json file. I will go through the different dependency types and list some defining features or characteristics:
Dependencies:
These are specified in a simple object that maps a package name to a version range. The version range is a string which has one or more space-separated descriptors. Dependencies can also be identified with a tarball or git URL.
npm install from a directory that contains package.json
npm install $package on any other directory
dependencies are required to run
Installed transitively: if A requires B, and B requires C. then C gets installed, otherwise B could not work, and neither would A.
devDependencies:
If someone is planning on downloading and using module in their program, then they probably don't want or need to download and build the external test or documentation framework that you use. In this case it's best to map these additional items in a devDependencies object, which is not installed when the user is installing the package unless specifically passing in --dev. These are typically installed when doing a traditional npm install from the root of the package.
npm install on a directory that contains package.json, unless the developer passes the --production flag.
not installed on npm install "$package" on any other directory, unless you give it the --dev option
Are not installed transitively
Other Dependency types:
These are less commonly used but may serve a purpose.
peerDependencies
optionalDependencies

difference between jspm install and npm install

I'm relatively new to jspm. I wanted to know what the difference is when is run jspm install package and npm install package. I know that there is a lookup with jspm/registry. But what's the difference when it comes to setting up config.js. Are there any additional changes to be made if the package is installed using npm?
npm and jspm are both package managers.
npm is used for the node ecosystem, and traditionally served back-end dependencies.
To enforce the separation between front-end and back-end, developers used tools specifically for front-end. There came bower and the likes... as well as jspm.
I wanted to know what the difference is when is run jspm install package and npm install package.
Here are some differences between npm and jspm:
- jspm stores its dependencies in jspm_packages whereas npm stores them in node_modules
- jspm uses a flat dependency tree
- jspm allows you to configure arbitrary registries to get your dependencies from (github and npm are configured by default)
- even if jspm tracks module declaration and mapping, as well as configuration, into its own file (config.json), it actually defines the project dependencies inside the package.json (within the property jspm)
- you could use jspm packages either for a jspm project, or for a node / web project
- jspm is in fact just a package manager which wrap around the configuration system of SystemJs
So when you install a package from jspm it uses SystemJs configuration and set up the mapping between the dependencies, allowing you to export the project as any module types (AMD, CJS, esm, umd ...).
Are there any additional changes to be made if the package is installed using npm?
jspm install package makes a lookup in the jspm registry.
If no package is found, it means that you have to specify from which registry this package is coming from.
For an npm package it is: jspm install npm:package.
You can of course specify a specific version by appending #version at the end of the package name.
jspm also allows you to declare a shorthand to map this library within your code.
for more info see documentation: http://jspm.io/docs/installing-packages.html
Both are package managers and essentially do the same function however here are some differences:
Npm will track packages in the package.json file whilst jspm will use the config.json file.
Npm will store it's packages in a node_modules folder whilst jspm will use a jspm_components folder.
Jspm is more commonly used to bring in client-side\front-end libraries and npm for server-side ones.
Restoring packages will normally follow like this:
Run npm install (should install jspm amongst other libraries)
Run jspm install

Clarification of the --save option for npm install

First experiences with node.js/npm. From the npm-install docs I read:
npm install takes 3 exclusive, optional flags which save or update the package version in your main package.json:
--save: Package will appear in your dependencies.
--save-dev: Package will appear in your devDependencies.
--save-optional: Package will appear in your optionalDependencies.
But I can't understand how it works in practice. If, for example, I run the command:
npm install bower --save-dev
I'd expect to find a package.json file in the current directory with devDependencies set to the installed version of bower, instead I find nothing.
Am I doing/expecting something wrong?
Using node v0.10.21, npm 1.3.12 on Ubuntu 12.04 x64
npm won't create package.json for you, but it will create the necessary dependencies for you as long as package.json exists and is legal JSON.
Create it like so
echo {} > package.json
Then, doing npm i --save whatever will add whatever#~x.x.x as a dependency as expected. The file needs to be there, and be JSON, that's it.
npm install only fetches the packages from the registry and puts them in your ./node_modules. It updates your package.json to register this new dependency if you tell it to.
Your package.json has three dependency blocks :
dependencies - these are needed for your app to run.
devDependencies - these are needed for the developer environments for your app (this is how your teammates can get the packages that you recently added to the project. The dependencies listed here are not required on production hosts.)
optionalDependencies - These packages are optional and it is OK if npm cant reolve the package to install. i.e a build failure does not cause npm install to fail (Note however, that your app should handle cases where the package cannot be found.)
Here is the behavior with the different usages of the npm install command:
$ npm install async #Only installs, no change made to package.json
$ npm install async --save #Installs, adds async#version to dependencies block
$ npm install async --save-dev # Installs, adds async#version to the devDependencies block
$ npm install async --save-optional # Installs, adds async#version to the optionalDependencies block

What does -save-dev mean in npm install grunt --save-dev

I've just started using Grunt.js. It is pretty hard to set up and I am at the point of creating a package.json file.
Following this tutorial, it says there are 3 ways to create a package.json file.
The first is to do npm install grunt --save-dev
But what does --save-dev means? I tried looking but it ends in vain.
--save-dev: Package will appear in your devDependencies.
According to the npm install docs.
If someone is planning on downloading and using your module in their program, then they probably don't want or need to download and build the external test or documentation framework that you use.
In other words, when you run npm install, your project's devDependencies will be installed, but the devDependencies for any packages that your app depends on will not be installed; further, other apps having your app as a dependency need not install your devDependencies. Such modules should only be needed when developing the app (eg grunt, mocha etc).
According to the package.json docs
Edit: Attempt at visualising what npm install does:
yourproject
dependency installed
dependency installed
dependency installed
devDependency NOT installed
devDependency NOT installed
devDependency installed
dependency installed
devDependency NOT installed
There are (at least) two types of package dependencies you can indicate in your package.json files:
Those packages that are required in order to use your module are listed under the "dependencies" property. Using npm you can add those dependencies to your package.json file this way:
npm install --save packageName
Those packages required in order to help develop your module are listed under the "devDependencies" property. These packages are not necessary for others to use the module, but if they want to help develop the module, these packages will be needed. Using npm you can add those devDependencies to your package.json file this way:
npm install --save-dev packageName
To add on to Andreas' answer, you can install only the dependencies by using:
npm install --production
When you use the parameter "--save" your dependency will go inside the #1 below in package.json. When you use the parameter "--save-dev" your dependency will go inside the #2 below in package.json.
#1. "dependencies": these packages are required by your application in production.
#2. "devDependencies": these packages are only needed for development and testing
Documentation from npm for npm install <package-name> --save and npm install <package-name> --save-dev can be found here:
https://docs.npmjs.com/getting-started/using-a-package.json#the-save-and-save-dev-install-flags
A package.json file declares metadata about the module you are developing. Both aforementioned commands modify this package.json file. --save will declare the installed package (in this case, grunt) as a dependency for your module; --save-dev will declare it as a dependency for development of your module.
Ask yourself: will the installed package be required for use of my module, or will it only be required for developing it?
For me the first answer appears a bit confusing, so to make it short and clean:
npm install <package_name> saves any specified packages into dependencies by default. Additionally, you can control where and how they get saved with some additional flags:
npm install <package_name> --no-save Prevents saving to dependencies.
npm install <package_name> ---save-dev updates the devDependencies in your package. These are only used for local testing and development.
You can read more at in the dcu
–save
The package installed is core dependency.
–save-dev
The package installed is not a core rather development dependency.
Use only when developing
--save-dev means omit in production environments, use only in development environments (smaller, and probably faster).

Resources