"." not being parsed as part of a require() Node.js - javascript

I've been working on a project and ran into an issue when I was reorganizing my files. The "." on my requires are not being parsed.
When I run my program I get a
Error: Cannot find module './src/map/createMap.js'
Here is my code:
server.js (main file):
process.chdir(__dirname);
//Completely unrelated code...
const gameConsole = require('./src/backend/console.js');
gameConsole.start();
console.js:
const {createMap} = require('./src/map/createMap.js'); << Error thrown here
const Server = require('./server.js').Server; << Error thrown here if I use path.resolve()
I've tried using path.resolve(), and that works fine. When I log process.cwd() it has the path of my root directory (the one with server.js). I am considering storing the paths as global variables. Thanks for your help.
EDITS:
Sample of file structure:
(root)
|_server.js
|_src
|_backend
| |_console.js
|_map
|_createMap.js
Here is createMap.js, on my git repo: https://github.com/ArkinSolomon/zombie-fight/blob/master/src/map/createMap.js

From the code you've linked, the path to ./src/map/createMap.js in console.js is wrong.
The correct path would be
../map/createMap.js
Go up 1 folder ../ then you've access to map folder
And for server in console.js, the path would be:
const { Server } = require('../../server.js')
Go up 2 folder ../../ as console.js is 2 folders deep relative to server.js

What about to use "../map/createMap.js"?

Related

Error: Cannot find module './src/handlers/buttons.js' after migrating all files to a ./src folder [duplicate]

Let's say I have this directory structure
/Project
/node_modules
/SomeModule
bar.js
/config
/file.json
foo.js
-
foo.js:
require('bar');
-
bar.js:
fs.readdir('./config'); // returns ['file.json']
var file = require('../../../config/file.json');
Is it right that the readdir works from the file is being included (foo.js) and require works from the file it's been called (bar.js)?
Or am I missing something?
Thank you
As Dan D. expressed, fs.readdir uses process.cwd() as start point, while require() uses __dirname. If you want, you can always resolve from one path to another, getting an absolute path both would interpret the same way, like so:
var path = require('path');
route = path.resolve(process.cwd(), route);
That way, if using __dirname as start point it will ignore process.cwd(), else it will use it to generate the full path.
For example, assume process.cwd() is /home/usr/node/:
if route is ./directory, it will become /home/usr/node/directory
if route is /home/usr/node/directory, it will be left as is
I hope it works for you :D

Initialize firebase config with .env file? [duplicate]

