What does mean "var router = require('./router/main')(app)"? - node.js

(I know that there is a similar question in stackoverflow, but I can't understand that question's comment..)
I'm Korean middle schooler.
So I am not good at English but Please help me.
I'm studying Node.js and Express.js by example codes.
This is example code which I'm looking at.
var express = require("express");
var app = express();
var bodyParser = require("body-parser");
var session = require("express-session");
var fs = require("fs");
app.set("views", __dirname + "/views");
app.set("view engine", "ejs");
app.engine("html", require("ejs").renderFile);
var server = app.listen(3000, function() {
console.log("Express server has started on port 3000");
});
app.use(express.static("public"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(session({
secret: '##SEC$$RET##',
resave: false,
saveUninitialized: true
}));
var router = require("./router/main")(app, fs)
I have understood majority of this code, but I cannot understand "(app, fs)" at last line.
What does that mean??
I'll appreciate your kindness if you help me .. ㅠㅠ

This means that ./router/main module exports factory function that accepts application instance and fs module as parameters and returns router instance that depends on these parameters, e.g.:
var express = require('express');
module.exports = (app, fs) => {
var router = express.Router();
// define router routes that make use of `app` and `fs`
return router;
};
This way router factory function basically implements dependency injection pattern.
app parameter is a common Express recipe to pass application instance to a router, while passing fs is unneeded. fs module could be imported directly in ./router/main module, it doesn't benefit much from dependency injection.

It imports the router from that file. The router requires you to pass 2 parameters - the app and fs. It's the same as calling a regular function. Just here, it is importing the route and calling the function in one place.

Related

express.Router() vs express() in express

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.

Node.js argument type string is not assignable to parameter type function(T)

I learn Node.js. I started to create my first app with API.
What means the error on the tooltip? (see the image) I have seen it for the first time.
My code:
const express = require('express'),
app = express(),
bodyParser = require('body-parser'),
mongoose = require('mongoose'),
morgan = require('morgan'),
consign = require('consign'),
cors = require('cors'),
passport = require('passport'),
passportConfig = require('./passport')(passport),
jtw = require('jsonwebtoken'),
config = require('./index.js'),
database = require('./database')(mongoose, config);
app.use(express.static('.'));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(morgan('dev'));
app.use(cors());
app.use(passport.initialize());
app.set('medsecret', config.secret);
consign({ cwd: './services' })
.include('../API/app/setup')
.then('../API/app/api')
.then('API/app/routes')
.into(app);
module.exports = app;
You may ignore this tooltip, if then is an innate feature of consign module. Essentially, for the editor you're using, then chain is being interpreted by it as set of promises, and since you cannot merely pass strings as an argument to promises in the fashion like this, it displays false error.
Rest assured, if it doesn't lead to a loss of functionality, it is acceptable. You may ignore this tooltip for now.
Alternatively, you may try to install the ts defintions of the same, and then see if the erroneous tooltip vanishes.

Serve static files and directory listing in LoopBack

Following a LoopBack tutorial, I want to modify it to serve a directory listing if the directory does not have an index.html or similar.
I have previously done this in Express using:
var express = require('express');
var serveIndex = require('serve-index');
var app = express.express();
app.use('/', serveIndex(__dirname + '/public', {}));
app.use('/', express.static('public'));
Can I modify middleware.json to do this? Alternatively, how could I do this in a LoopBack JS boot script?
I have tried putting the following in a file routes.js in the boot directory:
module.exports = function(app)
{
var serveIndex = require('serve-index');
app.use('/', serveIndex(__dirname + '../client', {}));
app.use('/', app.static('../client'));
};
But it's obviously not the same, since app.static() in the first example is not a method on the same object as use() - ie the second example produces the error:
TypeError: app.static is not a function
(Also the paths aren't right, but I'm dealing with one problem at a time)
It was quite straightforward. While I could not find a way to access the express module via the loopback app object, it could simply be require()d.
Create the file ./server/boot/routes.js with the following:
module.exports = function(app)
{
var express = require('express');
var serveIndex = require('serve-index');
var croot = __dirname+'/../../client';
app.use('/', express.static(croot));
app.use('/', serveIndex(croot, {'icons': true}));
}

How to efficiently separate routing code

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.

nodejs middleware is skipped when called externally

I'm relatively new to Express and Node but this seems like a VERY basic demand and I am struggling to understand how it could be happening. Any help in solving the problem or identifying how I'd troubleshoot it would be VERY appreciated.
Problem
var
express = require('express'),
bodyParser = require('body-parser'),
logger = require('morgan'),
express = require('express'),
app = express();
app.get('/heartbeat', function(req,res) {
res.status(200).json(req.header('host'));
});
// my simple middleware component
app.use(function (req, res, next) {
console.log('made it');
next();
});
// standard middleware components
app.use(logger('dev'));
app.use(bodyParser.urlencoded({ extended: true }));
// Start listener
app.listen(4400);
This simple program does output my "made it" console message but yet when I wrap all the code (minus the variable definitions) in a function called start:
var
express = require('express'),
bodyParser = require('body-parser'),
logger = require('morgan'),
express = require('express'),
app = express();
var start = function(config) { ... }
exports.start = start;
and then call start from a separate module I find that the logging and bodyParser modules seem to execute but my middleware component is ignored. I'm pulling my hair out trying to figure why.
I see 2 issues with your code:
You must call app.use() before calling app.get(...) Otherwise, none of the middlewares are called.
In your custom middleware, you need to call next() or next(error) so that the request is moved to the next middleware. Otherwise, your server hangs forever.
If you post your whole code after separating module, I can help you find more issues :)

Resources