webpack --optimize-minimize vs -p - reactjs

I am doing server side rendering inside my react app. Inside of app I have a few pictures so i have loder for them inside webpack-config
{
test: /\.(gif|png|jpg)$/,
loader: 'file-loader?name=assets/img/[name].[hash].[ext]',
},
If I run my code this way
cross-env NODE_ENV=production webpack --optimize-minimize --config webpack.config.prod.js,
I get an error
Warning: Prop `src` did not match. Server: "assets/img/profilna.1b1788096b2a10afe508dff672e50072.jpg" Client: "/assets/img/profilna.1b1788096b2a10afe508dff672e50072.jpg"
but if I run it like this
cross-env NODE_ENV=production webpack --p --config webpack.config.prod.js,
everything is good and functions perfectly like I want.
Why is that?
As I read -p is equivalent of
webpack --optimize-minimize --define process.env.NODE_ENV="'production'"
Since I am already setting production enviroment I don't need --define

cross-env NODE_ENV=production
with this, you are setting Node process.env.NODE_ENV but is not "being passed" or used - while bundling - inside the app. Basically, you need to create global variables for the app and set NODE_ENV to what you need by webpack. And this is what...
--define process.env.NODE_ENV="'production'"
...does. It will use Webpack DefinePlugin to set global process.env.NODE_ENV to be used while bundling the app.
I know this sounds a little bit unclear, I struggled to understand it myself but hopefully, documentation will clear that out.
Technically, NODE_ENV is a system environment variable that Node.js
exposes into running scripts. It is used by convention to determine
dev-vs-prod behavior by server tools, build scripts, and client-side
libraries. Contrary to expectations, process.env.NODE_ENV is not set
to "production" within the build script
See "Specifying the environment" for an example.

Related

How to set NODE_ENV on Amplify for React app