I have .env file at root folder file
NODE_ENV=development
NODE_HOST=localhost
NODE_PORT=4000
NODE_HTTPS=false
DB_HOST=localhost
DB_USERNAME=user
DB_PASSWORD=user
And server.js file in the root/app/config/server.js folder.
The first line of server.js file is
require('dotenv').config();
I also tried following:
require('dotenv').config({path: '../.env'});
require('dotenv').config({path: '../../.env'});
However, my env variable are not loaded when I run the server.js file
from command prompt
node root/app/config/server.js
If I use the visual studio and press F5, it loads!!
I'm not sure what I'm doing wrong, what I'm missing.
Any suggestion is highly appreciate. Thanks.
How about use require('dotenv').config({path:__dirname+'/./../../.env'}) ?
Your problem seems to be the execution path.
This solved my issues in Node v8.14.1:
const path = require('path')
require('dotenv').config({ path: path.resolve(__dirname, '../.env') })
Simply doing require('dotenv').config({path:__dirname+'/./../../.env'}) resulted in a location that resolved as /some/path/to/env/./../../.env
Here is a single-line solution:
require('dotenv').config({ path: require('find-config')('.env') })
This will recurse parent directories until it finds a .env file to use.
You can also alternatively use this module called ckey inspired from one-liner above.
.env file from main directory.
# dotenv sample content
USER=sample#gmail.com
PASSWORD=iampassword123
API_KEY=1234567890
some js file from sub-directory
const ck = require('ckey');
const userName = ck.USER; // sample#gmail.com
const password = ck.PASSWORD; // iampassword123
const apiKey = ck.API_KEY; // 1234567890
If you are invoking dotenv from a nested file, and your .env file is at the project root, the way you want to connect the dots is via the following:
require('dotenv').config({path:'relative/path/to/your/.env'})
One of the comments in #DavidP's answer notes logging the output of dotenv.config with
console.log(require("dotenv").config())
This will output a log of the config and display errors. In my case it indicated the config method was referencing the current directory instead of the
parent directory which contained my .env file. I was able to reference that with the following
require('dotenv').config({path: '../.env'})
I've had this problem and it turned out that REACT only loads variables prefixed with REACT_APP_
VueJs can have a similar issue as it expects variables to be prefixed with: VUE_APP_
In the remote case that you arrive till this point, my issue was quite dumber:
I wrongly named my env variables with colon ":" instead of equals "=". Rookie mistake but the resulting behavior was not loading the misspelled variables assignment.
# dotenv sample content
# correct assignment
USER=sample#gmail.com
# wrong assignment (will not load env var)
USER : sample#gmail.com
Be sure to load .env at the beginning of the entry file (e.g. index.js or server.js). Sometimes, the order of execution loads the environment variables after the services are initiated. And, by using __dirname, it can easily point to the file required relative to the current file.
Here my project structure is like this.
.
├─ src
│ └─ index.ts
└─ .env
// index.ts
import dotenv from 'dotenv';
import path from 'path';
dotenv.config({path: path.join(__dirname, '..', '.env')});
...
This solved the issue for me:
const path = require('path');
require('dotenv').config({
path: path.resolve('config.env'),
});
Try this:
const dotenv = require('dotenv');
dotenv.config({ path: process.cwd() + '/config/config.env' });
worked for me idk how??
You can first debug by using console.log(require('dotenv').config()).
In my scenario, my .env file is in root directory and I need to use it in a nested directory. The result gives me { parsed: { DATABASE_URL: 'mongodb://localhost/vidly', PORT: '8080' } }. So I simply parse the result and store it in a variable const dotenv = require('dotenv').config().parsed;. Then access my DATABASE_URL like a JS object: dotenv.DATABASE_URL
It took me a few head scratches, and the tip to log the output of the require statement to console was really helpful. console.log(require('dotenv').config());
Turns out I was running my app from my user/ directory with nodemon application_name/. and that was making dotenv look for the .env file in my home dir instead of the app's. I was lazy by skipping one cd and that cost me a few minutes.
const path = require('path');
const dotenv = require('dotenv');
dotenv.config({ path: path.resolve(__dirname, '../config.env') })
In my case .env was read fine, but not .env.local.
Updating package.json to name .env into .env.local ( cp ./.env.local .env) solved the problem:
"myscript": "cp ./.env.local .env && node ./scripts/myscript.js"
if config.env file and index.js file both present in the same directory:
then, file: index.js
const path = require('path');
// Set port from environment variables
dotenv.config({path: 'config.env'})
const PORT = process.env.PORT || 8080
file: config.env:
PORT = 4000
One time I have got the same problem. Dotenv did not load .env file. I tried to fix this problem with a path config, to put .env file in a root folder, to put .env in the folder where the file is running and nothing helps me. Then I just trashed Node_modules folder, reinstall all dependencies and it works correctly
You can need the path of the .env file relative to the current working directory from where the application was launched.
You can create this path like this:
const path = require('path')
require('dotenv').config({path: path.relative(process.cwd(), path.join(__dirname,'.env'))});
process.cwd() returns the absolute path of the working directory.
__dirname returns the absolute path of the application.
path.join() adds the path of the .env-file to the path of the application. so if your .env file is nested deeper, just add the folders (e.g. path.join(__dirname, 'config', 'secret','.env'))
path.relative() creates the relative path.
I'am using:
import findUp from 'find-up';
dotenv.config({ path: findUp.sync('.env') });
I found an option debug: true to be sent in the config which showed me the following:
[dotenv][DEBUG] "PORT" is already defined in `process.env` and was NOT overwritten
I added overwrite: true and got it working:
[dotenv][DEBUG] "PORT" is already defined in `process.env` and WAS overwritten
I know I might be too late answering, but decided to share my findings after hours of checking the documentation.
Typescript.
if you are trying to resolve __dirname and you are compiling your source folder in another folder, make sure that you edit __dirname. in my case i am compiling ts in dist folder and env files are not located in dist folder, but in the root folder. so you should delete /dist from __dirname. To debug it, you can call error() function which returns error if there is problem with reading env file.
require('dotenv').config({
path: __dirname.replace('\dist','') + `${process.env.NODE_ENV}.env`
}); # To debug .error()
another thing, when you set env variables make sure that following:
no space between variable and (&&) as following
"scripts": {
"build": "npx tsc",
"start": "set NODE_ENV=production&& node dist/index.js",
},
The fastest fix here, just into seconds, add the variables to the platform you are using in my case render.com
What worked for me using Playwright / typescript:
1 create file and place at the root of the project: global-setup.ts
add inside:
async function globalSetup() {
// Configure ENV variables
require('dotenv').config()
}
export default globalSetup
2 Then use this file into playwright.config.ts
as: globalSetup: require.resolve('./global-setup'),
In this way, global conf is created, and pickup in every single test.
Use only absolute path if you are using some other tool(installed globally) to call your config file somewhere ...
require('dotenv').config({
path: '/path/to/my/project/.env',
});
One silly mistake I did was i used colon ":" in place of "="
I used below
USER:root
But it should be
USER=root
If nothing helps put your .env outside the src folder if you have folder structure like
-src/
- index.js
- env.js (where you call dotenv.config)
// you may call dotenv.config anywhere but entry point is best.
.env (file outside the src folder)
My failer was the path keyword . should be the P not capital Letter . that was so funny

