passing the express app to the routes files - javascript

I'm writing an express 4 api server with no front end code. I chose to structure my project so that the folder structure is based on the business logic of the project rather than doing it based on the type of file (routes, models, etc.)
For instance, my User folder has my userRoutes.js, userModel,js, userApi.js, ...
My main question is actually how should I pass the app into my routes files? My favorite approach was doing global.app and making it global, but I hear that is not best practice. If you have any advice on my business logic structure that would be great too.

Firstly, your file structure sounds over-the-top. If you need that much to split things out cleanly, go for it. But, I have a hunch that you're overdoing it.
In any case, what I normally do is return middleware from each module. You can give each middleware its own Express router if you want. In the modules:
const express = require('express');
module.exports = function (config) {
const router = new express.Router();
router.get('/something', (req, res) => {
// Code here
});
return router;
}
Then in your main application:
const somethingHandler = require('somethingHandler.js');
app.use(somethingHandler);
This is in-line with how all other Express middleware modules work. This also allows you to namespace modules by path, with your app.use() call in the main app.

You must require express app or pass to routes file by excute require function like this:
var app = require('express');
var userRoutes= require('your route path')(app);
I think global variable is not good idea.

Related

Nodejs expressjs make npm package available throughout the project

I've this folder structure.
/app.js
/src
/routes
/controllers
In routes folder, I've bunch of js files. All of these files need to require passport js package like this
const passport = require('passport');
Instead of doing this, can I require the package in one place (Most probably in app.js) and somehow pass that to each and every file in the routes folder instead of requiring it on every file.
There may be a passport/Express-specific solution (e.g., installing passport once as middleware), but answering the question about modules in general:
Requiring a module in a module that uses it is standard practice and clearly expresses the dependencies between modules, so it's not usually something you want to avoid doing.
Instead of doing this, can I require the package in one place (Most probably in app.js) and somehow pass that to each and every file in the routes folder instead of requiring it on every file.
You have a couple of options:
If all of those files have other things they're also all importing, you can create a rollup module that requires all of those things and then makes them available as exports. Then your files would do:
const {passport, anotherThing, yetAnotherThing} = require("./the-rollup-module");
instead of
const passport = require("passport");
const anotherThing = require("another-thing");
const yetAnotherThing = require("yet-another-thing");
The rollup would look like this:
module.exports.passport = require("passport");
module.exports.anotherThing = require("another-thing");
module.exports.yetAnotherThing = require("yet-another-thing");
(I don't recommend this.) You can make it a global by putting this in your entry script:
global.passport = require("passport");
That exposes passport as a global variable, so your modules could just use passport without requireing it. (The default global variable is a reference to the global object, like window on browsers, so any property you create on it becomes a global variable.)
I don't recommend it because then the dependencies between your modules are no longer clearly defined.
No matter how often you require() a module, it will be loaded just once. There is nothing wrong with requiring one module in multiple files, actually this is basically the way the module system is designed to work.
If the files in the routes folder are not using the express router you can rather or else export the function which accepts passport and app objects like
module.exports = function(app, passport) {
app.get('/', (req, res) => {
res.json('some route');
});
}
Then you will be requiring the passport only once in the app.js/server.js and passing the same object to every route

Coffeescript: How to import express module in one line

Currently, I have to write
app = require 'express'
app()
To get the equivalent Javascript:
var app;
app = require('express');
app();
How can I do this in one line?
I want to clear thing up here.
First of all, here is the most common way to import express module and create an application:
express = require 'express'
app = express()
app variable here holds a freshly created express application, while express variable holds the framework itself.
Now, let's say you don't need express framework here, only an application. In this case you could write:
app = do require 'express'
And if you don't need a variable holding your application, you could write something like that:
do express = require 'express'
Though I can't imagine why anyone would want it. Of course, you could chain everything:
do express = require 'express'
.use(express.static('public'))
.listen(3000)
But for me it looks like a mess.
You could do something like this: require('express')(). But the downside to this approach is that you'd lose access to the app variable.
Try this
do app = require 'express'
There are multiple ways to do what you're asking...
For the correct answer (has the exact javascript output you want), try one of these:
app = require 'express'; do app
app = require 'express'; app()
Some other options would be:
(app = require 'express') null
do app = require 'express'
app = require 'express'; app null
Which result in slightly different Javascript output, but work exactly the same.

is passing app = express() into another module the same as requiring the module?

I am wondering what is the difference between passing app = express() into another module versus requiring express within that module instead.
if I was to pass app = express() like so:
var app = require('express');
app.locals.title = title;
require('somemodule')(app);
then in the somemodule;
exports = function(app) {
console.log(app.locals.title);
}
would you be able to use the app.locals variable set in the core file if you was to require express again within another module like so instead.
var app = require(express);
console.log(app.locals.title);
if not would you have to redefine the app.locals within this module?
which method would be best to use.
First, I'll assume you're using Express 4x. In 4x, the module actually exports a function, so you'll need to first create the app, after requiring the module. Like so:
var express = require('express');
var app = express();
If the module does something like adding middleware, or adding functionality to the app you create in your project, then it's only going to work if you first create the app, then pass it into the module. See below:
var express = require('express);
var app = express();
require('middleware-adder')(app);
// app now has the middeware provided by my module.
Anything set on the app before passing it into the module you're requiring (like app.locals.title in your example), would indeed be accessible inside of the module. As the author of a module, you'll need to be extra certain that the consumers are passing what you expect them to be though!
Hope this helps.

How do I split up index.js file in a node/mean/express application?

I've got one incredibly long index.js route file for my node/mongo/express application. Here is the structure.
app.js
/models
Schedule.js
Task.js
etc...
/routes
index.js
/public
/javascript
etc...
I want something like this
app.js
/models
Schedule.js
Task.js
etc...
/routes
index.js
schedule.js
tasks.js
etc...
/public
/javascript
etc...
How can I split up my index.js file?
For example, I have tried to do something like this in my app.js file
var routes = require('./routes/index');
var tasks = require('./routes/tasks');
// later in the file
app.use('/', routes);
app.use('/tasks', tasks);
However, it is not finding my task routes like it did before when I had only the index.js. This is probably because I took all the routes starting with "/task" from my routes/index.js and placed them in routes/task.js, but why express not recognizing the routes in this new file?
Any advice at all would be helpful, my friend and I are very new to the whole meanjs way of doing things, and basically cobbled together what we have from various tutorials. Now we desperately need to refactor, because routes/index.js is getting too long to work with. I did my best to do what makes sense intuitively, could anyone out there give advice on how to break up our routes file?
Well, the answer to this question lies in how you import (require in this context) the router instance. Each one of those files should do a module.exports with a router object or something similar where the routes can be mounted on the app instance you create.
For example, have a look at how I do it (with yeoman's help that is) in a project I have on GitHub here, then refer to how the router object is exported for each route like this example.
As another example of doing this, here is an open source project I've been contributing to here. Notice that we have a slightly similar approach here, then have a look at an example route declaration (with the corresponding export) here.

Making several applications inside of an express app

I come from a django background, and basically, the framework allows for a lot of modular code. I've created a simple blog engine in nodejs and express. However, all the routes end up being in my main app.js file, or rather app.coffee, since I used coffeescript for my nodejs applications, which complied to javascript.
So, say this is how my routes look:
app.get('/', index.index)
app.get('/users', user.list)
app.get('/blog', blog.blogList)
app.get('/blog/:id(\\d{5})', blog.blogEntry)
Now, the problem here is that if I want to sort these by categories, then this happens, then I would have to add another app.get function to the same file. Code:
app.get('/blog/categores/:cat(\w+), blog.someotherview)
If I wanted to add sorting according to time, for example:
app.get('/blog/time/:year(\\d{4}), blog.someYearView)
What I would like to do is delegate everything concerning /blog to be handled by blog.js for example. Ideally, how do I get all these routes out of the main app.js file?
You could easily do this by using the include() method in django.
Create an Express app in your app.js file, as you are used to. Then, do the same in the blog.js file. Import and use it within app.js as follows:
var blog = require('./blog');
var app = express();
app.use(blog);
Inside your blog.js file, all you need to do is to export your app:
var app = express();
app.get('/blog/...', ...);
module.exports = app;
To put it in other words: Any Express app can be used as middleware for any other Express app, hence you can create sub-apps.
Hope this helps.
PS: TJ Holowaychuk (the creator of Express) created a video on this, Modular web applications with Node.js and Express.

Categories