I am working on a project for a client and I need to use webpack's Hot Module Replacement feature. I am using an express (node) application behind NGINX. I am using many javascript frameworks to design the application, React happens to be one of them.
I will be using the HMR feature.
I have a webpack.config.js like this :
var webpack = require('webpack');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var merge = require('webpack-merge');
var validate = require('webpack-validator');
var CleanWebpackPlugin = require('clean-webpack-plugin');
var styleLintPlugin = require('stylelint-webpack-plugin');
//breaking up into smaller modules
//commons module
//first
var start = {
context : __dirname ,
//entry point defination
entry : {
app : ['./require.js','webpack-hot-middleware/client?https:127.0.0.1:8195'],
vendor : ['angular','angular-animate','angular-messages','angular-aria','angular-route','angular-material','react','react-dom',''webpack-hot-middleware/client?https:127.0.0.1:8195'']
},
//output defination
output : {
path : './public/dist',
publicPath: 'https://127.0.0.1:8195/public/dist/',
filename : 'app.bundle.js'
},
module: { preLoaders: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
loaders: ['eslint']
}
],
loaders: [
{test: /\.js$/, loader: 'ng-annotate!babel?presets[]=es2015!jshint', exclude: /node_modules/},
{
test: /\.css$/,
exclude: /(node_modules|bower_components)/,
loader: ExtractTextPlugin.extract("style-loader", "css")
},
{
test: /\.less$/,
exclude: /(node_modules|bower_components)/,
loader: ExtractTextPlugin.extract("style", "css!less")
},
{
test: /\.scss$/,
exclude: /(node_modules|bower_components)/,
loader: ExtractTextPlugin.extract("style", "css!sass")
},
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loaders: ['react-hot', 'babel'],
},
{
test: /\.woff2$/,
loader: 'url'
}
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin(/* chunkName= */"vendor", /* filename= */"vendor.bundle.js"),
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify("production")
}
}),
new ExtractTextPlugin("styling.css", {allChunks: true}),
new ExtractTextPlugin("styling.css", {allChunks: true}),
new ExtractTextPlugin("styling.css", {allChunks: true}),
//new webpack.optimize.UglifyJsPlugin({
//compress: {
// warnings: false
// },
//}),
// new webpack.optimize.DedupePlugin(),
// new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
//target: 'web'
};
var config;
// Detect how npm is run and branch based on that
//choose modules
//all modules
switch(process.env.npm_lifecycle_event) {
case 'build':
config = merge(start);
break;
default:
config = merge(start);
}
//export config
module.exports = validate(config);
My app.js file includes :
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
//webpack development server integration
app.use(require("webpack-dev-middleware")(compiler, {
noInfo: false, stats: { colors: true,
chunks: true,
'errors-only': true }, headers: { "X-Custom-Header": "yes" }, publicPath: webpackConfig.output.publicPath
}));
app.use(require("webpack-hot-middleware")(compiler, {
log: console.log
}));
My NGINX file includes
location / {
...
proxy_pass https://127.0.0.1:8195;
...
...
}
When I open https://127.0.0.1:8195. Then files are created and served up. Express listens on 8195 port. But when I open the https://domain-name.com, the files aren't served but NGINX doesn't show 502 error.
You can use the CLI to modify the webpack-dev-server configuration with the following command: webpack serve --hot-only . Now let's update the index. js file so that when a change inside print. js is detected we tell webpack to accept the updated module.
Hot Module Replacement (HMR) exchanges, adds, or removes modules while an application is running, without a full reload. This can significantly speed up development in a few ways: Retain application state which is lost during a full reload.
When a hot update failed to replace the code in the browser, the HMR runtime will let webpack-dev-server know. The webpack-dev-server will then refresh the browser to download a new bundle. js file. This behavior can be disabled by adding hotOnly: true to your Webpack configuration.
It is indeed. There are a few configurations needed to accommodate the websockets HMR uses.
Here is a sample config you can use.
nginx:
location /my-path {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Connection $http_connection;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Sec-WebSocket-Extensions $http_sec_websocket_extensions;
proxy_set_header Sec-WebSocket-Key $http_sec_websocket_key;
proxy_set_header Sec-WebSocket-Version $http_sec_websocket_version;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 900;
client_max_body_size 0;
proxy_buffering off;
add_header X-Accel-Buffering no;
proxy_pass http://my-internal-server;
}
webpack.config.js:
const webpack = require('webpack')
module.exports = {
mode: mode,
entry: {
main: [
`webpack-hot-middleware/client?path=__webpack__/__webpack_hmr&timeout=20000`,
'app/main.js')
]
},
devServer: {
hot: true
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
}
I went down a similar route myself and ended up figuring it out for my setup. I sort of messily documented it here: https://vcavallo.github.io/how_to/webpack/vps/front_end/2018/06/27/remote-dev-machine-webpack-dev-server-nginx.html#the-solution
Here’s a direct link to the gist of my notes and various config files: https://gist.github.com/vcavallo/4f11985c4364bc4edfdf56556bff4ccf
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With