by-node-env
Run package.json scripts by NODE_ENV.
Installation
Install with npm:
npm install by-node-env
Install with pnpm:
pnpm install by-node-env
Install with Yarn:
yarn add by-node-env
Features
- 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
.
Problem
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:
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.
Solution
package.json
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.
NODE_ENV
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.
Examples
Example 1a
Example 1a: package.json
{ "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
Example 1b
Example 1b: .env
NODE_ENV=production
Example 1b: package.json
{ "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
Example 2
Example 2: package.json
{ "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" }}
Contributing
Encounter bugs or having new suggestions?
Issues, comments, and PRs are always welcomed!