Node.js: Where To Place Internal Modules In Folder Structure? - node.js

The Situation
I often see Node.js applications with the following structure:
Common pattern:
lib/ or src/ - the self-written code
index.js - main code
internal modules... (e.g. self-written for this project)
node_modules
external modules... (e.g. taken from another project)
package.json
My Problem
What I don't like about this pattern:
I don't feel comfortable about it because you have to explicitly specify the directory path of the internal modules when require()ing:
// /lib/index.js
var internalMod = require('./internal'); // `require('internal')` (without path) wouldn't work
internalMod.doSomething();
My Idea
So I think it would be a good idea also to place internal modules in an node_modules folder (somewhere in the project). So node would be able to find them, even if you don't explicitly specify the path.
For example:
src/ - the self-written code
index.js - main code
node-modules - for internals
internal modules...
node_modules - for externals
external modules... (e.g. taken from another project)
package.json
My Question
Are there any cons about my plan?
Is there another idea where to place internal modules in folder structure?
Thanks for your answer (or comment). - If anything is unclear, please comment.

Perhaps you could use npm link to pull your modules into node_modules?
See: https://docs.npmjs.com/cli/link

Related

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.

browserify-shim error when node_modules folder is a symlink

On the production server node_modules folder is a symbolic link for continuous deployment purposes.
When I run gulp command, I got many errors like this:
Error: Unable to find a browserify-shim config section in the package.json for /home/web/www/persist/node_modules/jquery-ui/jquery-ui.js while parsing file: /home/web/www/persist/node_modules/jquery-ui/jquery-ui.js]
filename: '/home/web/www/persist/node_modules/jquery-ui/jquery-ui.js'
. . .
If I move node_modules in project folder, build process is successfull. How to solve this problem?
Answer from thlorenz (author of browserify-shim)
Linking breaks browserify and shim since your projects dependencies
are outside of your project tree. So when looking upwards these tools
can't find the package.json of your package anymore.
So don't link your node_modules folders .. it's a bad idea anyways
since you're then linked to a global in your system, i.e. it's better
to have all your deps be local to your project. Not sure what your
deployment purposes are, but to me it seems like whoever made that
decision didn't fully understand how node/npm is supposed to work.

Avoid using relative paths on require()

I'm new with NodeJs, my project is growing and i dont want make relative imports, i want imports like these installed from npm.
I have the following directory structure
Project
node_modules/
src/
model/
person.js
test/
model/
person.js
app.js
config.js
i'm using mongoose and i can require mongoose from any place with require('mongoose') but by example if a want require my person model from app.js i write require('./model/person') and from my test/model/person.js i need write require('../../src/model/person').
Exist some way "native" (without install more dependencies) to make this some like require('model/person') from any place of my app?
This topic is extensively discussed here. My conclusion is mostly:
The idea of putting tests in a separate directory is ineffective. Put tests right alongside the main code: app/users/user.js and app/users/user.test.js.
I create a symlink at node_modules/app that points to ../app so I can require('app/users'); from anywhere in the code base.
There is nothing which says you cannot put your own code inside node_modules. This will enable you to reference it as you want. If you have a .gitignore or equivalent preventing code inside node_modules from being committed, you can add exceptions for your own code.
node_modules
!node_modules/model/

Node.js npm dependencies in subfolder

I have a project in which I use node-webkit. node-webkit allows npm packages to be used for developing desktop applications. I make use of grunt to build my application.
My folder structure looks like this at the moment:
project root
node_modules/ (1)
package.json (1)
App/
node_modules/ (2)
package.json (2)
bower.json
bower_components/
...
controllers/
filters/
...
app.js
The npm dependencies for the application itself are kept within the App folder, but the dev dependencies for building the project are not related to the application source code, so i keep them in node_modules (1) inside the root folder. I also know that in a package.json file one can express dependencies and dev dependencies, exactly for this reason. I would rather have one package.json file in the root expressing ALL dependencies, including dev dependencies, but i would rather have a separation of those dependencies on folder level.
Two questions arise:
Is this a good way to organize my npm dependencies? If yes, awesome? If no, which I expect:
What is a better way to organize my dependencies? Is it possible to specify that dev dependencies go into folder a, and 'regular' dependencies go into folder b? If so, how do I do this?
In case anyone is wondering, this is the project i am talking about:
https://github.com/michahell/pinbored-webkit
[updated folder structure to include app.js for clarity]
It is perfectly fine to keep more than one package.json file and multiple node_module directories for a project. If you consider the parts as separate components.
An example might be if, you have one directory containing a node server, another containing a react app, and a third containing some kind of deployment script written in javascript.
#Michael package.json file contains all the dependencies related to that project.There is no need for multiple package files and multiple node_modules folders..
But you need to check where is your App.js file!!
your App.js , package.json must be in same folder unless configured.

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