Run package.json scripts by NODE_ENV.
Install with npm:
npm install by-node-env
Install with pnpm:
pnpm install by-node-env
Install with Yarn:
yarn add by-node-env
- Read
NODE_ENV
fromprocess.env
. - Read
NODE_ENV
from .env file. - Defaults
NODE_ENV
todevelopment
. - Customize
process.env
for eachNODE_ENV
. - Clearer, concise scripts in package.json.
- No more Bash scripting in package.json.
- Works on Linux, macOS, and Windows.
- Compatible with npm, pnpm, and Yarn.
- Consistent workflow for any
NODE_ENV
:npm install
orpnpm install
oryarn install
.npm start
orpnpm start
oryarn start
.
When developing a Node.js application in development
mode, we often use these different commands: npm run serve
, npm run watch
, npm run dev
, etc. In addition, we also set NODE_ENV=development
as an environment variable.
When deploying to production
, we often use these different commands: npm start
, npm build
, npm run prod
, etc. NODE_ENV=production
is a must-have environment variable in this case.
The package.json might look like this for those situations mentioned above:
{
"scripts": {
"watch": "webpack -d --watch",
"build": "webpack -p",
"dev": "nodemon src",
"prod": "node dist",
"serve": "npm run watch & npm run dev",
"start": "npm build && npm run prod"
}
}
Working on multiple projects with different commands can be very confusing and forgetting, especially under heavy cognitive load. As a result, we spend a lot of time consulting the README or the scripts field in package.json.
{
"scripts": {
"build": "by-node-env",
"build:development": "webpack -d --watch",
"build:production": "webpack -p",
"start": "by-node-env",
"start:development": "npm build & nodemon src",
"start:production": "npm build && node dist"
}
}
npm build
and npm start
have long been the de facto commands to build and start a Node.js application, respectively.
Besides that, NODE_ENV
should always be explicitly set as an environment variable for best practice. A lot of popular frameworks expect NODE_ENV
to be set as well.
Why not combine both, so that when NODE_ENV=production
, executing npm start
will spawn npm run start:production
. Similarly, when NODE_ENV=development
, executing npm start
will spawn npm run start:development
.
Arbitrary NODE_ENV
and scripts work too, refer to more examples below.
The priority order of resolving NODE_ENV
is as follows:
- Environment variable.
- .env file in project root directory.
development
(default).
The .env file, if present, must be located in the root directory of your project, where package.json lie.
The resolved NODE_ENV
is available as process.env.NODE_ENV
in your application at runtime.
{
"scripts": {
"start": "by-node-env", // 1
"start:development": "ts-node src", // 2a
"start:production": "ts-node-dev src" // 2b
}
}
npm start
: 1 ➡️ 2aNODE_ENV=development npm start
: 1 ➡️ 2aNODE_ENV=production npm start
: 1 ➡️ 2b
NODE_ENV=production
{
"scripts": {
"start": "by-node-env", // 1
"start:development": "ts-node src", // 2a
"start:production": "ts-node-dev src" // 2b
}
}
npm start
: 1 ➡️ 2bNODE_ENV=development npm start
: 1 ➡️ 2aNODE_ENV=production npm start
: 1 ➡️ 2b
{
"scripts": {
// If NODE_ENV is missing, defaults to "development".
"build": "by-node-env",
"build:development": "webpack -d --watch",
"build:production": "webpack -p",
"build:staging": "webpack -p",
// Deployment will not work unless NODE_ENV=production is explicitly set.
"deploy": "by-node-env",
"predeploy:production": "docker build -t ${DOCKER_USER}/${DOCKER_PROJECT} .",
"deploy:production": "docker push ${DOCKER_USER}/${DOCKER_PROJECT}",
// "npm start" is _the_ command to start the server across all environments.
"start": "by-node-env",
"start:development": "npm run build:development",
"prestart:production": "npm run build",
"start:production": "start-cluster build/server/server.js",
"prestart:staging": "npm run build",
"start:staging": "start-cluster build/server/server.js",
// Explicitly set NODE_ENV, which is helpful in CI.
"test": "NODE_ENV=test by-node-env",
"test:test": "mocha"
}
}
Encounter bugs or having new suggestions?
Issues, comments, and PRs are always welcomed!