how does NODE_ENV work - npm

in packages.json I see scripts set to be run under specific environments .
"scripts": {
"prod": "node_modules/.bin/gulp build; NODE_ENV=production webpack --config webpack.config.prod.js --display-error-details",
"bower": "node_modules/.bin/bower",
"test": "NODE_ENV=test jest" , .....
my questions are :
1-where are these environments declared ?
2-what is the difference between NODE_ENV=test and NODE_ENV=development ?
3-how does npm understand them and how can it tell what is my current environment?
4- can you explain differences between how and when to run the mentioned scripts

Related

Use Verbose when building with Webpack and NPM

I have the following package.json file and I am building using webpack:
{
"name": "web",
"private": true,
"scripts": {
"build": "webpack --config webpack.config.js --mode development"
},
"devDependencies": {
"webpack": "4.21.0",
"webpack-cli": "3.1.2"
},
"dependencies": {
"jquery": "3.4.1"
}
}
How can I pass a parameter when using npm run build to use verbose so I can see build errors?
Try the following:
npm run build --verbose
(you can pass any parameter via npm run <command> after --).
To be more clear with regards to the first answer, using npm run build --verbose does increase the log level of the npm process, as noted here https://docs.npmjs.com/cli/v8/using-npm/logging. This does not necessarily bump any log level in the Webpack process itself.
The first answer would incur additional logging for the npm process. The parenthetical note is slightly misleading -- if you want to pass a parameter to an npm script to pass to the underlying scripts, you need to add a primary "--". So, while that answer does increase npm logging, it doesn't necessarily alter the webpack logging verbosity.
For example, if you have a linter scripts in npm:
"jest-preview": "jest-preview",
"lint": "eslint ./src",
"build": "webpack --config webpack.config.js --mode development"
If you want to utilize the "--fix" parameter to pass to eslint, you would run this npm script as:
npm run lint -- --fix
As can be seen on https://webpack.js.org/api/cli/, there is no --verbose option for build in webpack-cli. There are some facilities for log output verbosity configuration for the loaders and plugins that can be implemented in the webpack config. I would check that documentation for further information.

cross-env not setting NODE_ENV

I want to set environment variables to configure URL at runtime.
I use webpack to bundle the js and here is the plugin defined to make the NODE_ENV available during compile time.
new webpack.DefinePlugin({
'process.env':{
'NODE_ENV': JSON.stringify(process.env.NODE_ENV),
//'TARGET_ENV': JSON.stringify(process.env.TARGET_ENV)
}
})
Here are the yarn I want to execute according to the targeted environment:
"test-kubernetes": "cross-env NODE_ENV=kubernetes-cluster webpack && yarn run testenv",
"build": "cross-env NODE_ENV=production webpack --mode=production",
"dev": "cross-env NODE_ENV=development webpack --mode=development && webpack-dev-server --hot",
However process.env.NODE_ENV is undefined at runtime.
This issue seems to be related to cross-env since using:
SET NODE_ENV=kubernetes-cluster
instead of
cross-env NODE_ENV=kubernetes-cluster
on my Windows machine makes things work.
Any idea?
There is a regression since 5.2.0 for Windows environment. I managed to make things work switching back to 5.1.6.
Reference issue: https://github.com/kentcdodds/cross-env/issues/185

Vuejs + webpack - build for production but deploy to localhost

Trying to figure out how can I create a production build with webpack but first run it locally as a last test before deploying it to the server.
I was thinking of creating another command something like npm run build_local for that purpose but can't quite figure out how to do that.
I can see the following in the root package.json and I was thinking of somehow combining dev + build but can't figure out how to do that (or using config otherwise):
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"lint": "eslint --ext .js,.vue src",
"build": "node build/build.js"
},
Any advice on how can I run a production build in localhost with something like npm run build_local command?
EDIT
What I've tried so far is to run (manually) http-server ./dist which seem to run the folder on localhost, but the result in fact deviates from production (and dev) behavior - in my case it first renders everything as expected but as long as I press refresh, it returns 404 not found which is unexpected (on dev and server deployed versions it still renders the login page in this case):
for example if I open localhost:8080, vue redirects me to localhost:8080/login which is expected and works fine. On refresh it gives 404 though.
Ideally I'd expect it to work at least in the same way as dev build on localhost.
Any ideas?
So it was as simple as combining the dev command and providing prod config to it under the root package.json:
"build_local": "webpack-dev-server --inline --progress --config build/webpack.prod.conf.js"
//
Or in the package.json:
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"lint": "eslint --ext .js,.vue src",
"build": "node build/build.js"
"build_local": "webpack-dev-server --inline --progress --config build/webpack.prod.conf.js"
}
Now I can do npm run build_local which runs production build on localhost
Note: as per this github thread and this doc reference to prevent 404 on refresh also add the following to your webpack.prod.conf.js (anywhere in the file, but for reference you can paste it just before plugins)
devServer: {
contentBase: path.join(__dirname, 'dist'),
historyApiFallback: true, //this line is requried
compress: true,
port: 9000
},
You can now check your production build under the localhost:9000
If anyone knows about any drawbacks give me a comment or post the corrected answer

