How to include other NPM modules when publishing to NPM? - node.js

I am trying to publish my first module to NPM, it renders markdown with EJS templating, it uses two other npm modules marked and ejs, I have these as dependencies in my package.json file. I have a .gitignore file that contains my node_modules directory, and also a .npmignore file that is empty.
I have successfully published to npm.
However when I try to install my module by putting it into the package.json of a test app and doing npm install -d it installs, but it does not install its dependencies, if I go into the test app root node_modules directory and then into my newly published module's installed directory, It has not installed any of its dependencies, it has not have a nested node_modules directory of its own.
There should be a way to get my module's dependencies to install with it correct, when I include express as a dependency, it installs its own node_modules folder with connect and other modules installed, I want to do the same with two other npm modules.
I know it would work if it would install its nested node_modules dependencies, when I do this it works.
$ npm install -d
$ cd node_modules/my_module
$ npm install -d
$ cd ../..
$ node app
EDIT: Here is a link to the GitHub repo for my module, and here is the package.json.
EDIT: Note, this has only happens when I had my dependencies marked and ejs already installed in my test app. When I then installed my module, it did not install marked and ejs in its own node_modules directory. However, if I remove all modules from the test app and install only my module, it will install them. Is there anyway to get it to work regardless of whether my dependencies have been installed beforehand.

It should all "just work" as is.
npm does not install any new modules, because it sees there are already appropriate modules in a node_modules directory at a higher level. Because node's require will look up into the tree, trying node_modules subdir for each directory, your module's require statements will work, without having a node_modules directory of its own.
If you'd install the module in any place which does not have the right dependencies already installed, they would be installed under the module's own node_modules directory. Alberto confirmes this.
You may want to specify a more specific version of the dependencies in package.json though. This will ensure your module gets to use the version of the dependencies you have tested it with.

Related

Is it possible to avoid local node_modules in js projects?

I am exploring nodejs and js frameworks. I noticed that when I create a project, for example with vue
vue init webpack my-project
I get a HUGE directory named node_modules containing a lot of things not related to my project. Newbie in this field my only wish is to gitignore this folder or better, put it somewhere else.
Is it common to have local modules to a project? Is there a way to install all these dependencies globally or in a dedicated environment (e.g Python virtualenv)?
The directory does contain libraries that are required by your project - and their dependencies. From my experience, the dependencies of the libraries I'm using are about 3/4 of the folder size.
You can install a library globally using the -g switch of npm, I'm not sure if vue has similar option. But this is not recommended - the point of installing libraries with your project is that the project will remember which libraries belong to it, those are saved in package.json.
You could copy the node_modules directory to the root of your hard-drive and merge it with other node_modules directories, but you're risking that you'll mix different library versions that way, so this is not recommended.
Unless you're running low on free space, just leave it be. Remember to add the node_modules to .gitignore if you're using git.
In short, node_modules is a place where all your project dependencies are stored. And allows you to use these dependencies in the code if you want to and allows for the modules itself to have it own dependencies if any.
And it is very common or rather always the case when a local node_modules folder is created.
You can install dependencies globally by doing npm install -g module_name command via your CLI. But these may cause the issue if the global paths are not configured properly.Also, it is not advisable to keep all the required dependencies by an application in global context.
If you do not want some dependencies to be part of your production environment you can install them as dev dependencies via npm install--save-dev module_name command. These(normal & dev dependencies) will be installed when a developer clones your project and run npm install locally to run the project and run tests. But to ignore these from being installed on production you can execute npm install --production command, this will make sure that only dependencies required for your code to run will be installed in the node_modules folder.

node_modules dir being included in module published to NPM registry

I published my module to the NPM registry. When I installed it using
npm install --save-dev X
I see that the node_modules folder was included in the install, such that when I go to project Y which depends on X, I see:
Y/node_modules/X/node_modules
How is this possible?
My .npmignore file in my X project is as follows:
.idea
node_modules
bower_components
internal-docs
Anyone know what could be up?
You don't need to add node_modules to your .npmignore; it is ignored by default:
Additionally, everything in node_modules is ignored, except for bundled dependencies. npm automatically handles this for you, so don't bother adding node_modules to .npmignore.
The npm install command will naturally install the package's dependencies that are listed in its package.json file. It is a normal part of the npm install process to install the whole dependencies tree, otherwise the package wouldn't really work.
If you want to be really sure, you can use the npm pack command to generate a tarball (similar to a zip file) that you can inspect and see what files are actually published when you run npm publish.

npm install generate more folders than needed

