Load custom modules from root directory with NPM - node.js

Probably a really simple answer but I'm lost. If I'm in a file several directories below root is there a way I can require ('mylib/module1') in that file and have it search for the 'mylib/module1.js' from the root rather than the relative path of where I'm using the require statement?
Obviously if I require('underscore') it will just look for it inpackage.json, but I couldn't find any way to set up a reference inpackage.json` to point the right folder, something like:
dependencies: {
"mylib/module1" : "./mylib/module1.js"
}
I did find a reference to browser that allows you to map to client-side files, but I'm looking for something that will work on the back-end.

One way of doing it without needing npm support is to rename your mylib folder to node_modules. You can then simply require('module').
The reason this works is because require searches recursively up the directory structure until / looking for folders called node_modules. This very simple mechanism allows node to have multiple levels of lib directories which can be overridden at multiple "local" level where necessary. For example, you can have the following directory structure:
/usr
/home
/diplosaurus
/node_modules
module1.js <-------- version 1
/code
/node_modules
module1.js <-------- version 2
/projectA
/node_modules
module1.js <------- beta version
main.js
/projetB
main.js
All code in your home directory would use version 1 of module1 but code in the code directory would use version 2 and projectA uses the beta version.
This also means that you can let npm manage your project's node_modules directory yet maintain a manually managed, higher level node_modules directory for your personal libraries.

Related

Run Nodejs program that ignores parent node_modules

I have a library and I want to test it by doing a full install locally before publishing to npm. One of the things I want to test is if all the dependencies are part of the project. Because of how nodejs structures its module system though, (a nodejs module is searched for at every directory level) I do not have a good way to ensure that the module I am requiring came from the current folder's node_modules, and not the parent folder's node_modules.
Here is the project structure:
library-folder/
package.json
node_modules/
testing/integration/
package.json
node_modules/
test-install.js
I want to know if there is a way to tell nodejs to only require modules from the current directory, and ignore any parent directories.
I do not have a good way to ensure that the module I am requiring came from the current folder's node_modules, and not the parent folder's node_modules.
For that, you can use require.resolve and check the path it returns.
I resolved this issues by creating a file in the child's root project folder.
File's name should be called like this: .env
The content: SKIP_PREFLIGHT_CHECK=true

How to redirect search for node_modules in other directory

