user10074403
user10074403

Reputation:

How can I make static variable in `module.exports = class` in node.js

How can I initialize a static variable in module.exports = class in node.js.

Basically, what I'm trying to achieve is, if StaticVariable is null, Ill get data from a json file. Then store it in StaticVariable.

module.exports = class Config { 
    static fetch() {

        if ( StaticVariable === null ) {
            const fs = require('fs');
            const data = fs.readFileSync('./config.json');
            const config = JSON.parse(data);  

            StaticVariable = config;

        }

        return StaticVariable;
    }
}

Function fetch() will be called several times so it is unnecessary to readFileSync every call.

Upvotes: 1

Views: 5492

Answers (3)

Lawrence Cheuk
Lawrence Cheuk

Reputation: 464

Starting from (node 15.2.1) ES2020, static private class fields is supported. So from now on static class may not be anti pattern and you can instantiate a class using new keywords. ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static

module.exports = class Config { 
    static #StaticVariable = null;
    static fetch() {    
        if ( StaticVariable === null ) {
            const fs = require('fs');
            const data = fs.readFileSync('./config.json');
            const config = JSON.parse(data);  

            StaticVariable = config;

        }    
        return StaticVariable;
    }
}

Where # sign means private more reference can be found in https://node.green, but still the easiest way is described in other answers

exports.config = require('./config.json');

Upvotes: 0

s_a94248
s_a94248

Reputation: 148

I can think of several ways to achieve what you are asking.

Saving it in a global variable

//initialise it here
var StaticVariable = null;

//however if you initialise it here, it makes more sense to just load it once
const fs = require('fs');
const data = fs.readFileSync('./config.json');
const config = JSON.parse(data);  
StaticVariable = config;

module.exports = class Config { 
    static fetch() {
        return StaticVariable;
    }
}

Or just use require. Require will do the same thing what you want to do. It will read the file config.json, try to parse it as a valid json and it will do this only once.

module.exports = class Config { 
    static fetch() {
          return require('./config.json');
    }
}

Upvotes: 0

Estus Flask
Estus Flask

Reputation: 222379

Static-only class is an antipattern in JavaScript because a class is never instantiated.

In case there's a need to have a method that lazily loads JSON file, a plain object can be used. There's already such object in module scope, module.exports:

const fs = require('fs');
let StaticVariable;

exports.fetch = () => {
    if ( StaticVariable == undefined ) { // not "=== null"
        const data = fs.readFileSync('./config.json');
        const config = JSON.parse(data);  

        StaticVariable = config;

    }

    return StaticVariable;
}

There may be no need to parse it manually because this could be handled by require('./config.json') one-liner and with more consistent relative paths.

In case JSON file can be eagerly loaded, this can be simplified to:

exports.config = require('./config.json');

If there's a need for Config class and it should access configuration object, it can refer to it, e.g.:

exports.Config = class Config {
  constructor() {
    this.config = deepClone(exports.config);
  }

  modify() {
    // modify this.config
  }
};

Upvotes: 1

Related Questions