16

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.

Sumit Lahiri
  • 505
  • 6
  • 13
  • This seems to be an NGINX configuration/DNS problem as you can reach your files over 127.0.0.1 but not the domain name. – detay Jun 22 '17 at 22:22
  • 10
    Why are you using webpack on the server? Webpack is for _development_. – Cisco Oct 22 '17 at 00:05
  • Maybe sth wrong with your nginx config file,how did you set domain? – 亚里士朱德 Jan 17 '18 at 07:32
  • I want to highlight Francisco Mateo's comment, why do you need to use this on a server on nginx? – George Mar 09 '18 at 23:12
  • 2
    @FranciscoMateo and George, some people do _development_ on remote machines using nginx. nginx is just a server - that doesn't mean it has to be used for production. Express is a server, too, but people routinely use if for development. – VCavallo Jun 14 '18 at 16:24
  • @VCavallo Yes I'm aware of that, but that's typically done using something such as citrix to remote into the desktop. nginx is a _web_ server and webpack is a _bundler_. There is absolutely no reason to use webpack on a nginx server, whether it's dev or prod. – Cisco Jun 14 '18 at 17:06
  • @FranciscoMateo I disagree again. I use a headless ubuntu server. I ssh into it for terminal access and text editing and then view the served files in my local browser. There are countless benefits of this approach that I won't enumerate. I use webpack on the 'server' because its part of my dev process. I use nginx so i can hit the files from outside. there's no reason those two things need to fight one another. – VCavallo Jun 15 '18 at 21:55
  • I agree with you @VCavallo that it may be useful to mix both nginx and webpack in some particular use cases. But it would be useful to know if the question here is related to one of these use cases or if the use of webpack do not really have a sense here... – Ricovitch Aug 10 '18 at 09:33
  • To be honest I was just trying this out for some reason. My usual setup for things is way different and I never use this approach. In retrospect, I am not able to recall, why I was doing this back then. Anyways. thanks for the comments. I guess I was trying to do something very weird with NGINX and HMR back then. Now it seems funny :)). I very much appreciate and agree with the comments. – Sumit Lahiri Oct 08 '20 at 14:01

2 Answers2

4

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()
  ]
}
wizulus
  • 5,653
  • 2
  • 23
  • 40
2

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

VCavallo
  • 190
  • 8