Webpacker: ./bin/webpack-dev-server command line arguments are ignored

Created on 12 Mar 2019  路  20Comments  路  Source: rails/webpacker

I am using the rails/webpacker v4.0.2.

When I run the ./bin/webpack-dev-server with command line arguments, those actually don't get passed to the actual webpack-dev-server. As a result - I cannot pass the needed arguments.

Steps to replicate the issue:

  1. Set the breakpoint here:
    https://github.com/rails/webpacker/blob/7a241e75bd5376524348466aa2daa11661c49f41/lib/webpacker/dev_server_runner.rb#L58

  2. Run the command with the debuger:

./bin/webpack-dev-server --https --cert ~/.ssl/private.pem --key ~/.ssl/private.key
  1. See that the arguments were ignored.
    The command being built here basically is not passing any of the original @args to the webpack-dev-server command:
      def execute_cmd
        env = Webpacker::Compiler.env

        cmd = if node_modules_bin_exist?
          ["#{@node_modules_bin_path}/webpack-dev-server"]
        else
          ["yarn", "webpack-dev-server"]
        end
        cmd += ["--config", @webpack_config]
        cmd += ["--progress", "--color"] if @pretty

        Dir.chdir(@app_path) do
          Kernel.exec env, *cmd
        end
      end

Related issues

Suggested solution

Add the line to pass the arguments from @argv to the real webpack-dev-server command.

Changed code:

      def execute_cmd
        env = Webpacker::Compiler.env

        cmd = if node_modules_bin_exist?
          ["#{@node_modules_bin_path}/webpack-dev-server"]
        else
          ["yarn", "webpack-dev-server"]
        end
        cmd += ["--config", @webpack_config]
        cmd += ["--progress", "--color"] if @pretty
        cmd += @argv  # <===== Add this line here

        Dir.chdir(@app_path) do
          Kernel.exec env, *cmd
        end
      end

Most helpful comment

A solution which worked for me is to set https: true in the webpacker.yml and read cert and key in the development.js:

process.env.NODE_ENV = process.env.NODE_ENV || 'development'

const fs = require('file-system')
const environment = require('./environment')

const customDevConf = {
  devServer: {
    cert: fs.readFileSync('./cert.pem'),
    key: fs.readFileSync('./key.pem'),
  },
}

environment.config.merge(customDevConf)

module.exports = environment.toWebpackConfig()

All 20 comments

I think, this will also solve the #1758.

This is super useful, and in fact required for me.

Use case:

I integrate with a bunch of third party platforms via OAuth. Some of them doesn't work with localhost (Mailchimp, for example), so I moved to 127.0.0.1 but others don't support 127.0.0.1 (FB Ads). So I decided to use a custom domain for local dev.

But then I started to get warnings that the FB's JS stuff (that I need to refresh the FB token, that expires after 90 days now without being able to refresh it with a refresh token) will stop working over http and require https.

So, I need my app to be on something that is a domain (not an IP), not localhost and needs to be HTTPS.

i.e., I pretty much _need_ this to be able to use Let's Encrypt and not a self-signed certificate (or anything custom).

What can we do to make it happen?

In the meantime, I am using @marisveide's fork (thanks!), but it's only a short term solution :) You can use it like this: ./bin/webpack-dev-server --key ssl.server.key --cert ssl.server.crt

image

Have you tried pointing to the files in your config? https://webpack.js.org/configuration/dev-server/#devserverhttps

image

Have you tried pointing to the files in your config? https://webpack.js.org/configuration/dev-server/#devserverhttps

This doesn't work if you use the webpacker.yml file instead of .js.

You could pass plain certificate PEM strings to yml https: key, but then the other thing breaks - it doesn't recognize it as "https".

Nope. It looks like the webpacker config we have access to is a wrapper around it, and the https value by default in that yml file is not a hash but a boolean. Maybe I missed something. I would be happy with a config file too! :)

@marisveide do you know if we can use a JS config instead while still using webpacker and its benefits?

@marisveide do you know if we can use a JS config instead while still using webpacker and its benefits?

Not sure. That I had as a "fallback" thing to try if I wouldn't manage to solve the passing of attributes.
I suppose, the .js file to try to pass the js config, is this one:
/config/webpack/environment.js

