Reading enviromental variable problem in node.js - javascript

Here is my excel.js:
let test = async () => {
console.log(process.env.DATABASE_HOST);
.......
}
test();
Here is my package.json fragment:
"scripts": {
.............
"excel": "cross-env NODE_ENV=development node ./server/excel.js",
"test": "react-scripts test"
}
My .env.development is stored in the application root folder.
Here is my .env.development:
DATABASE_HOST=dbServer
When I execute the following command line in the application root folder:
npm run excel
It should return "dbServer", unfortunately, it returns undefined.
How can I fix it?

Install dotenv package, and require it require('dotenv').config()

Related

how can we use environment variables properly with env.config.js file in react.js(i got undefined after reload)

When I'm running project with npm run start it's working fine after reloading my env.config.js giving variables undefined
I have got a problem with env-config.js file. I implemented like this below
App.js file
import "./App.css";
function App() {
const Query = window._env_.REACT_APP_QUERY;
console.log(Query);
return (
<div className="App">
<h1>hello world</h1>
</div>
);
}
export default App;
this is env-config.js file
window._env_ = {
REACT_APP_GRANT: "grate",
REACT_APP_CLIENT: "simple",
};
finally scripts in package-json file
"scripts": {
"start": "chmod +x .\\env.sh && cp env-config.js .\\public/ && .\\env.sh && react-scripts start",
"dev": "chmod +x ./env.sh && ./env.sh && cp env-config.js ./public/ && react-scripts start",
"test": "react-scripts test",
"eject": "react-scripts eject",
"build": "react-scripts build"
},
I don't know about this file it was mentioned in scripts then I copied it here
env.sh
#!/bin/bash
# Recreate config file
rm -rf ./env-config.js
touch ./env-config.js
# Add assignment
echo "window._env_ = {" >> ./env-config.js
# Read each line in .env file
# Each line represents key=value pairs
while read -r line || [[ -n "$line" ]];
do
# Split env variables by character `=`
if printf '%s\n' "$line" | grep -q -e '='; then
# tollerate = surrounded by blanks: ' = '
varname=$(printf '%s\n' "$line" | sed -E 's/^([a-zA-Z_-]+) *= *(.*)$/\1/')
varvalue=$(printf '%s\n' "$line" | sed -E 's/^([a-zA-Z_-]+) *= *(.*)$/\2/')
fi
# Read value of current variable if exists as Environment variable
value=$(printf '%s\n' "${!varname}")
# Otherwise use value from .env file
[[ -z $value ]] && value=${varvalue}
# Append configuration property to JS file
echo " $varname: \"$value\"," >> ./env-config.js
done < .env.local
echo "}" >> ./env-config.js
I'm running my project with git bash terminal with npm run start command
I don't want to use .env file for some varables because I'm unable to overide with docker build command
how can we get env-config.js variables without getting undefined after reload the project.
I'm not sure about env.sh file any more I couldn't understand what they coded earlier in that even don't know use of it
The comments in the script tell you what it is doing. It removes the env-config.js file, recreates it with the variables in .env file in the window._env_ variable. So, if you don't have a .env file, there will be no variables added to the window._env_ variable.
I suggest you remove the env.sh and use dotenv npm package: https://www.npmjs.com/package/dotenv
Install dotenv
npm i dotenv
Create .env file with the variables you want
REACT_APP_GRANT=grate
REACT_APP_CLIENT=simple
Use dotenv inside env-config.js file
import * as dotenv from "dotenv";
// dotenv reads the .env file and adds the variables in
// there to process.env
dotenv.config()
window._env_ = {
REACT_APP_GRANT: process.env.REACT_APP_GRANT,
REACT_APP_CLIENT: process.env.REACT_APP_CLIENT,
};
Success!
If you set a variable like this: REACT_APP_GRANT=newgrant npm run start, dotenv, by default, will not overwrite newgrant for the one in .env. I believe the same will work when setting the variable in docker command line if you use docker run --env REACT_APP_GRANT=newgrant myapp
EDIT:
Apparently, reactjs already uses dotenv, so you might not need to install it. All you need to do is create the .env file and add the REACT_APP_ prefix to your variable names, like you are already doing. Then you can access them via process.env.REACT_APP_MY_VAR, as I did in my example.
Read more at https://create-react-app.dev/docs/adding-custom-environment-variables/

Nodemon starts 2 instances of node when executed as a module in a javascript file

