I have a file where I call all the require modules called 'app.js'
var express = require('express');
...
var app = express();
...
var routes = require('ruotes/index.js)
use('/', routes);
module.exports = app;
I call the index.js where I have all the routes
routes/index.js
var express = require('express');
var app = express();
/* import controllers */
var indexController = require('../controllers/index');
app.route('/')
.get(indexController.index);
module.exports = app;
The problem is I have two variables called app and I call twice express(). Does it exist a more elegant way to handle this situation? Maybe I could call the variable in router file in another way?
You are currently using a technique that is known as submounting.
If you want to avoid creating different instances of Express, you will have to pass your unique instance of Express as a parameter to your router, meaning that your index.js needs to export a function that accepts your app as a parameter.
Something like :
//=== routes/index.js
/* import controllers */
var indexController = require('../controllers/index');
module.exports = function(app){
app.route('/').get(indexController.index);
};
Doing so will allow you to keep the same instance of Express in your entire Web App.
Since you exported a function in index.js, you need to call it in app.js.
var express = require('express');
...
var app = express();
...
var routes = require('routes/index.js)(app)
module.exports = app;
You can use the same technique for routes, modules, models etc...
This technique will allow you to avoid re-requiring modules, and instantiating them, but you will need to write extra-bits to make sure your variables are passed from one side of your app to the other. Because of this, some prefer using the submounting technique, and requiring modules only where they are needed.
Related
As mentioned in express routing guide and this answer, we can create "mini-app" and use it from the main app. However I saw a code where it uses app instead of router in the module
app.js
var express = require('express');
var userRoutes = require('./routes/user');
var app = express();
app.use('/user', userRoutes);
module.exports = app;
routes/user.js
var express = require('express');
var app = express(); // not express.Router() !!
app.get('/:name', function(req, res) {
var userName = req.params.name;
res.render('user.jade', {
userName: userName
});
});
module.exports = app;
I assumed the correct usage in routes/user.js should be
router = express.Router()
instead of
app = express()
but app = express() also works! what are the differences and why router = express.Router() is better?
When you are working with a server where there are many routes, it can be confusing to leave them in a Main file together. The let router = express.Router() option works differently than let app = express().
While the app returns an app object, router will return a small app fragment, similar to the app, where you will use logic to call them later on the Main.
The most important, about your question, is that a router, which is isolated, will not interfere with others in the application, being a single environment.
https://expressjs.com/en/api.html#router
A router object is an isolated instance of middleware and routes. You can think of it as a “mini-application,” capable only of performing middleware and routing functions. Every Express application has a built-in app router.
A router behaves like middleware itself, so you can use it as an argument to app.use() or as the argument to another router’s use() method.
Hello guys so i have this two variables i am requiring them for every route i have so i want to globalize them and just add them to the app.js but when i do that it didn't work.
var express = require('express');
var router = express.Router();
i tried to addd them in to my separate file config.js and then i require it in my route and assign it to variable and use it but it is not working.
my config file look like this
/**
* Module dependencies.
*/
var express = require('express'),
favicon = require('serve-favicon'),
logger = require('morgan'),
bodyParser = require('body-parser'),
methodOverride = require('method-override'),
errorHandler = require('errorhandler'),
path = require('path');
module.exports = function() {
var app = express();
var router = app.Router();
return app;
}();
i get this error all the time :
throw new Error('\'app.router\' is deprecated!\nPlease see the 3.x to 4.x migration guide for details on how to update your app.');
TLDR: Your router variable is an instance of Router, and should to be initialized inside each of your route files. I can appreciate trying to be as DRY as possible, but doing it this way will not work the way you expect it to. You can save a bit of typing by writing it this way:
var router = require('express').Router();
The longer explanation is that use multiple routes, you need a router for each route. This is to help break up the whole path associated with a request (i.e. /bar/foo/baz) into more manageable chunks.
Let's say your path can start with either /cats or /dogs. In the file where you declare all your middleware, you could write:
var catRoute = require(./routes/cats)
var dogRoute = require(./routes/dogs)
app.use('/cats', catRoute)
app.use('/dogs', dogRoute)
Then, inside cats.js:
var router = require('express').Router();
router.get('/whiskers', (req, res) => {
res.send('Cat whiskers!')
}
module.exports = router;
What this does is tell the app if it gets a path starting with /cats, use the cats route, which is just another piece of middleware. Within the route itself, we don't have to specify /cats/whiskers, only /whiskers because app is only passing down the part of the path after /cats to the cats.
You can nest as many routers as you want. Check out this article for a good example of how to do that.
Hypothetically, you could use only one router
Dumb/Newb question...
I am learning/working on an API in Node / Express4 and I would like to break my routes out into another module. I have it working with the following code, but it seems awkward to me to keep re-using the require('express') statement... Is there a way to move more of the code from the routes.js file into server.js and still keep my .get and .post statements in the routes module? Thanks in advance!
server.js:
'use strict';
var express = require('express');
var routes = require('./routes');
var app = express();
app.use('/api', routes);
app.listen(3000, function() {
console.log('Listening);
});
routes.js
var express = require('express'); // how do I get rid of this line?
var router = express.Router(); // can I move this to server.js?
var apiRoute = router.route('');
apiRoute.get(function (req, res) {
res.send('api GET request received');
});
module.exports = router;
Your on the right track. Its actually cool to reuse the var express = require('express'); statement each time you need it. Importing, ( requiring ), modules is a cornerstone of modular development and allows you to maintain a separation of concerns with in the files of your project.
As far as modularly adding routes is concerned: The issue is that routes.js is misleading.
In order to modularly separate out your routes you should use several modules named <yourResource>.js. Those modules would contain all of the routing code as well as any other configuration or necessary functions. Then you would attach them in app.js with:
var apiRoute = router.route('/api');
apiRoute.use('/<yourResource', yourResourceRouter);
For example, if you had a resource bikes:
In app.js or even a module api.js:
var apiRoute = router.route('/api')
, bikeRoutes = require('./bikes');
apiRoute.use('/bikes', bikeRoutes);
Then in bike.js:
var express = require('express');
var router = express.Router();
var bikeRoutes = router.route('/');
bikeRoutes.get(function (req, res) {
res.send('api GET request received');
});
module.exports = bikeRoutes;
From there its easy to see that you can build many different resources and continually nest them.
I'm using Express 4.2.0
Is it possible to include a module only once in app.js and use it in any defined route?
Right now this won't work:
app.js
//..
var request = require('request');
var routes = require('./routes/index');
var users = require('./routes/users');
app.use('/', routes);
app.use('/users', users);
//...
routes/user.js
var express = require('express');
var router = express.Router();
router.get('/add', function(req, res) {
var session = req.session;
request('http://localhost:8181/Test?val1=getDepartments', function (error, response, body) {
//...
});
res.render('users/add');
});
module.exports = router;
It will say that "request" is not defined in routes/user.js
ReferenceError: request is not defined
at Object.module.exports [as handle] (C:\inetpub\wwwroot\node7\routes\users.
js:12:5)
Having to include modules in every route which wants to use them doesn't sound like a proper solution...
Yes, there are two ways of creating global variables in Node.js, one using the global object, and the other using module.exports
Here is how,
Method 1. Declare variable without var keyword. Just like importModName = require('modxyz') and it will be stored in global object so you can use it anywhere like global.importModName
Method 2. Using exports option.
var importModName = require('modxyz');
module.exports = importModName ; and you can use it in other modules.
Look here for somemore explanation http://www.hacksparrow.com/global-variables-in-node-js.html
You can leave out the var and do just request = require('request'); but this is frowned upon.
Node.js caches modules. The standard approach is to require modules where needed.
I've just started to play around with Expressjs and I'm wondering how to pass variables to mounted middleware/sub application. In the following example, I'd like the config object passed to my /blog/index
in app.js
var express = require('express');
var app = express();
//...
var config = {}
//...
app.use('/blog', require('./blog/index')
in /blog/index.js
var express = require('express');
app = module.exports = express();
app.use(express.static(...
app.get('/', function(req, res, next) {
//handle the req and res
}
Thanks,
I see two options here:
Since your blog app is an express application, you can use app.set and app.get. E.g.
blog = require('./blog/index');
blog.set('var1', value1);
blog.set('var2', value2);
...
app.use('/blog', blog);
And in blog/index.js use app.get('var1') to get the value of var1.
You can wrap the blog express application in another function that accepts configuration parameters (much like the static middleware accepts a directory name) and returns the configured application. Let me know if you want an example.
EDIT: Example for the 2nd option
app.js would look like this:
var blog = require('./blog/index');
...
var config = {};
app.use('/blog', blog(config));
and /blog/index.js like that:
var express = require('express')
module.exports = function(config) {
var app = express();
// configure the app and do some other stuffs here
// ...
return app;
}