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

2

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.

Offprint answered 12/9, 2016 at 15:47 Comment(9)
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.Downwash
Why are you using webpack on the server? Webpack is for development.Genevieve
Maybe sth wrong with your nginx config file,how did you set domain?Orlene
I want to highlight Francisco Mateo's comment, why do you need to use this on a server on nginx?Landgravine
@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.Neonate
@Neonate 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.Genevieve
@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.Neonate
I agree with you @Neonate 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...Astrodynamics
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.Offprint
A
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()
  ]
}
Aggressive answered 14/11, 2019 at 22:1 Comment(0)
N
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

Neonate answered 11/8, 2018 at 21:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.