A customized npm script to compile, watch and server

I'm trying to set up a project which makes use of express and react. And I'm trying to make the best use of React-Slingshot project to benefit from it as much as possible. But the thing is that my project needs to be served (on the server side) by a script which I wrote. That script will use express and possibly socket.io to server the client side.
I think this is a problem if I use projects like React-Slingshot since they come with their own server scripts which support hot reloading and stuff. I'm willing to give up the fancy functionality like hot reloading. But I need to keep the --watch functionality so each time some file is changed, the code is compiled without me restarting the whole server.
Right now, the script section of package.json looks like this:
"scripts": {
"preinstall": "node tools/nodeVersionCheck.js",
"setup": "node tools/setup/setupMessage.js && npm install && node tools/setup/setup.js",
"remove-demo": "babel-node tools/removeDemo.js",
"start-message": "babel-node tools/startMessage.js",
"prestart": "npm run start-message",
"start": "concurrently -k -r -s first \"npm run test:watch\" \"npm run open:src\" \"npm run lint:watch\"",
"open:src": "babel-node tools/srcServer.js",
"open:dist": "babel-node tools/distServer.js",
"lint": "esw webpack.config.* src tools --color",
"lint:watch": "npm run lint -- --watch",
"clean-dist": "npm run remove-dist && mkdir dist",
"remove-dist": "rimraf ./dist",
"prebuild": "npm run clean-dist && npm run lint && npm run test",
"build": "babel-node tools/build.js && babel server -d dist --presets es2015,stage-2",
"test": "jest",
"test:CI": "babel-node tools/testCi.js",
"test:cover": "npm run test -- --coverage ",
"test:cover:CI": "npm run test:CI -- --coverage && cat ./coverage/lcov.info | node_modules/coveralls/bin/coveralls.js",
"test:watch": "jest --watch",
"open:cover": "npm run test:cover && opn ./coverage/lcov-report/index.html",
"analyze-bundle": "babel-node ./tools/analyzeBundle.js"
},
This is a modified version of what you can find in React-Slingshot. I've made a change so when I run npm run build, it builds the server code as well and terminates. It used to be like this:
"build": "babel-node tools/build.js && npm run open:dist",
Now, I'm trying to find a way to run my own server (i.e. node temp/server.js) while the rest of the code is compiled based on --watch as for my dev environment.
I believe you need a package like watch also check this video

how to dynamically select package manager in package.json

I am currently using yarn as my package manager, but some people on my team may still use npm. I wrote a few scripts in package.json
"scripts": {
"clear": "rm -Rf app/javascripts/* & rm index.html",
"watch": "yarn clear | NODE_ENV=development webpack -w --env.dev",
"build": "yarn clear && yarn dev && yarn start",
"dev": "yarn clear | NODE_ENV=development webpack --env.dev",
"prod": "yarn clear | NODE_ENV=production webpack --progress --env.prod"
}
If I want to call clear inside of other scripts, I have to either use npm clear or yarn clear. As the script is currently written, someone who doesn't have yarn installed will run into an error.
Is there a way for me to write this package.json so that it will work regardless if someone runs npm build or yarn build, and it will use the package manager of their choosing?
You can use the variable npm_execpath, it will point to the package manager used to run the script.
For example, this will output the version of yarn or npm:
"scripts": {
"version": "$npm_execpath -v",
}
$ npm run version
> 3.10.10
$ yarn run version
> 0.21.3