dotenv file is not loading environment variables

I have .env file at root folder file
NODE_ENV=development
NODE_HOST=localhost
NODE_PORT=4000
NODE_HTTPS=false
DB_HOST=localhost
DB_USERNAME=user
DB_PASSWORD=user
And server.js file in the root/app/config/server.js folder.
The first line of server.js file is
require('dotenv').config();
I also tried following:
require('dotenv').config({path: '../.env'});
require('dotenv').config({path: '../../.env'});
However, my env variable are not loaded when I run the server.js file
from command prompt
node root/app/config/server.js
If I use the visual studio and press F5, it loads!!
I'm not sure what I'm doing wrong, what I'm missing.
Any suggestion is highly appreciate. Thanks.
How about use require('dotenv').config({path:__dirname+'/./../../.env'}) ?
Your problem seems to be the execution path.
This solved my issues in Node v8.14.1:
const path = require('path')
require('dotenv').config({ path: path.resolve(__dirname, '../.env') })
Simply doing require('dotenv').config({path:__dirname+'/./../../.env'}) resulted in a location that resolved as /some/path/to/env/./../../.env
Here is a single-line solution:
require('dotenv').config({ path: require('find-config')('.env') })
This will recurse parent directories until it finds a .env file to use.
You can also alternatively use this module called ckey inspired from one-liner above.
.env file from main directory.
# dotenv sample content
USER=sample#gmail.com
PASSWORD=iampassword123
API_KEY=1234567890
some js file from sub-directory
const ck = require('ckey');
const userName = ck.USER; // sample#gmail.com
const password = ck.PASSWORD; // iampassword123
const apiKey = ck.API_KEY; // 1234567890
If you are invoking dotenv from a nested file, and your .env file is at the project root, the way you want to connect the dots is via the following:
require('dotenv').config({path:'relative/path/to/your/.env'})
One of the comments in #DavidP's answer notes logging the output of dotenv.config with
console.log(require("dotenv").config())
This will output a log of the config and display errors. In my case it indicated the config method was referencing the current directory instead of the
parent directory which contained my .env file. I was able to reference that with the following
require('dotenv').config({path: '../.env'})
I've had this problem and it turned out that REACT only loads variables prefixed with REACT_APP_
VueJs can have a similar issue as it expects variables to be prefixed with: VUE_APP_
In the remote case that you arrive till this point, my issue was quite dumber:
I wrongly named my env variables with colon ":" instead of equals "=". Rookie mistake but the resulting behavior was not loading the misspelled variables assignment.
# dotenv sample content
# correct assignment
USER=sample#gmail.com
# wrong assignment (will not load env var)
USER : sample#gmail.com
This solved the issue for me:
const path = require('path');
require('dotenv').config({
path: path.resolve('config.env'),
});
Be sure to load .env at the beginning of the entry file (e.g. index.js or server.js). Sometimes, the order of execution loads the environment variables after the services are initiated. And, by using __dirname, it can easily point to the file required relative to the current file.
Here my project structure is like this.
.
├─ src
│ └─ index.ts
└─ .env
// index.ts
import dotenv from 'dotenv';
import path from 'path';
dotenv.config({path: path.join(__dirname, '..', '.env')});
...
Try this:
const dotenv = require('dotenv');
dotenv.config({ path: process.cwd() + '/config/config.env' });
worked for me idk how??
You can first debug by using console.log(require('dotenv').config()).
In my scenario, my .env file is in root directory and I need to use it in a nested directory. The result gives me { parsed: { DATABASE_URL: 'mongodb://localhost/vidly', PORT: '8080' } }. So I simply parse the result and store it in a variable const dotenv = require('dotenv').config().parsed;. Then access my DATABASE_URL like a JS object: dotenv.DATABASE_URL
It took me a few head scratches, and the tip to log the output of the require statement to console was really helpful. console.log(require('dotenv').config());
Turns out I was running my app from my user/ directory with nodemon application_name/. and that was making dotenv look for the .env file in my home dir instead of the app's. I was lazy by skipping one cd and that cost me a few minutes.
const path = require('path');
const dotenv = require('dotenv');
dotenv.config({ path: path.resolve(__dirname, '../config.env') })
In my case .env was read fine, but not .env.local.
Updating package.json to name .env into .env.local ( cp ./.env.local .env) solved the problem:
"myscript": "cp ./.env.local .env && node ./scripts/myscript.js"
if config.env file and index.js file both present in the same directory:
then, file: index.js
const path = require('path');
// Set port from environment variables
dotenv.config({path: 'config.env'})
const PORT = process.env.PORT || 8080
file: config.env:
PORT = 4000
One time I have got the same problem. Dotenv did not load .env file. I tried to fix this problem with a path config, to put .env file in a root folder, to put .env in the folder where the file is running and nothing helps me. Then I just trashed Node_modules folder, reinstall all dependencies and it works correctly
You can need the path of the .env file relative to the current working directory from where the application was launched.
You can create this path like this:
const path = require('path')
require('dotenv').config({path: path.relative(process.cwd(), path.join(__dirname,'.env'))});
process.cwd() returns the absolute path of the working directory.
__dirname returns the absolute path of the application.
path.join() adds the path of the .env-file to the path of the application. so if your .env file is nested deeper, just add the folders (e.g. path.join(__dirname, 'config', 'secret','.env'))
path.relative() creates the relative path.
I'am using:
import findUp from 'find-up';
dotenv.config({ path: findUp.sync('.env') });
I found an option debug: true to be sent in the config which showed me the following:
[dotenv][DEBUG] "PORT" is already defined in `process.env` and was NOT overwritten
I added overwrite: true and got it working:
[dotenv][DEBUG] "PORT" is already defined in `process.env` and WAS overwritten
I know I might be too late answering, but decided to share my findings after hours of checking the documentation.
Typescript.
if you are trying to resolve __dirname and you are compiling your source folder in another folder, make sure that you edit __dirname. in my case i am compiling ts in dist folder and env files are not located in dist folder, but in the root folder. so you should delete /dist from __dirname. To debug it, you can call error() function which returns error if there is problem with reading env file.
require('dotenv').config({
path: __dirname.replace('\dist','') + `${process.env.NODE_ENV}.env`
}); # To debug .error()
another thing, when you set env variables make sure that following:
no space between variable and (&&) as following
"scripts": {
"build": "npx tsc",
"start": "set NODE_ENV=production&& node dist/index.js",
},
The fastest fix here, just into seconds, add the variables to the platform you are using in my case render.com
What worked for me using Playwright / typescript:
1 create file and place at the root of the project: global-setup.ts
add inside:
async function globalSetup() {
// Configure ENV variables
require('dotenv').config()
}
export default globalSetup
2 Then use this file into playwright.config.ts
as: globalSetup: require.resolve('./global-setup'),
In this way, global conf is created, and pickup in every single test.
Use only absolute path if you are using some other tool(installed globally) to call your config file somewhere ...
require('dotenv').config({
path: '/path/to/my/project/.env',
});
One silly mistake I did was i used colon ":" in place of "="
I used below
USER:root
But it should be
USER=root
If nothing helps put your .env outside the src folder if you have folder structure like
-src/
- index.js
- env.js (where you call dotenv.config)
// you may call dotenv.config anywhere but entry point is best.
.env (file outside the src folder)
My failer was the path keyword . should be the P not capital Letter . that was so funny

