How to set host environment variables inside npm scripts(package.json) - node.js

Imagine I have an environment variable
export NODE_ENV=production
when I do
echo $NODE_ENV //--> shows production which is correct
Problem:
Inside my package.json
scripts: {
...
"build": "export REACT_APP_NODE_ENV=${NODE_ENV:-development};
npm run build-css && react-scripts build",
...
}
Now when I do npm run build REACT_APP_NODE_ENV is getting set to development...but it should have been production as NODE_ENV is present.
If I do
scripts: {
...
"build": "export REACT_APP_NODE_ENV=production;
npm run build-css && react-scripts build",
...
}
It works correctly as expected i.e. all scripts access the REACT_APP_NODE_ENV with expected value that is production.
Goal
I wish to avoid hardcoding in my package.json
How can I set REACT_APP_NODE_ENV with value ${NODE_ENV}
"build": "export REACT_APP_NODE_ENV=${NODE_ENV};
npm run build-css && react-scripts build",

You probably want to ensure that this is cross-platform which will save you some headaches later on.
That problem has already been solved in the npm package cross-var.
Then, assuming you've already exported NODE_ENV, you use it this way:
"scripts": {
"build": "REACT_APP_NODE_ENV=${NODE_ENV}"
}

Related

Trouble running package.json commands

I am trying to run some commands I wrote in my package.json to test environment variables. However, when I try to run them in the Node.js command prompt, it throws me an error.
My package.json looks like this:
{
...
"scripts": {
...
"dev": "set NODE_ENV=development && node ./server/index.js",
"prod": "set NODE_ENV=production && node ./server/index.js"
},
}
And when I try to do npm run dev or npm run prod, it throws me the following:
npm ERR! Missing script: "dev"
so, what am I doing wrong here?
Are you sure you have this directory structure?
|- package.json
|- server
|-index.js
If so, try changing path to:
"dev": "set NODE_ENV=development && node server/index.js",

Using Nodemon or something similar to listen for changes, first build, then start?

Using Nodemon or something similar to listen for changes, first build, then start? Is it possible?
"scripts": {
"build": "npm run build:dll && webpack --progress",
"start": "node app.js",
}
Make sure nodemon is installed (npm install -g nodemon or npm install --save-dev nodemon) and then just change your package.json to this:
"scripts": {
"build": "babel lib -d build --copy-files",
"start": "nodemon build/index.js"
}
EDIT:
Add a nodemon.json on the root of your project, in there insert your build script in the "events.restart" section as documented here: https://github.com/remy/nodemon/blob/master/doc/sample-nodemon.md
"events": {
"restart": "your build script here"
}
And finally run with "npm run start". This run your app with nodemon and nodemon's configuration will execute your build very time you change your code (on restart)

Failed to write to file: ENOENT: no such file or directory

I am trying to build a folder with the name of build which will gonna contains number of map files and JavaScript files. But i'm getting an issue shown below.
Code :
"scripts": {
"prestart": "d2-manifest package.json manifest.webapp",
"start": "webpack-dev-server",
"test": "echo Everything probably works great\\! ## karma start test/config/karma.config.js --single-run true",
"build": "rm -rf build && set NODE_ENV=production webpack --progress && npm run manifest",
"postbuild": "cp -r src/i18n icon.png ./build/",
"validate": "npm ls --depth 0",
"manifest": "d2-manifest package.json build/manifest.webapp",
"deploy": "npm run build && mvn clean deploy",
"lint": "echo Looks good."
}
Error :
(I'm ignoring the fact that you seem to run this on a Windows machine)
The set command does not do what you think it does. To set an environment variable for a command, use
VARIABLE=value cmd
or
env VARIABLE=value cmd
This means changing
set NODE_ENV=production webpack --progress
into
env NODE_ENV=production webpack --progress
With set NODE_ENV=production webpack --progress you just set the positional parameters of the current shell instance to NODE_ENV=production, webpack and --progress.

Syntax (windows and linux) for multiple commands using Node cross-env

I'm taking a look at a project that has this line in it's package.json to run Karma tests
"scripts": {
"test": "NODE_ENV=test karma start karma.conf.js",
This doesn't work in Windows when I try "npm test".
I gather this is because this is a *nix syntax. And, in fact, if I change it to
"scripts": {
"test": "set NODE_ENV=test && karma start karma.conf.js",
the tests start when I run npm test.
Looking around, the optimal solution appears to be to use the cross-env package and rewrite it like
"scripts": {
"test": "cross-env NODE_ENV=test && karma start karma.conf.js",
So I get the cross-env will take care of the "set NODE_ENV" part to work on multiple OSes, but it's the "&&" part I'm questioning.
Do I leave the "&&" between the commands when using cross-env? Will that work in windows and linux?
Your cross-env example won't work, it should just be:
"scripts": {
"test": "cross-env NODE_ENV=test karma start karma.conf.js",
without the &&. The command to run comes immediately after you're done setting the variables.
I found your question by searching for how to set multiple variables with cross-env and also how to run multiple scripts/commands with cross-env. So to address the "multiple commands" part of your question:
Given these 2 test scripts:
a.js
console.log('a', process.env.TEST_VAR, process.env.TEST_VAR_2);
b.js
console.log('b', process.env.TEST_VAR, process.env.TEST_VAR_2);
You'll find if you have an && in the script in your package.json the subsequent scripts don't receive the variables. For example:
"scripts": {
"check": "cross-env TEST_VAR=hello TEST_VAR_2=world node a.js && node b.js",
Running npm run check gives:
a hello world
b undefined undefined
You can solve this by having an extra script which runs the multiple commands and running that with cross-env:
"scripts": {
"check": "cross-env TEST_VAR=hello TEST_VAR_2=world npm run check-real",
"check-real": "node a.js && node b.js",
Now npm run check gives:
a hello world
b hello world

Npm scripts doesn't work the way I want

see below:
scripts": {
"build": "node_modules/.bin/babel sercer/src --out-dir server/dist ",
"build:watch": "node_modules/.bin/babel server/src --out-dir server/dist --watch",
"start:server": "node ./node_modules/nodemon/bin/nodemon.js ./server/dist/app.js",
"dev" : "(npm run build:watch) && (npm run start:server)"
}
you know, both of them can work well when I run npm run xxx , but when i conbian them like npm run dev does,the last one will not taking effect.what wrong with my script?
You could try
"dev" : "npm run build:watch && npm run start:server"
you can use the post- and pre- scripts that will be called before and after that script.
eg :
"build": "npm run build:css && npm run build:js",
"prebuild:js": "npm run lint"
In the above example build will execute both build:css and build:js - but not before running the lint task.

Resources