I am trying to execute a node application through nodemon. I have a index.js file as entry point of my application and a main.js file as:
var nodemon = require('nodemon');
/**
* some setup done
*/
nodemon({}).on('quit', ()=> {...});
with the config nodemon.json as:
{
"env": {
...
},
"execMap": {
"js": "node --inspect --max-old-space-size=4096"
},
"watch": [
"src/server",
"config",
"dist"
]
}
When i execute the main.js via npm script and run ps command in terminal, I am seeing 2 instances of my node application being run as:
12752 ttys001 0:02.53 /Users/testUser/.nvm/versions/node/v8.17.0/bin/node --inspect --max-old-space-size=4096 index.js
12777 ttys001 0:02.61 /Users/testUser/.nvm/versions/node/v8.17.0/bin/node --inspect --max-old-space-size=4096 --inspect-port=9230 /Users/testUser/projects/nodeProj/index.js
Also I am only able to attach node debugger on PORT 9230 not on 9229!
Why is such thing happening?

How to load config json as environment variable nodejs

I am a newbie to node js. I have different configs for different environments viz dev, prod etc. Currently while creating my app package I copy .json to config.json and then export config.json as config variable (global) and use it throughout the app.
config = require(__dirname + '/config/config');
(config.httpProxy && config.httpProxy.enabled);
I want to load specific env.json as part of environment variable (for dev dev.json's all keys are exported as global variable in app) instead of copying it into app's config.json, so that same app can be used in different env. How to do that.
PS: for application packaging support and dependency management I use gulp and npm.
Please help.
you can name your files like this:
config.development.json
config.production.json
config.test.json
Then load files as:
config = require(__dirname + '/config/config.' + process.env.NODE_ENV);
where process.env.NODE_ENV value can be development/production/test
you have to start your application as
NODE_ENV=development node app.js
for this to work.
I suggest you use this module called config it handles all your env config files.
https://www.npmjs.com/package/config
Just make a folder named config and makes files in it as :
1. development.json
2. qa.json
3. production.json
While starting server provide relevant environment as others mentioned.
Then you can use any property mentioned in your config files.
If you are running your project from your script then set NODE_ENV into your package.json file.
{
...
"scripts": {
"nodemon:server": "NODE_ENV=dev NODE_PATH=. nodemon --exec \"babel-node --stage 1\" server.js",
"prod:server": "NODE_ENV=prod NODE_PATH=. nodemon --exec \"babel-node --stage 1\" server.js"
},
"author": "'Shubham Batra'",
"license": "MIT",
....
}
"prod:server": "**NODE_ENV=prod** NODE_PATH=. nodemon --exec \"babel-node --stage 1\" server.js"
than use in config,js file e.g.
if (process.env.NODE_ENV === 'test' ) {
url = 'http://abc:3000';
dbUrl= 'xyz';
password = '***';
} else if (process.env.NODE_ENV === 'prod') {
url = 'http://def:3000';
...
}
export default {
conf: {
url,
dbUrl,
...
}
}
after that, you can import this config file anywhere in your project and use conf

Run a npm script from gulp task

How to run a npm script command from inside a gulp task?
package.json
"scripts":
{
"tsc": "tsc -w"
}
gulpfile.js
gulp.task('compile:app', function(){
return gulp.src('src/**/*.ts')
.pipe(/*npm run tsc*/)
.pipe(gulp.dest('./dist'))
.pipe(connect.reload());
});
I want to do this because running npm run tsc does not give me any error but if I use gulp-typescript to compile .ts then I get bunch of errors.
You can get the equivalent using gulp-typescript
var gulp = require('gulp');
var ts = require('gulp-typescript');
gulp.task('default', function () {
var tsProject = ts.createProject('tsconfig.json');
var result = tsProject.src().pipe(ts(tsProject));
return result.js.pipe(gulp.dest('release'));
});
gulp.task('watch', ['default'], function() {
gulp.watch('src/*.ts', ['default']);
});
Then on your package.json
"scripts": {
"gulp": "gulp",
"gulp-watch": "gulp watch"
}
Then run
npm run gulp-watch
Alternatively using shell
var gulp = require('gulp');
var shell = require('gulp-shell');
gulp.task('default', function () {
return gulp.src('src/**/*.ts')
.pipe(shell('npm run tsc'))
.pipe(gulp.dest('./dist'))
.pipe(connect.reload());
});
gulp-shell has been blacklisted you can see why here
Another alternative would be setting up webpack.
Wasted about 1 hour on this simple thing, looking for a ~complete answer, so adding another here:
If you question is only on typescript (tsc), see https://stackoverflow.com/a/36633318/984471
Else, see below for a generic answer.
The question title is generic, so a generic example is given below first, then the answer.
Generic example:
Install nodejs, if you haven't, preferably LTS version, from here: https://nodejs.org/
Install below:
npm install --save-dev gulp gulp-run
File package.json has below contents (other contents can be there):
{
"name": "myproject",
"scripts": {
"cmd1": "echo \"yay! cmd1 command is run.\" && exit 1",
}
}
Create a file gulpfile.js with below contents:
var gulp = require('gulp');
var run = require('gulp-run');
gulp.task('mywatchtask1', function () {
// watch for javascript file (*.js) changes, in current directory (./)
gulp.watch('./*.js', function () {
// run an npm command called `test`, when above js file changes
return run('npm run cmd1').exec();
// uncomment below, and comment above, if you have problems
// return run('echo Hello World').exec();
});
});
Run the task mywatchtask1 using gulp?
gulp mywatchtask1
Now, gulp is its watching for js file changes in the current directory
if any changes happen then the npm command cmd1 is run, it will print yay! cmd1 command is run. everytime the one of the js file changes.
For this question: as another example:
a) package.json will have
"tsc": "tsc -w",
instead of the below:
"cmd1": "echo \"yay! cmd1 command is run.\" && exit 1",
b) and, gulpfile.js will have:
return run('npm run tsc').exec();
instead of below:
return run('npm run cmd1').exec();
Hope that helps.
You can try to implement it using childprecess node package or
use https://www.npmjs.com/package/gulp-run
var run = require('gulp-run');
gulp.task('compile:app', function(){
return gulp.src(['src/**/*.js','src/**/*.map'])
.pipe(run('npm run tsc'))
.pipe(gulp.dest('./dist'))
.pipe(connect.reload());
});