Node requiring directory rather than specific file

Are these two statements equivalent?
const deviceModule = require('..').device;
const deviceModule = require('../device');
I thought require needed a module (with our without path) as the parameter. How is it that a directory can be provided and what does the .device do?
Thanks to anyone who can help me understand node.js and javascript better.
require('..').device requires index.js from the parent directory, and then gets device from that file.
So if you had the following structure:
- index.js
- /foo
- - bar.js
With index.js having the following:
module.exports = {
device: "baz"
};
Then require("..").device in bar.js would give you "baz".
Here is the specification for loading a directory:
LOAD_AS_DIRECTORY(X)
1. If X/package.json is a file,
a. Parse X/package.json, and look for "main" field.
b. let M = X + (json main field)
c. LOAD_AS_FILE(M)
2. If X/index.js is a file, load X/index.js as JavaScript text. STOP
3. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP
4. If X/index.node is a file, load X/index.node as binary addon. STOP
So in your example, it will:
look for package.json and get the main property, and then load that if it exists
If step 1 does not exist, it will load index.js if it exists
If step 2 does not exist, it will load index.json if it exists
If step 4 does not exist, it will load index.node if it exists
You can use module require-file-directory.
1- Helps to require all the files only with name. No need to give absolute path of files.
2- Multiple files at a time.

