3

This is something I've wondered for a while now. Say I have an express application. I have this export in its own file:

// my-var.js
export const myVar = new Thing();

Then I have the server creation where I access that variable:

// index.js
import { myVar } from './my-var';
import { myRoutes } from './my-routes';

function startServer() {
    myVar.doSomething(); /* 1 */

    const app = express();
    app.use('/', myRoutes);
    
    app.listen(port, () => {});
}

Finally, I have my routes, which also use that variable:

// my-routes.js

import { Router } from 'express';
import { myVar } from './my-var';

const router = new Router();

router.get((req, res) => {
    myVar.doSomething(); /* 2 */
    res.json({});
});

So my question is: Is .1 and .2 referencing the same variable? Or has it been instantiated twice? I would kind of think it's instantiated every time the file is imported, because importing a file runs the code in that file. So myVar = new Thing(); is executed every time that file runs.

Troncoso
  • 2,343
  • 3
  • 33
  • 52

2 Answers2

1

The script file is executed once and there is a single result of that file. If any object is exported, all the modules will refer to the same instance of that object.

const myVar = new Thing();

myVar is created only once and then exported.

You can try changing a property in one module and checking that property in another to be sure.

Tushar Shahi
  • 16,452
  • 1
  • 18
  • 39
  • Thank you for the answer! I did run a test and verify that this is true. I don't quite understand how this works though. I thought every time a file is imported, it is executed. But I added a `console.log` in the `my-var.js` and it only printed once even though I import the file in 2 different places. – Troncoso Aug 05 '22 at 16:16
  • @Troncoso No, files are not executed every time they're imported; when a file is *first* loaded it's executed and Node remembers (caches) that file so it's not re-executed. – Dave Newton Aug 05 '22 at 16:25
1

That's what we call a singleton pattern package design, when you do it like this:

export const myVar = new Thing()

You only create the Thing instance once, and afterwards everytime you import it, you're importing the same instance, because it's a reference now.

If you want to get a new reference everytime the myVar is imported, change the code

from:

export const myVar = new Thing()

To

export const myVar = () => new Thing()

And when you import it, use it as follows:

import { myVar } from './my-var'

const instance = myVar() // returns a new instance from Thing

// use the instance here, ex: instance.color
Normal
  • 1,616
  • 15
  • 39