Reputation: 68
I'm making a simple module require script (running in "sloppy" mode) to make requiring modules with regular NodeJS simpler. Here's my current code, and I'll tell you the problem I'm having after this:
const util = require('./util.js')
const path = require('path')
const fs = require('fs')
module.exports = function (...requirements) {
let modulel = {}
modulel.requireAll = function () {
requirements.forEach((requirement) => {
if (util.getType(requirement) === 'String') {
let pr = requirement;
if (fs.existsSync(path.join(__dirname, pr))) { /// Always returns false
let pname = path.basename(pr);
this[pname] = require(path.join(__dirname, pr)); /// Always throws an error.
}
else {
let pname = requirement.replace(/[^A-Za-z0-9$_]/g,'').replace('.','').replace('/','').replace('js','');
this[pname] = require(pr);
}
}
})
}
if (!(requirements === null || requirements === undefined)) modulel.requireAll();
return module
}
This should be the usage
require('simplyrequire')('express', './util.js')
const app = express();
const bar = util.foo();
So, how would I fix this error?
Error: Cannot find module 'C:\Users\*****\OneDrive\Documents\requireall\express'
Require stack:
- C:\Users\*****\OneDrive\Documents\requireall\index.js
- C:\Users\*****\OneDrive\Documents\requireall\test\test.js
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at C:\Users\*****\OneDrive\Documents\requireall\index.js:16:20
at Array.forEach (<anonymous>)
at Object.modulel.requireAll (C:\Users\*****\OneDrive\Documents\requireall\index.js:10:16)
at module.exports (C:\Users\*****\OneDrive\Documents\requireall\index.js:27:70)
at Object.<anonymous> (C:\Users\*****\OneDrive\Documents\requireall\test\test.js:1:37)
at Module._compile (node:internal/modules/cjs/loader:1101:14) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'C:\\Users\\*****\\OneDrive\\Documents\\requireall\\index.js',
'C:\\Users\\*****\\OneDrive\\Documents\\requireall\\test\\test.js'
]
}
Thats what happens when I replace (fs.existsSync) with (!fs.existsSync) to test path joining with a relative path and the executed script's directory.
But how would I get if the file exists or not in terms of the executed script's directory? Am I doing this right and it will work if I flip the ! back to a regular if true statement? Because it still seems like that won't work, and I'm still really low on confidence about this entire code being deprecated in the future.
Any help? Thanks.
Upvotes: 0
Views: 1194
Reputation: 47672
I'm going to ignore the different problems in the code you show and just focus on the main question, which looks interesting to me: How to get the directory path of the script that required my module in Node.js?
There are different approaches, but the simplest solution without external dependencies is using the V8 stack trace API to find out the file that contains the code that called a function, and then get the directory part out of it.
So you could have in your simplyrequire.js
something like this:
// simplyrequire.js
const { dirname } = require('path');
module.exports = () => {
let callerPath;
const error = { };
Error.captureStackTrace(error);
Error.prepareStackTrace = (error, callSites) => {
callerPath = callSites[1]?.getFileName();
};
void error.stack;
delete Error.prepareStackTrace;
if (callerPath != null) {
const dir = dirname(callerPath);
console.log('Called from a file in directory %s', dir);
}
};
Then, when you call in another file
// main.js
require('simplyrequire')();
You should see in the log the path of the directory that contains main.js.
Again, there are other problems in your code that you will need to solve before you can achieve what you want, but this should give you a start.
Upvotes: 1
Reputation: 396
require.main.path gives the path of the script that first was passed as an option to node
Upvotes: 1