I've been using ember for a while and when I wanted to install the node dependencies of a project, I just needed to use npm install to create the folder node_modules with all the dependencies (as it's described in http://ember-cli.com/user-guide/).
Since I was using an old version of node I unisntalled node and npm and installed nvm with the versions node v5.0.0 and npm v3.3.6but now, when I try to use npm install to install the dependencies of a project as I used to do before, instead of the dependencies of the package.json file, I get many, many more from things I'm not sure where they come (I think they are dependencies that npm handles by itself in a globally way but now it's adding them to my project locally, but I'm not sure).
Why am I getting all those unknown (for me) dependencies?
Notice that, when I run ember new it generates the correct dependencies in node_modules but if I delete this folder and run npm install happens the same.
That's one of the changes introduced by npm v3.0:
Your dependencies will now be installed flat - by default. If
possible, all of your dependencies, and their dependencies, and their
dependencies will be installed in your project's node_modules folder
without nesting. Nesting will only occur when two or more modules have
conflicting dependencies.
Read more at http://www.felixrieseberg.com/npm-v3-is-out-and-its-a-really-big-deal-for-windows/

"npm install" only those modules that arent already installed globally

Is there anyway to install dependencies which are not installed globally? For example: i got gulp installed globally, then I have some app with gulp inside package.json. When i run:
npm install
it will download and install gulp in node_modules in my app root folder, even if it is already in node.js global.
It would be nice, because I made template for new projects, with lots of dependecies. I dont want to keep over 20000 files in each project root folder...
Gulp is actually required to be installed both locally and globally.
require can only find locally installed modules. Globally installed modules are generally required for command line. But if you have a require statement in your file (which it is in case of gulpfile.js) it will need that module be installed locally.
A possible solution for not having to keep same dependencies in two places could be to put them in a parent node_modules folder
My Projects
node_modules
gulp
Project A
...
Project B
...
Since require looks for modules in parent directories successively from current level this shall work.

Install Certain NPM Modules Globally?

I'm debating how I should setup certain node modules.
Lets say I have a folder called "Projects". This will hold various code projects for node that I'll create under this going forward.
Now I can install stuff like cucumber, lodash, mocha, etc...stuff that I know I'll probably use across most all my projects:
1) npm install -g
- here, any package.json can find it on my PC I think
2) npm install [whatver] in the root of my "Projects" folder so that now I have an npm_modules folder sitting at the root so any projects created's package.json will able to find those type of modules at the root of my Projects folder
- here, I'd have to npm install once at the root of my Projects folder if not already installed globally and I didn't go with option #1
3) npm install into each project under projects. But this seems like it's not efficient. If I have to make people install stuff like cucumber every time they clone down a project, that means when they run npm install, it'll have to install cucumber again and again, for each project which seems stupid to me to do something like that if it's really a global package I plan on using across many projects
-- so here for example I might have several projects I create or clone: Projects**MyProject1**, Projects**MyProject2**, and so on. Each of those projects has its own package.json of course looking for dependencies like cucumber, mocha, etc. If I do it this way I'll have to wait for npm to install those into each's own node_module folder so for example Projects\MyProject1\node_modules\cucumber, Projects\MyProject2\node_modules\cucumber and so on. Seems stupid and duplication all over to do that...?
Suggestions on which option is best and why you think that based on your experience managing projects in node?
npm install -g - here, any package.json can find it on my PC I think
This won't work because global modules cannot be picked up by require in your node scripts.
npm install [whatver] in the root of my "Projects" folder so that now I have an npm_modules folder sitting at the root so any projects created's package.json will able to find those type of modules at the root of my Projects folder
This will work for sure as long as the projects in your "Projects" folder will always be there. If you publish a project then the dependencies for that project will have to go with it.
npm install into each project under projects. But this seems like it's not efficient. If I have to make people install stuff like cucumber every time they clone down a project, that means when they run npm install, it'll have to install cucumber again and again, for each project which seems stupid to me to do something like that if it's really a global package I plan on using across many projects
Why is this stupid? As long as you do npm install cucumber --save then your dependency on cucumber will be saved to your project's package.json file. All anyone who clones your project should have to do is this:
$ git clone project.git
$ cd project && npm install
npm install without any additional arguments will install all the dependencies listed in the package.json file for the project. It only has to do this once. After that all the dependencies are downloaded and installed within the node_modules directory for your project. The only time they'd need to run npm install again from the root of the project directory would be if they deleted the node_modules folder or you made a change and added a new dependency to package.json.
Installing modules in your "Projects" directory will make them available to any scripts requireing the module from within any subdirectories. Keep in mind that if I were to clone your repository I won't have your "Projects" directory. I'll just have the directory for your project, wherever I cloned it to. I need to get those dependencies somehow and the easiest way is for me to cd into the project and run npm install where you should have a package.json file that lists all the required dependencies.
PS - npm install [module-name] --save only saves the dependency version if you already have a package.json file in the root of your project. If you don't have one yet, then initialize one first.
$ npm init

Resources