I am trying to run multiple environments of an AWS Amplify react app. So have set up a single environment, created two versions pointing to a master and a staging branch of GIT, assigned them to two different domains, and all working.
However, now I need to start one as production and one as staging so dotenv will read .env.production and .env.staging. (which is my actual objective :) )
So I set up an environment variable called NODE_ENV and set it to staging and production. However, Amplify seems to ignore it, and if I print out the environment variables, I get production on both systems
And the output from console.log(process.env)
Object
FAST_REFRESH: true
NODE_ENV: "production"
PUBLIC_URL: ""
OK, so I may have found a solution, it AIN'T pretty, but it works for me.
My solution is
Create two files,
env.production
env.stagign
Notice the missing .
They will be like your good old .env files
REACT_APP_VARIABLE=VALUE
Then you create an environment variable called BUILD_ENV like above, with an override. In my case, I have a master and staging based on the git branches.
The ugly magic comes in the build script. In amplify.yml we'll add BUILD_ENV, one line to write it, because I had a lot of problems getting it to work.
The second is that we add a new build type, called build:$BUILD_ENV
version: 2
frontend:
phases:
preBuild:
commands:
- npm ci
build:
commands:
- echo "Build environment is ${BUILD_ENV}"
- npm run build:${BUILD_ENV}
artifacts:
baseDirectory: build
files:
- '**/*'
cache:
paths:
- node_modules/**/*
The last step is that we need to get around that react build cares little about what you want to do, so we'll just build production, but with our env. So we will copy the relevant env.environment to .env.production I told you it would be ugly :)
"scripts": {
"start": "PORT=8082 react-scripts start",
"build": "react-scripts build",
"build:staging": "cp env.staging .env.production && NODE_ENV=staging react-scripts build",
"build:production": "cp env.production .env.production && react-scripts build",
=========================================
So the problem is (I think) that between react, node, AWS amplify, there are a lot of people who feel that things should be in very specific ways, like react deciding that there can only be production and dev, and amplify limiting what we're allowed to do to the environment in regards to variables.
This is probably not the right way of doing this, but it DOES work, so that's OK?

dotenv : how to set custom path

This is my architecture and I want to access the.env file
I tried all the solutions, __dirname, find-config, ckey and read all the stack solutions. I can't understand why my .env file is not loaded....
console output is always :
{NODE_ENV: "development", PUBLIC_URL: ""}
If you're using create-react-app to bootstrap your application, the react-scripts module handles setting up environment variables for you. However, there's a catch. All React environment variable needs to be prefixed with REACT_APP. Thus, your environment variable would be: REACT_APP_MY_ENV_VARIABLE.
You should not import dotenv. After changing .env files, you must restart the development server. This is the excerpt from the create-react-app docs. The .env must appear in the root of your project.
Note: You must create custom environment variables beginning with
REACT_APP_. Any other variables except NODE_ENV will be ignored to
avoid accidentally exposing a private key on the machine that could
have the same name. Changing any environment variables will require
you to restart the development server if it is running.
You can read more about environment variables and .env files with create-react-app in the create-react-app documentation.
If you really need to set a custom path, you can use env-cmd. It requires small changes in scripts section like this:
// from
"start": "react-scripts start"
// to
"start": "env-cmd -f ./custom/path/.env react-scripts start"

React: Environment Specific Config on Production Builds

My company uses the three standard environments: Development, Test, and Production. My create-react-app based application is hosted as a content item within our CMS, so to get it into any environment, I need to run the npm run build command.
I've created a file, config.js, which exports a different configuration object based on variables in process.env, but the default behavior here has the limitation that npm run build is always considered production. This makes sense, I just need different behavior.
What I'd like to do is run a script like npm run build:dev, etc, which sets a process.env variable that I can switch on. Essentially I need to create an npm script that sets a dotenv variable, then calls npm run build.
What is the best way to accomplish this?
You can use cross-env package (from npm) to define a environment variable.
Just install the package:
npm install --save-dev cross-env
And create your custom script hwere do you define your variable, for example:
{
"scripts": {
"build": "cross-env NODE_ENV=production webpack --config build/webpack.config.js"
}
}
It worked like a charm on my projects.
More information here cross-env

ReactJs - Webpack and environment variable

Im tring to build my ReactApp using an environment variable system.
Following online guides, I've create two different files
.env.developtment and .env.production
using the syntax for variables:
REACT_APP_BASE_SERVER_URL=myapp/
During development (using npm start to start the server), development file is loaded perfectly and all variable are stored in process.env global.
Unfortunally after compiling it with webpack, process.env is empty.
Im compiling my code with:
./node_modules/.bin/webpack --config webpack.config.js --env.production --progress --env.NODE_ENV=production --colors
and in my webpack there is no process.env override (using DefinePlugin is the common mistake).
Following a similar question on this site, I've tried to put this command in the config to avoid any process override:
node: {process: false}
but with this process.env will be totally undefined instead of empty ( {} ).
Is it possible to use this kind of environment system or .env files are only supported with npm build?
Sending the env as an argument does not set the application environment. Said so, I considering you are doing it inside your config. What would set up few env values is the option mode as development or production, which is available on webpack4 (You do -p or -d for the previous versions).
I dont know why you said using webpack.DefinePlugin is a common mistake. I have been using it and it works very well.
In last case, if you are sure you process.env should not be empty I would suggest you to do the syntax process.env["expected_attr"].

Preact and Webpack for Production

Just trying to make sure I am setting up my preact js correct for production.
In my webpack setup with preact, and run npm run build I notice with Bundle Analyzer Plugin the path for the preact js file is
/node_modules/preact/dist/preact.js and not
/node_modules/preact/dist/preact.min.js
I have uglify and minify js set up as well, but just thought it was curious that the minified package is not picked up ?
Entry script within webpack
entry: { app: './src/index.js', vendor: [ 'preact', 'preact-router' ] },
Npm Run build script
"build": "cross-env NODE_ENV=production webpack --progress -p --display-modules --display-chunks"
The default main for preact is dist/preact.js - preact.min.js is there for people who want to take advantage of minification when not applying their own (people hotlinking it off a CDN, for example), and to measure real-world output size.
You're already applying UglifyJS to your bundle by running webpack with the -p flag, so you needn't worry too much about trying to use dist/preact.min.js. It could save a few bytes, but nothing major. The file you're using (dist/preact.js) is actually already run through UglifyJS by Preact, it's just not compressed but not mangled (so the variable names remain intact).

Resources