node.js can't find module from relative path - javascript

I have two simple files in node.js and want to export two classes from one file and import them in the other. I'm using:
module.exports = {TrigInter, Hilbert};
Now, if I call require, it only works with the absolute file path:
const lib = require("/Users/username/documents/atom/project_folder/lib.js");
and not with the relative file path:
const lib = require("./lib.js");
eventhough the two files are both located in the "project_folder". I'm pretty sure, I tried the exact same thing before and it worked with the relative path. I don't see what I'm doing wrong. What am I missing?

Absolute path is not best practice to use, instead you can use path join method like
const path = require('path');
let your_file_path = path.resolve(__dirname, '/lib.js');
https://www.digitalocean.com/community/tutorials/nodejs-how-to-use__dirname

Related

How can i get the multiple .dat files in particular path in protractor

var filepath =../project/e2e/*.dat,
By using this I am able to get one file at a time but I need to fetch multiple files.
Instead of using this path to get the file, is there any other way to get multiple .dat files in the same path?
It will be better if you can share more details, like how are you fetching the files.
Though try this
const path = require('path'); //at global level
let filepath = '../project/e2e/*.dat';
let absolutePath = path.resolve(__dirname, filepath); // This will resolve the absolute path

Resolve relative path relative to another path instead of current working directory

I have a Node.js module that looks like this:
module.exports = function()
{
// linked dependencies
this.dependency1 = 'dependency1/dependency1.exe';
this.dependency2 = 'dependency2/dependency2.exe';
this.dependency3 = 'dependency3/dependency3.exe';
}
I want developers to be able to easily edit the location of the dependencies relative to the module file itself. However, when using the module, the current working directory process.cwd() is usually not the same as the module directory, so those paths do not resolve correctly. path.resolve() only seems to work relative to the current working directory, and doesn't have any arguments to allow for a custom reference point/path.
I have been able to resolve the paths in the following way, but I find it ugly and cumbersome, and it should be easier than this:
this.ResolvePath = function(p)
{
var cwd = process.cwd();
process.chdir(path.dirname(module.filename));
var resolvedPath = path.resolve(p);
process.chdir(cwd);
return resolvedPath;
}
Is there a cleaner way to do this? I feel like path.relative() should hold the solution, but I can't find a way to make it work. Perhaps chaining together multiple path.relative()s could work, but I can't wrap my brain around how that would work right now.
why not just:
path.resolve(__dirname, p)
__dirname works a bit differently and returns the current modules path, which can then be joined easily with the relative path.

How to get current filename without path and extension with webpack?

I can get the relative file path with __filename, and sure I could hack it apart to get just the basename with some JS-fu, but I want to do this at compile-time.
DefinePlugin will let me inject some globals like I want, but AFAICT I can't have a "dynamic" global based on the current file.
So how can I do this?
e.g. given I am in the file assets/scripts/lib/components/bpm/RecordAttendancePopup.jsx, how can I get webpack to inject a constant like __basename that evaluates to "RecordAttendancePopup"?
Generic version
If you're using modules or any supported bundler, you can access the pre-existing import.meta.url and manually extract the filename:
const filename = import.meta.url // Get current path
.split(/[\\/]/).pop() // Get current filename
.replace(/\.[^.]+$/, ''); // Drop extension
or you can use a better parser (which may or may not work depending on your config)
const path = require('path');
const filename = path.parse(import.meta.url).name;
Webpack-specific version
This is what I use in my webpack.config.js:
const path = require('path');
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.DefinePlugin({
__filebasename: webpack.DefinePlugin.runtimeValue(
info => JSON.stringify(path.parse(info.module.resource).name)
)
})
]
};
and then I'll have the __filebasename variable available everywhere in my source. Works in Webpack 4 and 5.
I guess there is no other way than creating your own "DefinePlugin" based on https://github.com/webpack/webpack/blob/master/lib/DefinePlugin.js to get what you want.

How to dynamically resolve nodejs required module's path based on caller script's path?

I am kind of new to Javascript programming. Currently I am trying to write a test for Javascript files in existing codebase that contains other programming languages. The structure is like below.
src/js/path1/path2/path3/path4/path5/
Rectangle.jsx
Circle.jsx
test/js/path1/path2/path3/path4/path5/
RectangleTest.jsx
CircleTest.jsx
The content of RectangleTest.jsx is below
import Rectangle from './../../../../../../../src/js/path1/path2/path3/path4/path5/Rectangle';
describe('<Rectangle>', () => {
it('Should show content', () => {
assert.ok(true);
});
});
As you can see, I need to set the path as a very long relative path ./../../../../../../../src/js/path1/path2/path3/path4/path5. It will be very exhaustive for I prefer something like below.
import Rectangle from './Rectangle';
Since the path of the test file and the tested file is pretty similar, it should be possible to calculate the path to be resolved by the import.
Is there a way to do that?
I am using mocha for the testing framework. I uploaded the sample code to Github (link), so you can see it.
You can use the __dirname global node variable which contains the absolute path to the current file. However you have to use require() instead of import ... because import does not support dynamic paths.
if your absolute path only contains one test name you can get away with:
const path = require('path');
const retanglePath = path.join(__dirname.replace('/test/', '/src/'), 'Rectangle'));
const Rectangle = require(rectanglePath).default;
Note: the .default is for ES6 exports that are converted with babel.
Hope this helps.
Edit: Here is a solution that also works with other test folder names in the absolute path (replace the path relative for your needs):
const path = require('path');
const basePath = path.join(__dirname, '../../../../');
const srcPath = __dirname.replace(basePath + 'test', basePath + 'src');
const Rectangle = require(path.join(srcPath, 'Rectangle')).default;
After researching about how nodejs resolve module, it turns out that it's possible to override the require function behavior by overriding module module.
So I write a file called bootstrap.js that contains code below
let path = require('path');
const BASE_DIR = __dirname;
const SRC_DIR = path.resolve(BASE_DIR + '/../../src/js');
var Module = require('module');
Module.prototype.require = new Proxy(Module.prototype.require, {
apply(target, thisArg, argumentsList){
let name = argumentsList[0];
let isLocal = thisArg.filename.startsWith(BASE_DIR) &&
name.startsWith('./');
if (isLocal) {
let testFileDir = path.dirname(thisArg.filename)
let testPath = testFileDir.replace(BASE_DIR, '');
let srcPath = SRC_DIR + testPath;
let relativePath = path.relative(testFileDir, srcPath);
argumentsList[0] = relativePath + '/' + name;
}
return Reflect.apply(target, thisArg, argumentsList)
}
});
The structure now is like this
src/js/path1/path2/path3/path4/path5/
Rectangle.jsx
Circle.jsx
test/js/
bootstrap.js
path1/path2/path3/path4/path5/
RectangleTest.jsx
CircleTest.jsx
To execute the test, I use the statement below
nyc mocha --recursive \
--require test/js/bootstrap.js \
--compilers js:babel-core/register \
test/js/**/*.{js,jsx}
Using the code above, I can check the caller script and called module and see if the caller script resides in the test directory. If it does then, it will see if the module called by using relative path.
The advantage is that, we still can use import statement.
import Rectangle from './Rectangle';
describe('<Rectangle>', () => {
it('Should show content', () => {
assert.ok(true);
});
});
The downside is for now the test file cannot call relative path in the test directory. Relative path will now only resolve in source path. But it's good for now. I am wondering if we can check if a module is resolvable or not.
The updated source code can be read here.

my config.js file is not being recognized

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

Categories