Express Route calling methods at initialization phase?

1.6k views Asked by At

I have a basic express app, where app.ts looks like

import * as express from "express";
const application: express.Application = express();
 
application.get("/", function(
  request: express.Request,
  response: express.Response
) {
  console.log("Inside Router ");
  response.json({ "test": true});
}); 

application.listen(3000, function() {
  console.log("sever ready");
});

In this case, the console message "Inside Route" is printed in server console when the route is hit.

However,

wrapper.ts


const methods = () => {

};

console.log("This is a testable offence");
export const wrapperMethod = {methods};

 const express = require('express');
const wrapper = require('./wrapper');
const application = express();


application.get("/city", function(
  request,
  response
) {
  console.log("when");
  let results = {};
  let test = wrapper.methods();
  response.json(results);
}); 

application.listen(3000, function() {
  console.log("sever ready");
});

NPM COMMAND:

nodemon ts-node ./src/index.ts

In this case, on server start, we can observe "This is a testable offence" is being printed.

But the message "Inside Route" is only printed when the route is hit.

can anyone explain the reason for the same ?

4

There are 4 answers

0
Masih Jahangiri On

Short answer:

  1. All code inside of the module will run if we import it,
  2. A callback function will run when reciprocal action occurs.
0
tbhaxor On

TS is basically super set of javascript, so let's talk in terms of javascript.

While importing javascript, it execute the file, evaluate the script and cache it.

// module.ts
const app = "HELLO"

export {app}
// index.ts
import { app } from "./module.ts"

console.log(app);

app = 100; // you will get error here, because it already evaluated in module.ts

In your case, actually application.get has been executed but the callback function i.e function (req, res) is executed by the express whenever the particular route is hit by the user.

// express.ts
import { Router } from "express"

const router = Router(); // creating express router
router.get("/", function (req, res) {
  console.log("hit by ", req.ip)
  res.send("PING")
})

export default router;

So basically this whole code will be executed as soon as you will import the file into another

// server.ts
import router from "./express"
import express from "express"

// creating express application
const app = express();
// registering the route
app.use("/", router);

app.listen(3000)

Console after starting server

$ ts-node server.ts

Running command on terminal

$ curl localhost:3000
PONG

The server terminal after hitting api would be

hit by ::1 

If you want to see all the routes registered in app, see this question How to get all registered routes in Express?

0
Jack Yu On

After you use require, node.js will wrap your function with this.

'(function (exports, require, module, __filename, __dirname) { ',
    '\n});'

You could try to type node in your terminal and type require("module").wrapper to see.
So, node will put your code in this function, then execute this wrapper function like following code.


(function (exports, require, module, __filename, __dirname) {
    const methods = () => {

    };
    console.log("This is a testable offence");
    module.exports = {
        wrapperMethod: {
            methods
        }
    }
})

Note: I convert your export to CommonJS syntax.

After node execute this function, you could access wrapperMethod in outside file, and console.log should be printed. We could simplify thin function like following code.

(function () {
    console.log("This is a testable offence");
})

If you execute this function, what is it with output?
It's console.log message.

So, when you use require, node will execute the content of file with wrapper function.
That's why when your server startup, it display This is a testable offence.
Because you require your wrapper file with require('./wrapper'); in the head of index file.

0
janluke On

The console.log that prints "Inside router" is located inside a callback that is called only when the route "/" is hit. So the message is printed when the route "/" is hit.

The 2nd console.log is located at the top-level of the wrapper.ts module, so it is called only when wrapper.ts is loaded (at require('./wrapper')), which happens only when the application starts.

If you want to log that 2nd message every time wrapper.methodsis called, you need to put that console.log inside wrapper.methods.