Webpack 4 configuration with React - reactjs

How can I reload the application automatically in development mode with Webpack 4?
At the moment, I tried this script but it does not work:
"scripts": {
"dev": "webpack-dev-server --mode development",
"build": "webpack --mode production"}

Need to enable the hot property for webpack-dev-server. Read more in docs.
Use from CLI in the package scripts:
"scripts": {
"dev": "webpack-dev-server --mode development --hot"
}
Use inside the devServer config object:
module.exports = {
mode: 'development',
// other configs: entry, output, module, plugins, etc.
devServer: {
hot: true
}
};
Also, you can check this Webpack-Demo project using Webpack 4 and React.

Related

Create a react "development" build

What's the best way to create a development build bundle for a create-react-app project?
npm run build builds something that's buggy in ways that development isn't and it ignores my NODE_ENV setting
This works for the react-scripts 5.0.1:
Install react-app-rewired: npm install react-app-rewired
Replace the build script in your package.json:
"scripts": {
"build": "react-app-rewired build"
}
Create the config-overrides.js file in the root folder of your project.
module.exports = function override(config) {
config.mode = 'development';
config.optimization.minimize = false;
return config;
};
If you want to create two build modes you can add a condition that checks the mode.
"scripts": {
"build": "cross-env react-app-rewired build",
"build:dev": "cross-env DEV_MODE=true react-app-rewired build",
}
module.exports = function override(config) {
if (process.env.DEV_MODE) {
config.mode = 'development';
config.optimization.minimize = false;
}
return config;
};

Electron react app hot reloading from src folder not working

