Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use Webpack-Hot-Middleware with NGINX on server side?

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.

like image 377
Sumit Lahiri Avatar asked Sep 12 '16 15:09

Sumit Lahiri


People also ask

Which command helps to enable hot module replacement in the dev server?

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.

What is HMR server?

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.

How does Webpack hot reload work?

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.


2 Answers

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()
  ]
}
like image 124
wizulus Avatar answered Sep 21 '22 05:09

wizulus


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

like image 26
VCavallo Avatar answered Sep 20 '22 05:09

VCavallo