how to execute es6 scripts from CLI

I have the latest NodeJS installed and for any JavaScript files, I can execute it with node myscript.js but recently I'm learning es6 and for some of the latest syntax, it just pop out some errors/exceptions while executing. I tried babel-cli, but didn't seem to work as it is for compile es6 to 5 not for command line execute.
1) To enable the support of ES6, use the --harmony flag:
node --harmony myscript.js
This will enable the available ES6 syntax in node. But notice it's currently a limited subset of the ES6 standard (see the compatibility table).
2) To have a complete compatibility, you have to use babel node.
Install #babel/node to get a babel-node executable which works exactly the same as Node.js's CLI, only it will compile ES6 code before running it.
babel-node myscript.js
For simple ES6 or even Typescript experimentation, maybe Deno could be considered nowadays. It supports newest ES (and TS) out of the box without needing any additional tooling.
#source1
https://dev.to/geekygeeky/get-started-with-es6-javascript-for-writing-nodejs-using-express-544h
#create dir /project1
mkdir /project1
cd /project1
#install babel etc
npm i #babel/cli #babel/core #babel/node #babel/preset-env --save-dev
npm i #babel/plugin-proposal-class-properties #babel/plugin-proposal-object-rest-spread --save-dev
npm i rimraf nodemon --save-dev
#initialize project1
#https://philna.sh/blog/2019/01/10/how-to-start-a-node-js-project/
npm init
#edit /project1/package.json
nano /project1/package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "rimraf dist && babel src --out-dir dist --copy-files",
"start": "node dist/app.js",
"start:dev": "nodemon --exec babel-node src/app.js"
},
#edit /project1/.babelrc
nano /project1/.babelrc
{ "presets": [
["#babel/env", {
"targets": {
"node": "current"
}
}]
],
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-proposal-object-rest-spread"
]
}
#install express
npm i express --save
#open a bash shell
#create /project1/src
mkdir src
cd src
#edit /project1/src/app.js
nano /project1/src/app.js
import express, { json } from 'express';
import items from './items';
const app = express();
app.use(json())
const PORT = process.env.PORT || 3000;
app.get('/', async (req, res) => {
res.json({ status: true, message: "Our node.js app works" })
});
app.get('/items', (req, res) => {
res.json({ status: true, message: "Fetched all items", data: items })
})
app.listen(PORT, () => console.log(`App listening at port ${PORT}`));
#edit /project1/src/items.js
nano items.js
const items = [
{
id: 1,
username: "John doe",
cartItems: ['football', 'ps5', 'cd-rom'],
},
{
id: 2,
username: "Jane doe",
cartItems: ['mobile phone', 'game pad'],
}
];
export default items;
#open another bash shell
#run server
cd /project1
npm run start:dev
#keep the server running
#check your app via browser
http://localhost:3000
http://localhost:3000/items

Categories