Using webpack infront of rails in development

I just thought to share, for my local dev environment, I’ve decided to put webpack as a proxy in front of rails, this allow asset to handled by webpack(the one’s that are not in the asset pipeline), and rails doesn’t need to know anything about webpack. it also solved a side issue i was seeing where the http proxy code in foreman also impacted http calls to webpack dev server from foreman, imho this is a better model since its simulate user environment better, and also reduce the complexity around secure headers and open ports.

if you want to give it a try, you would need to change your webpack configuration as follows:

diff --git a/config/webpack.config.js b/config/webpack.config.js
index 596ad044a..3db5756ae 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -15,7 +15,7 @@ var vendorEntry = require('./webpack.vendor');
 
 module.exports = env => {
   // must match config.webpack.dev_server.port
-  var devServerPort = 3808;
+  var devServerPort = 3000;
 
   // set TARGETNODE_ENV=production on the environment to add asset fingerprints
   var production =
@@ -180,7 +180,10 @@ module.exports = env => {
       host: process.env.BIND || 'localhost',
       port: devServerPort,
       headers: { 'Access-Control-Allow-Origin': '*' },
-      hot: true
+      hot: true,
+      proxy: {
+        "/": "http://localhost:5000"
+      }
     };
     // Source maps
     config.devtool = 'inline-source-map';

This assumes your browser points to http://locahost:3000 and your webpack is listening on that port, and if using foreman gem, the default port for rails is 5000. (adjusted if needed).

You would also need to set :webpack_dev_server: false in your config/settings.yaml

I’ve tested this, and it works quite well! Its nice in that it only requires the use of a single port, so its easier to proxy through another layer (such as when running on a remote hypervisor’s guest). It also works with ‘./scripts/foreman-start-dev’ which makes debugging much easier.

Making port 5000 be configurable via an ENV variable would be needed for katello dev envs (or using a different default), but other than that I would love to see it become the default.

2 Likes

This works well in katello for me as well, my foreman diff looks like:

diff --git a/config/webpack.config.js b/config/webpack.config.js
index 596ad04..c34013b 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -15,7 +15,7 @@ var vendorEntry = require('./webpack.vendor');
 
 module.exports = env => {
   // must match config.webpack.dev_server.port
-  var devServerPort = 3808;
+  var devServerPort = 3000;
 
   // set TARGETNODE_ENV=production on the environment to add asset fingerprints
   var production =
@@ -179,7 +179,11 @@ module.exports = env => {
     config.devServer = {
       host: process.env.BIND || 'localhost',
       port: devServerPort,
+      disableHostCheck: true,
       headers: { 'Access-Control-Allow-Origin': '*' },
+      proxy: {
+        "/": "http://localhost:5001"
+      },
       hot: true
     };
     // Source maps

and in config/settings.yaml I added

:webpack_dev_server_https: false
:webpack_dev_server: false

then I ran the dev server with BIND=0.0.0.0 ./script/foreman-start-dev -p 5001

I’m a bit concerned at the amount of work and tribal knowledge needed to get a katello dev server w/ webpack and debugging capabilities running.

This isn’t very intuitive and beginner-friendly, which isn’t great considering we have interns starting soon. Can we make this process more configurable and have a “happy path” that just works when you spin up a new katello development environment? At the very least we should have clear documentation detailing the various dev server options available.

2 Likes

any idea why this is needed?

I guess this is not required, as the second option webpack_dev_server: false should disable them both.

I think it is needed to use VMs on a remote hypervisor. Without it, I see “Invalid Host Header” in the browser when navigating to the foreman page.

@sharvit has found this doesn’t actually work as expected if you are working on the UI as it still reads the manifest.json from the filesystem (the weback-rails gem) and end up creating the wrong links to webpack assets (and not including the dev-server.js). it might be easier to simply be more opinionated and force a proxy setup (including forklift) and drop the usage for the gem at all. (e.g. make foreman less aware of webpack).

Could you elaborate more on the proxy setup? You mean a HTTPD reverse proxy?

I still think Foreman needs to know about manifest.json since it needs to generate the correct URLs in the HTML.

there are actually 2 different types of proxies:

  1. if you are using forklift with katello scenario, it set up an httpd process to do ssl terminations and redirections to port 3000 / 443
  2. if you use the webpack proxy in front of rails, then webpack assets are served by it (including web sockets for hot live reload and other nice features) - the value here is that you can make foreman not even aware of webpack with the exception of what you just said about creating the correct links.

hope this helps,
Ohad