Dynamic require() on node NODE_ENV with webpack - node.js

I am building a simple NodeJs Lambda with webpack. There is a dependent node_module using different configuration file based on NODE_ENV
let config = require(`./${process.env.NODE_ENV ? process.env.NODE_ENV : 'dev'}_env.js`);
I am setting NODE_ENV in package.json
"serve": "set NODE_ENV=qa&webpack --mode development --watch",
"serve-windows": "$env:NODE_ENV=qa&webpack --mode development --watch"
and in webpack configuration
mode: process.env.NODE_ENV ? process.env.NODE_ENV : 'default',
No matter what I do, its always including dev_env.js ignoring the NODE_ENV I am setting. I spent all night trying to figure out this looking at different posts, is there anything I am doing incorrectly?

webpack --mode development sets NODE_ENV to development. See the documentation: https://webpack.js.org/configuration/mode/#usage
Another remark, default and qa&webpack are non-standard values for NODE_ENV. Usually, the expected value is either development, test, or production.
If you want to use this approach, you will have to use a different environment variable, for example:
let config = require(`./${process.env.APP_ENV ? process.env.APP_ENV : 'dev'}_env.js`);
"serve": "set APP_ENV=qa&webpack --mode development --watch",

Related

Can you set a NODE_ENV variable for a staging site url in react?

I'm using the following NODE_ENV variable to use a different API depending on whether i'm in development mode or on the live site
process.env.NODE_ENV === 'development'
I also have a staging site hosted which i would like to use the same API as the development (local) project. Is there a way to set a URL as another NODE_ENV variable? So that my staging URL can be accessed via for example process.env.NODE_ENV === 'test'?
I would like process.env.NODE_ENV === 'development' to be my local project and process.env.NODE_ENV === 'test' to be my staging URL eg. https://www.stagingsite.com. How would this be set?
Every bootstrap provides their way to do this.
If you are using create-react-app then... try this
https://create-react-app.dev/docs/adding-custom-environment-variables/#what-other-env-files-can-be-used
then create env files after that place script commands and provide file location and name and run build script with appropriate env
"scripts": {
"build": "react-app-env --env-file=config/${BUILD_ENV}.env build",
"build:staging": "BUILD_ENV=staging npm run build",
"build:production": "BUILD_ENV=production npm run build",
...
}
try this for now although react-app-env is deprecated now .. this is code snippetfrom my old project... now cra and dotenv is enough .. although i need to create the flow

How to deploy a React SSR application to Heroku?

I have simple running react Server Side App .
GitHub Link for the repo, in the local env i have a build script that runs using npm start which starts the client and server builds and then i have a watcher which listen's to changes in file. This set up works really well locally.
"scripts": {
"start": "npm run dev",
"dev": "npm-run-all --parallel dev:*",
"dev:server": "nodemon --watch build --exec \"node build/bundle.js\"",
"dev:build-server": "webpack --config webpack.server.js --watch",
"dev:build-client": "webpack --config webpack.client.js --watch"
},
I tried to deploy these changes as a prod app to heroku here for some odd reason it never works and returns 503 . I have not added any changes to the build scripts in the package.json and tried deploying as is.
I thought it should work as the build log dosent give any errors on heroku but while trying to access the app it shows error and asks me to check app log but i am not using heroku cli and not planning on using it , and
thinking of auto deployment from github.
I am quite new to script/ largely build scripts trying to learn more on them.
How can we make sure this small React SSR git repo deploys and i am
able to access the home page .
I am not using heroku cli and not planning on using it
You should and I really recommend, as it's the best way to see errors that occurs after the build, why your app crashed and see the full logs. Even though you can see the logs from your heroku dashbord (More -> View logs), this only gives you the tail of the logs.
How can we make sure this small React SSR git repo deploys and i am able to access the home page.
Make sure the server is listening on the right port
by using process.env.PORT as heroku expose a dynamic port.
const port = process.env.PORT || 3000
app.listen(port, () => {
console.log('Listening on Port ' + port);
})
On heroku the NODE_ENV environment variable is set toproduction by default,
which means heroku will prune thedevDependencies after the build,
but in your case, you still need these dependencies to start your app with webpack.
You can fix this in two ways :
Customize your build process by adding a build script:
From your github
repo
:
"start": "webpack --config webpack.client.js; webpack --config webpack.server.js; node build/bundle.js"
to
"scripts": {
"start": "node build/bundle.js",
"build": "webpack --config webpack.client.js & webpack --config webpack.server.js",
"build:start": "webpack --config webpack.client.js && webpack --config webpack.server.js && node build/bundle.js",
}
Set the NODE_ENV to any other value to skip pruning your
devDependencies
heroku config:set NODE_ENV=development //(Another reason to use the CLI)
Check this link for more details

