How to use nodemon with .env files? - javascript

I am using an .env file to hold environment variables for the server. This works if I run the server with foreman start. But it doesn't work with nodemon.
I would like to use nodemon instead because it restarts automatically when you modify the server. How can I get nodemon to work with .env files?

Install dotenv npm i dotenv
Create .env file and your variables inside
Add the script to execute
"dev": "nodemon -r dotenv/config ./app/index.js " or
"start": "node -r dotenv/config ./app/index.js "
Run the app using npm run dev or npm run start

I have a production Procfile with:
web: node web.js
So I have created a Procfile_dev file with:
web: nodemon web.js
And when I am at development environment I run:
$ foreman start -f Procfile_dev
It works like a charm and doesn't affect production.

You can get nodemon to directly use the .env with the following command
$: env $(cat .env) nodemon app.js
Be aware that you'll have to restart it if you make changes to .env and it won't like it if there are any spaces in your .env file.

With recent versions of Node (since io.js 1.6), you can pass it the -r flag to require a module on start. This lets you directly load .env by using nodemon's --exec:
nodemon --exec 'node -r dotenv/config'
This requires the npm package dotenv to be installed.

Place your local configuration variables in the .env file and run foreman along with nodemon using the following command
$ foreman run nodemon web.js

This works pretty well for me so far,
nodemon -w . -w .env index.js
How it works:
"-w ." tells nodemon to watch the files in the current directory
"-w .env" tells nodemon to watch the .env file
"index.js" is just the file to run when changes occur (could be anything)

"scripts": {
"start": "node -r dotenv/config src/server.js dotenv_config_path=dev.env dotenv_config_debug=true",
"start:dev": "nodemon --exec \"npm start\""
}

In my case the .env file is used for development and not deployment. So I wanted my code to be decoupled from the .env file. Ideally I didn't want to import 'dotenv/config' anywhere in my code. This is my solution:
My nodemon config:
{
"watch": [
"src",
".env"
],
"ext": ".ts",
"exec": "ts-node -r dotenv/config ./src/index.ts"
}
My NPM script:
"start:dev": "nodemon"
In this solution ts-node requires dotenv, which sets up the environment variables before the main app starts. This means that nowhere in my code do I need a import 'dotenv/config'. dotenv can become a dev dependency, and this also prevents dotenv to be loaded at all once the code is deployed.

Thread necromancy!
Use grunt-env to load environmental variables from your heroku config.

In Three steps
Creating the file on root folder > .env
# .env ======
PORT=5000
WHO_AM_I="Who Knows"
Install the dotenv
Run below command
"dev": "nodemon -r dotenv/config src/app.js"
You can access the your defined variables using > process.env.varible_name

If you want to run Typescript in nodemon and require a particular .env file with dotenv then you can do:
In package.json scripts:
"dev": "nodemon -r dotenv/config src/myApp.ts dotenv_config_path=/path/to/your/env/file",
And a line in nodemon.json to tell nodemon to use ts-node when encountering Typescript extensions:
"execMap": {"ts": "node -r ts-node/register"},
This is useful for using a development .env file say .env.development.local for local dev work and leave the main .env file for live production variables.

Use the -w key to specify nodemon what to watch additionally.
"scripts": {
"dev": "env-cmd nodemon -w app -w *.js -w .env server.js"
}
Don't forget rerun npm run dev

Heroku Procfile
Change: web: node app.js to web: nodemon app.js

To load the dotenv package and any declared .env vars into the environment, you can do the following:
nodemon -r dotenv/config myapp.js

I use cross-env for environments.
npm i cross-env
set package.json.
"start": "cross-env NODE_ENV=production node dist/app.js",
"dev": "cross-env NODE_ENV=dev nodemon --exec ts-node src/app.ts",
npm run start OR npm run dev

Related

not working "NODE_ENV=development nodemon server.js" commnd in window and showing error as below mention

NODE_ENV=development : The term 'NODE_ENV=development' is not recognized as the name of a cmdlet, function, script file, or operable program. Check
the spelling of the name, or if a path was included, verify that the path is correct and try again.
Need win-node-env module
npm install -g win-node-env
For Windows
SET NODE_ENV=development
node app.js
For setting environment variables like that on Windows you can use package called cross-env.
You can install it by: npm install --save-dev cross-env. And then you have almost exact example from their docs:
{
"scripts": {
"build": "cross-env NODE_ENV=production webpack --config build/webpack.config.js"
}
}

