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');
Related
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');
I'm defining a package, PackageA, that has a function (parseJson) that takes in a file path to a json file to parse. In another package, PackageB, I want to be able to call PackageA using a file I specify with a local path from PackageB. For example, if file.json is in the same directory as packageB, I'd like to be able to call PackageA.parseJson('./file.json'), without any extra code in PackageB. How would I do this? It seems that require requires a path from PackageA to the file, which is not what I want.
Edit: Currently, parseJson looks something like this:
public parseJson(filepath) {
let j = require(filepath);
console.log(j);
}
and PackageB is calling it like this:
let a = new PackageA();
a.parseJson("./file.json");
file.json is in the same directory as PackageB.
CommonJS modules have __dirname variable in their scope, containing a path to directory they reside in.
To get absolute path to RELATIVE_PATH use join(__dirname, RELATIVE_PATH) (join from path module).
example:
// PackageB .js file
const Path = require('path')
const PackageA = require(/* PackageA name or path */)
const PackageB_jsonPathRelative = /* relative path to json file */
// __dirname is directory that contains PackageB .js file
const PackageB_jsonPathAbsolute = Path.join(__dirname, PackageB_jsonPathRelative)
PackageA.parseJson(PackageB_jsonPathAbsolute)
UPDATED
If you can't change PackageB, but you know exactly how PackageA.parseJson is called by PackageB (e.g. directly, or through wrappers, but with known depth), then you can get path to PackageB from stack-trace.
example:
// PackageA .js file
// `npm install stack-trace#0.0.10` if you have `ERR_REQUIRE_ESM` error
const StackTrace = require('stack-trace')
const Path = require('path')
const callerFilename = (skip=0) => StackTrace.get(callerFilename)[skip + 1].getFileName()
module.exports.parseJson = (caller_jsonPathRelative) => {
// we want direct caller of `parseJson` so `skip=0`
// adjust `skip` parameter if caller chain changes
const callerDir = Path.dirname(callerFilename())
// absolute path to json file, from relative to caller file
const jsonPath = Path.join(callerDir, caller_jsonPathRelative)
console.log(jsonPath)
console.log(JSON.parse(require('fs').readFileSync(jsonPath)))
}
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.
In my index.js file, I have const config = require('config'); written as one of the first lines.
And I have a file in my project folder called config.js
But I keep having my console tell my that it Cannot find module 'config'
My config file is this basically:
module.exports = {
'secretKey': 'mySecretCode12232',
'mongoUrl' : 'mongodb://localhost:27017/test'
};
This doesn't make any sense it should be working.
const config = require( path.join(__dirname, 'config'+'.js' ) );
I also have own function which loads atomaticaly from specified subdirectory at it's definition, it saves a lot of time.
When you don't provide any path selector in the require statement (eg. require('./config')), your code will search for the package named config and fail as it cannot find this specific one, as require will assume that it was the package name that was provided (and will start searching e.g. in your node_modules etc. - search path for it is not a trivial topic :) ).
If you want to require the module from another file, you have to provide a correct path to it, so assuming your config.js resides in the same catalog as your other file, the correct statement would be:
const config = require('./config'); // Extension can be omitted
I am using Browserify to compile a large Node.js application into a single file (using options --bare and --ignore-missing [to avoid troubles with lib-cov in Express]). I have some code to dynamically load modules based on what is available in a directory:
var fs = require('fs'),
path = require('path');
fs.readdirSync(__dirname).forEach(function (file) {
if (file !== 'index.js' && fs.statSync(path.join(__dirname, file)).isFile()) {
module.exports[file.substring(0, file.length-3)] = require(path.join(__dirname, file));
}
});
I'm getting strange errors in my application where aribtrary text files are being loaded from the directory my compiled file is loaded in. I think it's because paths are no longer set correctly, and because Browserify won't be able to require() the correct files that are dynamically loaded like this.
Short of making a static index.js file, is there a preferred method of dynamically requiring a directory of modules that is out-of-the-box compatible with Browserify?
This plugin allows to require Glob patterns: require-globify
Then, with a little hack you can add all the files on compilation and not executing them:
// Hack to compile Glob files. Don´t call this function!
function ಠ_ಠ() {
require('views/**/*.js', { glob: true })
}
And, for example, you could require and execute a specific file when you need it :D
var homePage = require('views/'+currentView)
Browserify does not support dynamic requires - see GH issue 377.
The only method for dynamically requiring a directory I am aware of: a build step to list the directory files and write the "static" index.js file.
There's also the bulkify transform, as documented here:
https://github.com/chrisdavies/tech-thoughts/blob/master/browserify-include-directory.md
Basically, you can do this in your app.js or whatever:
var bulk = require('bulk-require');
// Require all of the scripts in the controllers directory
bulk(__dirname, ['controllers/**/*.js']);
And my gulpfile has something like this in it:
gulp.task('js', function () {
return gulp.src('./src/js/init.js')
.pipe(browserify({
transform: ['bulkify']
}))
.pipe(rename('app.js'))
.pipe(uglify())
.pipe(gulp.dest('./dest/js'));
});