Hi I want to aceess npm modules from directory that is not the current one. The global modules are not solution since the dependency they involve. I want to have a container with all the modules I have downloaded and to redirect require to that directory instead of the current directory. That way all my projects could search for modules in a relative path like this ../ for example.
Here you can use npm link.
For example,
Let's say you have 10 local node package repositories (with package.json inside each package) in /User/you/modules and your project is in /User/you/project.
All you need to do is, link all modules in /User/you/modules directory to /User/you/project.
cd /User/you/project
find /User/you/modules/* -type d -maxdepth 0 -exec npm link {} \;
Now, you can use all your modules from /User/you/modules in /User/you/project without relative path.
So, you can now;
require('package-name')
package-name is taken from package.json, not from directory name.
instead of;
require('../modules/package-name')
Cheers.
You can set the NODE_PATH environment variable before/when running your app and this will allow you to add your own directories to the paths Node tries to resolve packages from.
The below example seems to work well when run as such: NODE_PATH=./lib node app.js
app.js
require('api')();
lib/api.js
module.exports = () => console.log('hello');
Here is an interesting Gist which includes some other routes if the above doesn't look appropriate for you. There is also some interesting discussion in the comments between some of the prominent Node.js folks.

Nodejs require module from external folder

I'm developing microservice architecture on nodejs.
I moved 'core' functionality to separate git repository, and each 'service' add that core as npm dependency.
In service I use core as
require('core/module1');
In that case nodejs takes 'core' from node_modules, it's ok for production but for development I want to take 'core' from the external folder not from node_modules.
My main idea - do changes in 'core' and immidiately get the result in 'service'.
I cannot use NODE_PATH for specify external 'core' folder, because I've used it now.
I found solution to use 'app-module-path' module for adding additional directories to the Node.js module search path.
if(isDevelopment()){
require('app-module-path').addPath('path_to_core_folder');
}
It's working solution, but maybe you can suggest some more clear way?
My folders structure
- core
module1
- service1
-index.js
-node_modules
-core
Thanks.
Either one works. If you require('modulename') and it's present in your node_modules folder, it will be loaded from there. If you want it to load from another folder or from your main folder, you need to do require('./modulename") which will look for it in the current folder. Alternatively you can do require('./my_modules/modulename') which will work for a subfolder.
i would look at the mockrequire module, it allows you to redirect the directory your modules are loaded from
npm link is the answer to your problem. You can run the below command in the root directory of 'service1' (where your package.json is present)
npm link [../relative-path-to/library]
Refer to https://docs.npmjs.com/cli/v7/commands/npm-link for more details about npm link.

require name instead of file path

I am looking at some code on github.
https://github.com/madhums/node-express-mongoose/blob/master/config/routes.js
On line 7 it says.
var home = require('home');
home.js is in another folder. I am wondering how this works, and how I can do this in my own code.
on
http://nodejs.org/api/modules.html#modules_folders_as_modules
it explains how to create a self-contained directory, but I can only find the package.json in the root folder. So how does this work?
It seems like a more clean way than having direct file references.
There are ways to refer to folders on the filesystem as packages in node, npm link for example, will pretend a folder is a module using symlinks.
The package you linked to is cheating a bit though, and I'd argue it's not clean at all when put like that. It's actually setting the NODE_PATH to include all controllers when the service is ran: https://github.com/madhums/node-express-mongoose/blob/master/package.json#L13
So all controllers files like home.js are autmatically available. The .js is always optional anyway.

Can I put the npm node_modules directory outside of my 'webroot'

I'm new to Node but am enjoying myself so far. I was trying to move my node_modules (libraries) directory outside of the public 'webroot' and need advice and guidance.
I've setup my simple expressJS based Node project as follows:
/my_project
/config
/public
/node_modules
server.js
I was wondering if there was any way I could have the /node_modules dir outside of my webroot and not break my application. I'm just so used to keeping the bare minimum in my publicly exposed webroot and don't feel right with the libs being in there. Call me old fashioned but that's how I'm used to doing stuff in the PHP and C# world.
If I setup the project as follows:
/my_project
/config
/node_modules
/public
server.js
then it all goes wobbly and Node's require() magic breaks.
I've tried the following:
var express=require('../express'); which doesn't work either giving me the 'Cannot Find module' type error.
Is what I'm asking even possible, if so then how?
Are there any major risks with me having my libs in a webroot or have I missed something fundamental here with the way Node works.
What do you guys do, what is best practice for production apps? May I have some examples of your production practices and why.
1. Is it possible to have modules in a folder outside of the project
Yes.
2. Are there any major risks with having modules in a webroot?
Assuming that you by "webroot" mean in the root of the server or any folder outside of your project: yes. It is possible to install modules globally with npm using the g-flag: npm install -g express. This generally considered bad practice as different projects may depend on different versions of the same module. Installing locally allows different projects to have different versions.
If you're using version control and don't want to check in the external modules, a common (and standard in npm) pattern is to ignore ./node_modules and specify dependencies in a package.json file.
3. "What is best practice for production apps?"
Not a good fit for SO, but since I'm at it I'll give it a shot anyway. If you use grunt (a very popular task automation tool) you'll usually end up with a structure like this:
/my_project
/node_modules
/lib
# actual project files
/public
# files that are meant to be sent to clients
/test
package.json # specifies dependencies, main script, version etc
README.md # optional
This structure has the advantages of clearly separating core files, dependencies and any tests while keeping it all in the same folder.

Resources