node.jsrequire

In node.js is there a way to reuse a list of const-require statements, in all files?


In a Node project I will have these 20 lines of code ...

const db = require('./db')
const comms = require('./comms')
const stuff = require('./stuff')
const blah = require('./blah')
const bleh = require('./bleh')
...
const admin = require('./admin')

And I literally paste those 20 lines at the top of each and every one of the 20 .js files in question.

You do this for simple procedural efficiency (any of the lines unused, in that file, VS will harmlessly indicate it's unused, but you never have a missing one, and everyone on the team does the same thing, and you never have to think about it).

(Actually, one team I was on someone wrote a line of script to automate the process! It would just make the top of each file the same, based on all the current files. But setting that solution aside).

Is there some way to keep those 20 lines in another file reqs.js (or reqs.txt, or something) and have it "applied" to all files?

So it would be something like

actuallyRunTheCodeFrom( 'reqs.js' )

or something like

macro( someMacro )

which literally inserts the 20 lines of code in question, "in", this file.

I appreciate I could require reqs.js, and then prepend "reqs." everywhere: that is not my question.

I believe there is no way to "dynamically const" in node; there's nothing like ['db', 'comms', 'stuff'].foreach(const $0 = require(./$0)). I would be keen to know if I am wrong.

Is there a way to do this?


The @YoushaAleayoub method!

https://www.mediafire.com/file/t81fppv2x6wnwty/ya.zip/file

It works perfectly BUT unfortunately it does produce a mass of warnings

enter image description here

Also note for the record. With the "y.a. method" you do have to "change the line at the top of each file" each time someone on the team adds or deletes a file. For example:

 const { aa, bb, cc } = require('./common.js')

becomes

 const { aa, bb, cc, dd } = require('./common.js')

When a new file is added, they all need to be changed.

(Ideally, I was wondering if there is some sort of "macro like include" - the answer seems to be no.)

Here are the files to copy/paste:

ya % ls
aa.js       bb.js       cc.js       common.js
ya % tail -n +1 *js
==> aa.js <==
// aa.js
const { aa, bb, cc } = require('./common.js')

function sayOne() { console.log(1) }
function sayTwo() { console.log(2) }

console.log("test")
console.log("testB")
bb.sayOne()
console.log("testC")
cc.sayOne()

module.exports = { sayOne, sayTwo }
==> bb.js <==
// bb.js
const { aa, bb, cc } = require('./common.js')

function sayOne() { console.log(10) }
function sayTwo() { console.log(20) }

module.exports = { sayOne, sayTwo }

==> cc.js <==
// cc.js
const { aa, bb, cc } = require('./common.js')

function sayOne() { console.log(100) }
function sayTwo() { console.log(200) }

module.exports = { sayOne, sayTwo }

==> common.js <==
// common.js
const aa = require('./aa')
const bb = require('./bb')
const cc = require('./cc')
module.exports = { aa, bb, cc }

Simple method

https://www.mediafire.com/file/u3f6o1n7jf5pz95/usual.zip/file

If you tediously paste the N "const lines" at the top of every file (i.e. the whole point of this question is to avoid having to do that), as you can see it works fine with no warnings.

To copy/paste:

% ls
aa.js   bb.js   cc.js
% tail -n +1 *js              
==> aa.js <==
// aa.js

const aa = require('./aa')
const bb = require('./bb')
const cc = require('./cc')

function sayOne() { console.log(1) }
function sayTwo() { console.log(2) }

console.log("test")
console.log("testB")
bb.sayOne()
console.log("testC")
cc.sayOne()

exports.sayOne = sayOne
exports.sayTwo = sayTwo
==> bb.js <==
// bb.js

const aa = require('./aa')
const bb = require('./bb')
const cc = require('./cc')

function sayOne() { console.log(10) }
function sayTwo() { console.log(20) }

exports.sayOne = sayOne
exports.sayTwo = sayTwo

==> cc.js <==
// cc.js

const aa = require('./aa')
const bb = require('./bb')
const cc = require('./cc')

function sayOne() { console.log(100) }
function sayTwo() { console.log(200) }

exports.sayOne = sayOne
exports.sayTwo = sayTwo

As I say, I was basically wondering if there is some sort of "macro like include" in node.js - the answer seems to be no sadly!


Solution

  • Use an aggregator file and then import from there. For example, let's create a collection of files we need imported "everywhere":

    first, a.js exporting a function

    function aFunction() {
      return `a`;
    }
    
    module.exports = { aFunction };
    

    then, b.js exporting a normal const

    const B_CONST = `b`;
    
    module.exports = { B_CONST };
    

    then, c.js exporting a symbol

    const cSymbol = Symbol(`c`);
    
    module.exports = { cSymbol };
    

    And finally a d.js that exports a class

    class D {
      constructor() {
        this.d = `d`;
      }
    }
    
    module.exports = { D };
    

    We can aggregate those in an imports.js that re-export them as a single collection:

    const a = require("./a.js");
    const b = require("./b.js");
    const c = require("./c.js");
    const d = require("./d.js");
    
    module.exports = { a, b, c, d };
    

    Which we can now import in any file that needs it. Let's create an index.js:

    const { a, b, c, d } = require("./imports.js");
    
    console.log(a.aFunction);
    console.log(b.B_CONST);
    console.log(c.cSymbol);
    console.log(d.D);
    

    And then let's run that:

    $node index.js
    [Function: aFunction]
    b
    Symbol(c)
    [class D]
    

    And if you want to skip the namespace and instead directly export a single specific thing, then just do that, and then have the aggregator export it as part of the collection too.

    For instance, let's add an e.js that directly exports just a function, rather than wrapping it in its own namespace:

    function verifyData() {};
    module.exports = verifyData;
    

    Cool. We simply update our imports.js:

    ...
    const verifyData = require("e.js");
    module.exports = { a, b, c, d, verifyData };
    

    As well as our index.js:

    const {a, b, c, d, verifyData } = require("./imports.js");
    ...
    console.log(verifyData);
    

    And we're done:

    $node index.js
    [Function: aFunction]
    b
    Symbol(c)
    [class D]
    [Function: verifyData]