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?
https://www.mediafire.com/file/t81fppv2x6wnwty/ya.zip/file
It works perfectly BUT unfortunately it does produce a mass of warnings
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 }
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!
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]