But I am not sure how to hook the config params into that. 馃

Since we can't pass arguments to the webpack-dev-server I pasted my key and cert into webpacker.yml https field as a workaround as suggested above.

development:
  dev_server:
    https:
      key: |
        -----BEGIN PRIVATE KEY-----
        -----END PRIVATE KEY-----
      cert: |
        -----BEGIN CERTIFICATE-----
        -----END CERTIFICATE-----

This works when connecting directly to the webpack-dev-server on port 3035, but does not when requesting assets directly from the rails server which reverse proxies the request to the webpack-dev-server without using SSL. Webpacker is treating the Webpack https configuration field as boolean in dev_server.py and anything other than "true" will result in regular http calls, such is the case of hard-oding the key and cert above.

I think the real issue here is that webpacker made an incorrect assumption about a webpack-dev-server configuration - the https? method in dev_server.rb should not be expecting strictly boolean, or it should not be using another library's configuration to make decisions, though I understand the desire since the two are directly tied to each other.

This is my workaround in dev_server.rb, defaults to true when not false:

  def https?
    case fetch(:https)
    when false, "false"
      false
    else
      true
    end
  end

I would appreciate this feature, as certain configuration parameters for webpack-dev-server (color, info, progress, and stdin) can only be set at the command line.

Is there a workaround folks are using for this at the moment?

Hi, @hwhelchel!
I am using my fork at the moment - while waiting this PR to be merged:
https://github.com/marisveide/webpacker

@marisveide thank you! Is there any workaround that doesn't require a fork? Can I write the underlying JS config file and have rails webpacker pick that up?

FYI setting https in webpacker.yml to this currently works just fine (I struggled with this for a bit as well):

dev_server:
  host: localhost
  port: 3035
  https:
    key: './config/ssl/localhost.key',
    cert: './config/ssl/localhost.pem'
  ...
  ...

Replace key and cert with a path to your SSL cert.

I'm on Webpacker 4.0.7

Wow, thanks - sounds promising!
Can you also pass the root CA file, and is it taken too?
And can you set the host name other than localhost, and is it not always falling back to localhost, as it previously did?

_Sorry to ask, cannot test it now..._

For future readers @PatKoperwas solution runs into the same problem that @nicklozon identified.

It gets the key and cert passed as configuration but then the DevServer thinks https is not enabled when this line is called: https://github.com/rails/webpacker/blob/master/lib/webpacker/dev_server_proxy.rb#L15.

Maybe the below method can be changed to just check for a truth value instead of the exact boolean true?

  def https?
    case fetch(:https)
    when true, "true"
      true
    else
      false
    end
  end

Here is an alternate solution that keeps configuration within webpacker.yml https://github.com/rails/webpacker/pull/2251

For those like me who wanted to have a more recent fork, but also wants the patch from @marisveide, I made this fork + branch, which is branched off of the v4.0.7 tag with only one commit cherry-picked from @marisveide's fork (thanks for that @marisveide!): https://github.com/metricswatch/webpacker/tree/4.0.7-with-custom-ssl

In your Gemfile, you should use:

gem 'webpacker', git: 'https://github.com/metricswatch/webpacker.git', branch: '4.0.7-with-custom-ssl'

Thank you, @jipiboily - that's exactly what's needed for us as well!
Will be switching to yours now!
鉁岋笍

A solution which worked for me is to set https: true in the webpacker.yml and read cert and key in the development.js:

process.env.NODE_ENV = process.env.NODE_ENV || 'development'

const fs = require('file-system')
const environment = require('./environment')

const customDevConf = {
  devServer: {
    cert: fs.readFileSync('./cert.pem'),
    key: fs.readFileSync('./key.pem'),
  },
}

environment.config.merge(customDevConf)

module.exports = environment.toWebpackConfig()
Was this page helpful?
0 / 5 - 0 ratings

Related issues

johan-smits picture johan-smits  路  3Comments

naps62 picture naps62  路  3Comments

towry picture towry  路  3Comments

FrankFang picture FrankFang  路  3Comments

suhomlineugene picture suhomlineugene  路  3Comments