Well i have index.js which is about 3000+ lines. I started building an app and at the same time I was learning NodeJS and didn’t think about separating routes to external files as i did not think, it will end up this big, so all my routes code ended up in index.js and again at the same time I was also started learning and using Firebase functions, so that also ended up in index.js.
Interestingly there is no problem with the code for last 4-5 years, thats the number of years, i havent touched it or reviewed it. It works perfectly. Currently i got plans to decommission some pages, functions and routes. Since its massive, i am little worried that i might break things unnecessarily.
Looking at the WWW on the topics of Modularizing code in NodeJS came across few patterns which i will be following,
Big Bang Pattern - My current pattern, all in one file. You can call it index.js, app.js, server.js whatever you want but all your app code is in that one file.
Not going to explain on Big Bang Pattern much, it basically looks like below code. Middleware, Routes, 404 Invalid Route Handling all in one page.
We will be building upon this for the all pattern examples.
2. All routes are externalized to a route folder
Here we have externalized routes to a separate folder ./routes and created a separate .js file for each route and grouped some in a single file.
Below i have highlighted some important lines
Requiring the files from ./routes folder
Using app.use(), mounting the routes in index.js
Using app.get()
Whats the different between app.use() and app.get()
app.use() is intended for middleware. The path is a “mount” or “prefix” path and limits the middleware to only apply to any paths requested that begin with it. app.use() will respond to all the HTTP verbs(GET, POST, PUT)
app.get() is part of ExpressJS application routing and is intended for matching and handling a specific requested route. This allows you to align responses for requests more precisely than app.use(). When using app.use() for routing, you might require extra code to identify what type of HTTP request, routes and parameters passed.
Here we are using express.Router class to create modular, mountable route handlers. A Router instance is a complete middleware and routing system.
At the end, you export this module and you can import and consume by requiring it index.js
For wiki, we are directly writing a function and exporting it to be consumed in index.js
In this technique, we are moving the routes to its own separate folder under routes. Main index.js is simple enough where we are just requiring and using app.use() to mount the routes.
Highlighted is how we are exporting the app to be used by Main index.js
4. Dynamically including all the routes
In this approach, routes are dynamically included meaning ./routes/index.js will read all the .js files in the folder and export it.
This file reads all .js files in the routes folder and requires it and creates an instance app and thats exported which is consumed by index.js.
Below is the books.js routes file which exports one or more routes.