typescript node.js express routes separated files best practices

Andrei picture Andrei · May 11, 2016 · Viewed 27.3k times · Source

using Express in a Node project along with Typescript what would be the "best practices" for express.Router.

example directory structure

|directory_name
  ---server.js
  |--node_modules
  |--routes
     ---index.ts
     |--admin
        ---admin.ts
     |--products
        ---products.ts
     |--authentication
        ---authentication.ts

so inside index.ts it would encapsulate and manage all the sub-routers



    //index.ts (master file for express.Router)

    import * as express from "express";

    //import sub-routers
    import * as adminRouter from "./admin/admin";
    import * as productRouter from "./products/products";

    export = (() => {

      let router = express.Router();

      // mount express paths, any addition middleware can be added as well.
      // ex. router.use('/pathway', middleware_function, sub-router);

      router.use('/products', productRouter);
      router.use('/admin', adminRouter);

      //return for revealing module pattern
      return router;
    })(); //<--- this is where I don't understand something....

lastly we would set-up our server.js

    //the usual node setup
    //import * as *** http, body-parser, morgan, mongoose, express <-- psudocode

    import * as masterRouter from './routes/index'

    var app = express();
    //set-up all app.use()

    app.use('/api', masterRouter);

    http.createServer(app).listen(8080, () => {
          console.log('listening on port 8080')
        };

my main question really is, is index.ts (masterRouter file) and it's nested routes that are IIFe's

export = (function(){})();

should that be the correct/best way to write typescript modules for routers?

or would it be better to use another pattern, perhaps one the utilizes the pattern

export function fnName() {} -- export class cName {} -- export default.

the reason for the IIFe is that when i import them into another file i won't need to initialize the module and there will only ever be 1 instance of each type of router.

Answer

basarat picture basarat · May 12, 2016

Answer

In NodeJS each file is a module. Declaring variables does not pollute the global namespace. So you don't need to use the good old IIFE trick to properly scope variables (and prevent global pollution / collision).

You would write:

  import * as express from "express";

  // import sub-routers
  import * as adminRouter from "./admin/admin";
  import * as productRouter from "./products/products";

  let router = express.Router();

  // mount express paths, any addition middleware can be added as well.
  // ex. router.use('/pathway', middleware_function, sub-router);

  router.use('/products', productRouter);
  router.use('/admin', adminRouter);

  // Export the router
  export = router;

More on modules

https://basarat.gitbooks.io/typescript/content/docs/project/modules.html

My reaction 🌹

my main question really is, is index.ts (masterRouter file) and it's nested routes that are IIFe's export = (function(){})(); should that be the correct/best way to write typescript modules for routers


(source: memesvault.com)