cross NODE_ENV does not work while running the server from dist folder

I am running the node server after the application build, pointing to the dist folder using: node dist/server/main.js. The server points to production environment by default (I think that's what webpack does by default).
In order to make it reference the local environment I tried the 2 scripts below:
"start": "cross-env NODE_ENV=local ./node_modules/.bin/cross-env node
dist/server/main.js"
and
"start": "cross-env NODE_ENV=local node dist/server/main.js"
These does not work. Is there any way if my server could point to the local/ development environment instead of always pointing to production? Thanks!
Your crossenv syntax looks wrong. It should probably be:
"start": "cross-env NODE_ENV=local node dist/server/main.js"

electron-builder, how to set node environmental variables

Node.js in windows system can be set environmental before the server is started, like this:
set NODE_ENV=production
That NODE_ENV parameter can be using in node.js or electron by process.env.NODE_ENV.
But when I builder electron by electron-builder, like this:
electron-builder build --windows
How do I set the environmental variables?
Update:
May be cannot pass a fixed environment variable to an executable by electron-builder.
Maybe you can only manually load an environment file, modify it when you package it, or preset the parameters to the dev state. When there is no state, it is production.
If you want an environment variable to be set on runtime you can either set them manually or use other tools like dotenv https://www.npmjs.com/package/dotenv
But the easiest way is to set them at runtime when running the binaries. You can use either a batch script (If windows) for example:
setlocal
set NODE_ENV=production
.\your-binaries.exe
endlocal
Note: setlocal prevents the variable leaking any further.
The one-liner version could be set NODE_ENV=production && .\binaries.exe
Under linux works the same way: set variable then run.
I'm posting this in the hopes that it helps other people in my situation. I have three environments (development, staging, and production), and I wanted my Electron main process to be aware of which environment it was running on.
Now, for development it's quite easy to expose an environment variable to Electron inline using the CLI:
export NODE_ENV=development && electron desktop/main.js
Then, Electron's main process can access this environment variable like so:
const isDev = process.env.NODE_ENV === 'development';
However, being able to distinguish between the staging and production environments was slightly trickier. My staging and production environments are both packaged and deployed using electron-builder, with package.json scripts like so:
"desktop-build": "webpack --config config/webpack/webpack.prod.js && electron-builder --config config/electron.config.js",
"desktop-build-staging": "webpack --config config/webpack/webpack.staging.js && electron-builder --config config/electron.config.js",
NOTE: The webpack configs above expose configs to the renderer process (website), but not the main process.
So my solution to expose the environment to the Electron main process for staging and production was as follows:
Set NODE_ENV=staging or NODE_ENV=production to electron-builder via command line invocation:
# Production
export NODE_ENV=production && webpack --config config/webpack/webpack.prod.js && electron-builder --config config/electron.config.js
# Staging
export NODE_ENV=staging && webpack --config config/webpack/webpack.staging.js && electron-builder --config config/electron.config.js
In my electron.config.js file (configs for electron-builder) use the extraMetadata parameter (docs) to inject a variable into my package.json:
extraMetadata: {
isProduction: Boolean(process.env.NODE_ENV === 'production'),
},
Then you can access that from your Electron main process:
// This variable is injected into package.json by electron-builder via the extraMetadata field (specified in electron.config.js)
const {isProduction} = Boolean(require('./package.json'));

Issues with getting started with webpack 4

I am following the tutorial exactly as given here . But I am amazed that the docs seems outdated. e.g
npx webpack src/index.js dist/bundle.js fails with:
The CLI moved into a separate package: webpack-cli. Please install
'webpack-cli' in addition to webpack itself to use the CLI.
-> When using npm: npm install webpack-cli -D
-> When using yarn: yarn add webpack-cli -D
If I install webpack-cli and try again I see this error:
Hash: af9bc06fd641eb0ffd1e Version: webpack 4.0.0 Time: 3865ms Built
at: 2018-2-26 05:10:45 1 asset Entrypoint main = main.js 1
(webpack)/buildin/module.js 519 bytes {0} [built] 2
(webpack)/buildin/global.js 509 bytes {0} [built] [3]
./src/index.js 212 bytes {0} [built] [4] multi ./src/index.js
dist/bundle.js 40 bytes {0} [built]
+ 1 hidden module
WARNING in configuration The 'mode' option has not been set. Set
'mode' option to 'development' or 'production' to enable defaults for
this environment.
ERROR in multi ./src/index.js dist/bundle.js Module not found: Error:
Can't resolve 'dist/bundle.js' in '/var/app/webpack_demo' # multi
./src/index.js dist/bundle.js
I hope I am not doing something crazy, given the popularity of webpack the documentation should reflect the actual behavior. Let me know if I am
doing something wrong.
Edit
A details description of upgrade to webpack 4,that might be helpful
You can pass mode param in the webpack config or cli command.
Config: mode: 'development' or mode: 'production'
CLI: webpack --mode development or webpack --mode production
The Webpack team is working on updating the package docs asap.
New guides and docs are available in the webpack.js.org official site.
In the meantime, You can also read related posts on medium:
webpack 4: mode and optimization
webpack 4: released today!!
Check on GitHub this Webpack-Demo project intended to be a Webpack 4 tutorial.
Previous and others links to helpful resources used in the webpack configs are included in the project's Readme.
It has two zero-config builds (using the new webpack mode option which includes a sets of defaults), and another two using custom configs.
Since webpack-4, the CLI has been move to webpack-cli therefore you need to install also this package in your devDependencies.
Also, webpack expect the new mode configuration to be set either on the CLI run or the config object.
CLI usage in your npm scripts:
"scripts": {
"dev": "webpack --mode development",
"prod": "webpack --mode production"
}
Set mode property in your webpack config object:
{
mode: 'production' // | 'development' | 'none'
}
If mode value isn't specified, webpack uses the production value (defaulted option). But warns you in the output with:
WARNING in configuration
The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this environment.
Webpack mode reduce the required configuration for an useful build by using a set of defaults (default values for configuration properties depending the mode value):
production enables all kind of optimizations to generate optimized bundles
development enables useful error messages and is optimized for speed
none is a hidden mode which disables everything
Read more on release notes & changelog
Got the same issue and after a bit of research found its a problem to be fixed as you can see on this Github thread
One of the options:
Inside package.json set scripts to either development or production mode
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production"
}
And now when you run npm run dev it will give you bundle.js but not minified.
But when you run npm run build it will give you a minified bundle
It will be updated very soon, see this link for information
We are very close to having out Migration Guide and v4 Docs Additions complete! To track the progress, or give a helping hand, please stop by our documentation repository, checkout the next branch, and help out!
Webpack 4 docs are not ready yet. I recently migrated from webpack 3 to 4 and it took me quite some time to figure out all the issues.
Here'a my sample repo you can use as reference for migrating from webpack 3 to 4.
https://github.com/flexdinesh/react-redux-boilerplate
There's one commit specific for migration. Take a look at that for more info.
In webpack config file:
const isProd = process.env.NODE_ENV === 'production';
module.exports = {
***
mode: isProd ? 'production' : 'development'
***
};
In package.json:
***
"scripts": {
"dev": "node ./app.js",
"prod": "cross-env NODE_ENV=production npm run dev",
***
},
***
"dependencies": {
"cross-env": "^7.0.2",
***
}
***

Resources