Node.js relative require paths to executing script - javascript

How can I make require look in the relative path of the executing script (not whatever script has require'd the executing script)? Example:
index.js
require('lib/foo.js');
--
lib/foo.js
var barFunction = require('./bar.js').barFunction;
barFunction();
--
lib/bar.js
module.exports.barFunction = function(){
return true;
}
When you node index.js, foo.js looks for bar.js instead of lib/bar.js.
If foo.js is amended to require('lib/bar.js'), then node foo.js will stop working.
How can I set up require in a way that I can both node index.js and node lib/foo.js and have then both work?

You can use __dirname to get the absolute directory the currently executing script resides in. For example:
index.js:
require(__dirname + '/lib/foo.js');
lib/foo.js:
var barFunction = require(__dirname + '/bar.js').barFunction;
barFunction();

Related

How do I import variables from a file not located in the same folder [duplicate]

I have the following structure:
-- node_modules
-- websites
---- common
------- config.js
---- testing
------- test.js
Inside config I have some variables set, which are being exported using module.export.
I am trying to retrieve those variables when running node test.js from config.js using the following codes:
var configData = require('./common/config.js')
var configData = require('../common/config.js')
None of them work. What can I do to retrieve the data from the other folder?
var configData = require('./../common/config.js');
./ is testing/
./../ is websites/
./../common/ is websites/common/
./../common/config.js is websites/common/config.js
from test.js:
const configData = require('../common/config');
You can safely omit '.js'.
As documentation say:
File Modules
If the exact filename is not found, then Node.js will attempt to load the required filename with the added extensions: .js,
.json, and finally .node.
.js files are interpreted as JavaScript text files, and .json files
are parsed as JSON text files. .node files are interpreted as compiled
addon modules loaded with dlopen.
A required module prefixed with '/' is an absolute path to the file.
For example, require('/home/marco/foo.js') will load the file at
/home/marco/foo.js.
A required module prefixed with './' is relative to the file calling
require(). That is, circle.js must be in the same directory as foo.js
for require('./circle') to find it.
Without a leading '/', './', or '../' to indicate a file, the module
must either be a core module or is loaded from a node_modules folder.
If the given path does not exist, require() will throw an Error with
its code property set to 'MODULE_NOT_FOUND'.
More info about how require() work here.
const cheerio = require('../node_modules/cheerio');
const request = require('../node_modules/request-promise');
const vl = require('../node_modules/validator');
const crypto = require('crypto');
const fs = require('fs');

No such file or directory when exporting function from another file

src/test.js
module.exports.test = function() {
const { readFileSync } = require('fs');
console.log(readFileSync('test.txt', 'utf8').toString())
}
index.js
const { test } = require('./src/test.js');
test();
Which results in No such file or directory. Does module.exports or exports not work when requiring files in another directory?
When you do something like this:
readFileSync('test.txt', 'utf8')
that attempts to read test.txt from the current working directory. That current working directory is determined by how the main program got started and what the current working directory was when the program was launched. It will have nothing at all to do with the directory your src/test.js module is in.
So, if test.txt is inside the same directory as your src/test.js and you want to read it from there, then you need to manually build a path that references your module's directory. To do that, you can use __dirname which is a special variable set for each module that points to the directory the module is in.
In this case, you can do this:
const path = require('path');
module.exports.test = function() {
const { readFileSync } = require('fs');
console.log(readFileSync(path.join(__dirname, 'test.txt'), 'utf8').toString())
}
And, that will reliably read test.txt from your module's directory.

node.js require from parent folder

I have the following structure:
-- node_modules
-- websites
---- common
------- config.js
---- testing
------- test.js
Inside config I have some variables set, which are being exported using module.export.
I am trying to retrieve those variables when running node test.js from config.js using the following codes:
var configData = require('./common/config.js')
var configData = require('../common/config.js')
None of them work. What can I do to retrieve the data from the other folder?
var configData = require('./../common/config.js');
./ is testing/
./../ is websites/
./../common/ is websites/common/
./../common/config.js is websites/common/config.js
from test.js:
const configData = require('../common/config');
You can safely omit '.js'.
As documentation say:
File Modules
If the exact filename is not found, then Node.js will attempt to load the required filename with the added extensions: .js,
.json, and finally .node.
.js files are interpreted as JavaScript text files, and .json files
are parsed as JSON text files. .node files are interpreted as compiled
addon modules loaded with dlopen.
A required module prefixed with '/' is an absolute path to the file.
For example, require('/home/marco/foo.js') will load the file at
/home/marco/foo.js.
A required module prefixed with './' is relative to the file calling
require(). That is, circle.js must be in the same directory as foo.js
for require('./circle') to find it.
Without a leading '/', './', or '../' to indicate a file, the module
must either be a core module or is loaded from a node_modules folder.
If the given path does not exist, require() will throw an Error with
its code property set to 'MODULE_NOT_FOUND'.
More info about how require() work here.
const cheerio = require('../node_modules/cheerio');
const request = require('../node_modules/request-promise');
const vl = require('../node_modules/validator');
const crypto = require('crypto');
const fs = require('fs');

Referencing non-exportable file in node module

I am trying to reference an html document in a "self containing" module. The module is comprised of two files:
app_root/node_module/my_module/main.js
app_root/node_module/my_module/header.html
main.js contains:
module.exports.test = function() {
var doc = fs.readFileSync('./header.html');
console.log(doc);
}
when i run my program in app_root/program.js
require('my_module').test();
When i start my app, the current working directory is set to app_root. When it tries to read ./header.html it breaks because the paths aren't correct.
How would I find directory of the installed module without knowing anything about what is running it?
You can use __dirname to refer to the path of the current script.
So main.js would become:
module.exports.test = function() {
var doc = fs.readFileSync(__dirname + '/header.html');
console.log(doc);
}

Require a module relative to the original code

I have this directory structure:
project/
mymodule.js
test/
run.js
node_modules/
canvas/
I have code like so:
run.js
var Canvas = require(__dirname+"/../mymodule");
mymodule.js
if (typeof require==='function' && typeof module==='object'){
// when using mymodule with Node the 'canvas' module must be available
var canvas = require('canvas');
module.exports = canvas;
} else {
// code that works in a web browser, without Node
}
The result of node test/run.js is Error: Cannot find module 'canvas'.
How can I make it so that the require from mymodule knows to look relative to the original script? Or is that contrary to the way Node modules work? Must I move canvas (which is only used for testing on my end) out of the test directory?
When you don't put a path in the require statement, it assumes you're trying to load a module. If you want to load something in your code, be sure to include a relative or absolute path. In your case:
var canvas = require('./test/node_modules/canvas');
The other way to do this is to have your node_modules directory in root, and not web-accessible.
project/
mymodule.js
node_modules/
canvas/
test/
run.js
Then in your run.js or your mymodule.js you can require('canvas') as you'd expect.

Categories