NodeJS cannot find custom module

I am trying to export a module to my routes file.
My file tree goes like
routes.js
app.js
controllers/users.js
posts.js
on my app.js I exported var route = require('./routes'); and that works.
now on my routes.js I tried to export require('./controllers');.
But it keeps telling me that it cannot find module controllers.
Doing this works:
require('./controllers/users')
But I am trying to follow expressjs sample initial projects format.
And it is bugging me because the example of expressjs shows: (express routes is a folder)
var routes = require('./routes');
and loads it like
app.get('/', routes.index);
with no error. and that ./routes is a folder. I am just following the same principle.
If you try to require a directory, it expects there to be an index.js file in that directory. Otherwise, you have to simply require individual files: require('./controllers/users'). Alternatively, you can create an index.js file in the controllers directory and add the following:
module.exports.users = require('./users');
module.exports.posts = require('./posts');
and then import: var c = require('./controllers');. You can then use them via c.users and c.posts.
You have to understand how require() works.
In your case it fails to find a file named controller.js so it assumes it's a directory and then searches for index.js specifically. That is why it works in the express example.
For your usecase you can do something like this -
var controllerPath = __dirname + '/controllers';
fs.readdirSync(controllerPath).forEach(function(file) {
require(controllerPath + '/' + file);
});
From:
http://nodejs.org/api/modules.html
LOAD_AS_DIRECTORY(X)
If X/package.json is a file, a. Parse X/package.json, and look for "main" field. b. let M = X + (json main field) c.
LOAD_AS_FILE(M)
If X/index.js is a file, load X/index.js as JavaScript text. STOP
If X/index.node is a file, load X/index.node as binary addon. STOP
So, if a directory has an index.js, it will load that.
Now, look # expressjs
http://expressjs.com/guide.html
create : myapp/routes
create : myapp/routes/index.js
Taking some time to really read how modules work is time well spent. Read here

Categories

Resources