I'm trying to use the hot reload feature in development mode of a react electron app.
It use to work well but I'm having issues with the latest electron version 15+.
I am able to run the app from the build folder but anytime I want to make a change I need to run the build command therefor the hot reloading is not working.
I have change the package.json path to use the public folder. But I get a blank page. however if I make a change to the main.js folder, the app reload but not when I make a change within the src folder of the app itself.
In my package.json if I use the public folder the app is not loading. It only loads when I use the build folder.
"version": "0.1.0",
"private": false,
"main": "build/main.js",
"homepage": "./",
"files": [
"public/**/*",
"node_modules/**/*"
],
"scripts": {
"electron-dev": "set ELECTRON_START_URL=http://localhost:3000 && electron . --overwrite --asar=true --platform=win --arch=x64 --icon=icons/icon.png --prune=true --out=build",
"electron": "electron .",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"dist": "electron-builder --win"
},
"devDependencies": {
"electron": "15.3.0",
"electron-builder": "^22.13.1",
"electron-reload": "^2.0.0-alpha.1",
"electron-reloader": "^1.2.3"
}
In my public/main.js file;
require('electron-reloader')(module,
{
debug: true,
watchRenderer: true
});
const startUrl = url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
});
I can also see the watcher in the console;
Watched paths: {
'..': [
'public'
],
'.': [
'assets',
'favicon.ico',
'icon.png',
'index.html',
'logo-black.png',
'logo.png',
'logo.svg',
'main.js',
'manifest.json',
'package.json',
'preload.js',
'robots.txt'
],
assets: [...]
It seams like the public folder is not being watched at all. When ever I make a change to my app inside the src folder. nothing get's picked up. The src folder is not being watched/
What should I look for?
Please comment if you would like to see more code.
[UPDATE]
The start url is not getting picked up in the .env nor in the inline command.
As a temporary solution I am running the build & electron.
Very counter productive!
One potential hacky solution you could use is just using nodemon, and make it re-launch electron each time you change any content inside the src directory. In order to do this you would have to run npm install --save-dev nodemon. Then in your packages.json put in the following
"dev": "NODE_ENV=development nodemon --watch ./src/**/* --watch . --exec 'npm run electron'"
With respect to the actual question, why are you using electron-reloader over just using electron-reload. It is easy to setup, just by adding the following to your code
require('electron-reload')(__dirname, {
electron: path.join(__dirname, 'node_modules', '.bin', 'electron'),
hardResetMethod: 'exit'
});

How use env in webpack?

I created .env and .env.production files with differnt values:
API=http://localhost:8082/api/
Created config:
var config = {};
config.api = process.env.API;
module.exports = config;
I try to get config in an action but 'api' field is undefined.
const config = require("../config/server");
console.log(config);
I think need to add something in the start command
"start": "webpack-dev-server --mode development --inline --progress",
"production": "webpack-dev-server --mode production --inline --progress",
But I'm not sure what I should add here.
Could you please help me?
Create a webpack.config.js in project root directory and add entries in it as suggested below
webpack.config.js
// Do the imports at top of config file
var webpack = require('webpack');
var dotenv = require('dotenv').config({path: __dirname + '/.env'});
....
// In plugins section
plugins: [
...
new webpack.DefinePlugin({ "process.env": dotenv.parsed })
]
Don't forget to install dotenv package. (yarn add dotenv / npm install --save dotenv).
Then change start script as below
"start": "webpack"
To get more insights on webpack.config.js options, check here.
(or)
Edit
If you have only fewer environment variables and don't want to maintain them in a separate file (.env/.env.production) and load it via webpack DefinePlugin, libraries like cross-env will come handy here.
Change your scripts as below
"start": "cross-env API=http://localhost:8082/api webpack-dev-server --mode development --inline --progress",
"production": "cross-env API=https://prodsite.com/api webpack-dev-server --mode production --inline --progress",
You can add multiple variables too
"start": "cross-env NODE_ENV=... API=... webpack-dev-server ..."
I use the dotenv package along with the define plugin.
We first parse the .env file then iterate over the values assembling an object. Afterwards we pass the assembled object to the define plugin. The define plugin sets them as global constants accessible from your application.
const dotenv = require('dotenv');
const fileEnv = dotenv.config({ path: '.env.development' }).parsed;
const envKeys = Object.keys(fileEnv).reduce((prev, next) => {
prev[`process.env.${next}`] = JSON.stringify(fileEnv[next]);
return prev;
}, {});
module.exports = {
...
plugins: [
new webpack.DefinePlugin(envKeys),
],
...
}

npm run build won't create build directory

It's my first time running a build to deploy a react website. When I run npm run build, nothing happens. I tried running npm run build:all and I do get a build directory created but with no index.html file.
My current package.json is:
"eslint": "eslint \"src/**/*.js\"",
"start": "concurrently \"npm run dev:server\" \"npm run dev:bundle\"",
"test": "jest",
"dev:server": "cross-env NODE_PATH=./src nodemon --exec \"babel-node src/server/server.js\" --ignore .reactful.json --ignore public/",
"dev:bundle": "webpack -wd",
"verify-tests": "jest --coverage",
"build:react": "cross-env NODE_ENV=production webpack --progress -p",
"build:node": "babel src -d build --config-file ./babel-node.config.js --copy-files",
"build:all": "npm install && npm run build:react && npm run build:node",
"prod:start": "cross-env NODE_ENV=production NODE_PATH=./build pm2 start -i max build/server/server.js --update-env --name react-testProd",
"prod:stop": "pm2 stop react-testProd",
"prod:reload": "pm2 reload --update-env react-testProd",
"prod:logs": "pm2 logs --update-env react-testProd",
"build": "webpack --config webpack.config.js"
My current webpack config is:
resolve: {
modules: [path.resolve('./src'), path.resolve('./node_modules')],
},
entry: {
main: ['./src/renderers/dom.js'],
},
output: {
path: path.resolve('public', 'bundles'),
filename: isDev ? '[name].js' : '[name].[chunkhash].js',
},
Any idea what is wrong with this?
I cant see anything particularly wrong but you can try using CopyWebpackPlugin
module.exports = {
plugins: [
new CopyWebpackPlugin([
{ from: './index/html', to: 'relative/path/to/dest/' }
])
]
}

HMR not working when using nodemon

I have an app that is using express to serve some API calls and webpack to server some static assets in development. All works ok until I bring nodemon into the setup.
When I run my app using nodemon I get this error when I update a file on the React side (client side).
GET http://localhost:3004/__webpack_hmr
net::ERR_INCOMPLETE_CHUNKED_ENCODING
If I run my app without nodemon the HMR works perfect and all updates and reloads the React modules.
In my package.json file I have the following scripts.
The start one works fine but the dev one using nodemon causes the error when a change is made to a React component.
"scripts": {
"start": "node server/app.js",
"dev": "nodemon server/app.js",
"build": "cross-env NODE_ENV=production webpack --config ./webpack/webpack.prod.config.js --progress --colors",
"heroku-postbuild": "npm run build"
},
Any ideas what might be causing this?
Here is my entry point in my webpack config file.
entry: [
`${ROOT_DIR}/js/index`,
'webpack-hot-middleware/client'
]
Here is my webpack setup with webpackHotMiddleware which I call in my app.js and pass in App to it. App being my express server.
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');
const webpackConfig = require('../../webpack/webpack.dev.config.js');
const compiler = webpack(webpackConfig);
const devOptions = {
noInfo: true,
publicPath: webpackConfig.output.publicPath,
stats: { colors: true },
historyApiFallback: true
}
// WEBPACK MIDDLEEWARE
function setupWebpackMiddleware( app ){
app.use(webpackHotMiddleware(compiler));
app.use(webpackDevMiddleware(compiler, devOptions));
}
module.exports = {setupWebpackMiddleware}
Using the following versions.
"webpack": "^2.2.1"
"webpack-dev-middleware": "^1.10.0",
"webpack-dev-server": "~1.16.2",
"webpack-hot-middleware": "^2.16.1"

Resources