Home > OS >  is Express initialized first in Node initialization dependencies?
is Express initialized first in Node initialization dependencies?

Time:10-04

I'm having a problem during the initialization of a system. In order to initialize this system, I'm calling the index.ts file. This file imports an initializer class called StartServer. This class has an async method called start that initialize all the system database connections and express server. The problem is, somehow Node initialize express files, index.routes.ts, where the routes are defined, and all it dependencies, before starting the index file with the initializer class, generating an error of undefined due to no connections exits at this point.

index.ts file :

import { StartServer } from './services';

StartServer.start();

StarterServer.ts file :

export class StartServer {
  public static async start(): Promise<void> {
    try {
      const configPort: IConfig = config.get('App.port');

      await Connections.startDatabaseConnections();

      const server = ServerFactory.create();
      await server.init();

      console.log(`Server is listening at port ${configPort}...`);
    } catch (error) {
      console.error((error as Error)?.stack);
    }
  }
}

ExpressServer.ts file :

import routes from '../routes/index.routes';

export class ExpressApp {
  private app = express();
  private port = config.get('App.port');

  routes() {
    this.app.use(routes);
  }

  async init() {
    this.routes();
    this.app.listen(this.port);
  }
}

index.routes.ts file :

import express from 'express';

const router = express.Router();

router.get('/', (_, res) => {
  res.status(200).json({ message: 'App listening...' });
});

export default router;

ServerFactory.ts file :

import { ExpressApp } from '@src/services';

export class ServerFactory {
  public static create() {
    return new ExpressApp();
  }
}

CodePudding user response:

In Node, import (and require) are synchronous. As soon as you require a file it is executed.

// a.js
import b from './b';
console.log('a.js');

//b.js
import c from './c';
console.log('b.js');

// c.js
console.log('c.js');

That will output:

c.js
b.js
a.js

In your case, the index.routes.ts will be executed as soon as it's required by ExpressServer.ts. One pattern to avoid initialisation is to export a factory function to perform the setup. You're doing this for your server already!

import express from 'express';

export default function createRouter() {
    const router = express.Router();

    router.get('/', (_, res) => {
        res.status(200).json({ message: 'App listening...' });
    });
}
  • Related