Fastify reload browser

In Fastify framework is there anyway to reflesh the browser when changes happen on save.
In Express we have npm livereload as a middleware to listen to backend changes in Express. Are there any similar functions in Fastify or do I have to write my own registered plugin to automatically reflesh the browser on backend changes?
The livereload package that you mentioned is a general-purpose tool that works with Fastify as well. I was able to make it run with the following packages:
typescript Running tsc -w -outdir dist/ to watch the .ts files and transpile them into .js files
nodemon Running nodemon -r dotenv/config dist/server.js to watch the .js files and restart the web server
livereload Running livereload ./dist/ -w 500 so that the browser refreshes once the server restarted
concurrently To tie it all together in the package.json
"scripts": {
"build": "tsc",
"start": "node -r dotenv/config dist/server.js",
"dev:tsc": "tsc -w -outdir dist/",
"dev:watch": "nodemon -r dotenv/config dist/server.js",
"dev:livereload": "livereload ./dist/ -w 500",
"dev": "concurrently -k -p \"[{name}]\" -n \"TypeScript,App,LiveReload\" -c \"yellow.bold,cyan.bold,green.bold\" \"yarn dev:tsc\" \"yarn dev:watch\" \"yarn dev:livereload\" "
},
Note that you need to include the following <script> tag in your .html files to make livereload work
<script>
document.write(
'<script src="http://' +
(location.host || "localhost").split(":")[0] +
':35729/livereload.js?snipver=1"></' +
"script>"
);
</script>
This was enough to make my small Fastify project run, your milage may vary.
Yes, there is the fastify-cli module for that:
https://github.com/fastify/fastify-cli
it has the --watch option that you can use to live reload your backend on file changes.
In your package.json add this script:
"dev": "fastify start -l info --watch --pretty-logs app.js",
Note that app.js must expose this interface:
module.exports = function (fastify, ops, next) {
next()
}

How to run npm script (package.json) written in an external js file?

I know it has been covered in different questions but mine is a bit different:
Sorry in advance if it sounds really noob.
this is the script in package.json:
"start": "nodemon ./index.js --exec \"node -r babel-register\"",
I replaced that with:
"start": "node scripts/start.js",
and in start.js, I do:
const { execSync } = require('child_process')
execSync('nodemon ../index.js --exec \"node -r babel-register\"')
which throws an error:
/bin/sh: nodemon: command not found
Am I right with "execSync"?
I tried import nodemon in the file but it is obviously not helping.
What you're doing should work if nodemon is installed globally, i.e. with:
npm install -g nodemon
But if it's installed as a project dependency, i.e. with:
npm install --save-dev nodemon
Then you'll need to run it from the directory containing all the locally installed binaries: node_modules/.bin/
So something like this should work:
execSync('./node_modules/.bin/nodemon ../index.js --exec \"node -r babel-register\"')

How to have different .env file for Grunt for staging/production?

How can I have a different .env file in my project when compiling my project with Grunt?
npm install --save cross-env
In your package.json
"scripts": {
"start": "cross-env PROJECT_ENV=production grunt",
"dev": "cross-env PROJECT_ENV=development grunt"
}
In your grunt file you can use process.env.PROJECT_ENV to verify the current environment depending on which script you run.

How can I reload the webpack when I changed one of my required modules in package.json?

It is okey when I changed the .js files in the same directory.
But I have dependencies in package.json.
I didn't figure it out, is it possible the reload when I changed something in .js files one of these dependencies.
Update:
you can use this npm command from package.json,
{
"build": "webpack --progress --color",
"watch": "nodemon --watch ./ --delay 200ms --exec npm run build"
}
You can use nodemon to watch files which are out of webpack context. But webpack watch wont work with this.
nodemon --watch ./ --delay 200ms --exec 'your cmd here'
The above command will watch the files under the root folder and will execute the command which will trigger the webpack build. Here no need of setting watch flag for webpack because nodemon is watching everything.

Categories