Webpack-encore: When using dev-server https option manifests and paths in CSS files are still http:// instead of https://

Created on 29 Jan 2021  路  15Comments  路  Source: symfony/webpack-encore

I have just spent a few hours trying to make dev-server serve files via SSL with .pfx specified (as per Symfony recommendation and personal preference), but I found no way around it. It looks to me like a bug in webpack-dev-server, but am not sure where to look for.

  • Before (encore < 1.0.0)

I had set up in packages.json:

"scripts": {
    "dev-server": "encore dev-server --compress --https --pfx=\"$HOME/.symfony/certs/default.p12\" --disable-host-check",
}
  • After (encore 1.0.x)

Most options were easily migrated to configureDevServerOptions, but:

  • when I set options.https: { pfx: process.env.HOME + '/.symfony/certs/default.p12' } and no --https in command line, dev-server serves files with correct certificate. But manifest.json, entrypoints.json and paths in CSS contains paths with http://, thus development app served via https cannot load any asset.
  • when I set options.https: { pfx: process.env.HOME + '/.symfony/certs/default.p12' } or no options.https at all, but pass --https in command line, dev-server serves files with self signing certificate (ignoring pfx configuration), but creates correct manifest.json, entrypoints.json and paths in CSS.

Second options could be a short term solution for me (accepting new certificate once in a while is not that bad), but it would be nice to have working pfx option with manifest plugin. I see no way to pass pfx in command-line, which could probably solve the issue.

bug

Most helpful comment

Ok, this problem still exists. I think I've found the problem and the reason why both @Lustmored and I thought the problem has been solved magically.

webpack-dev-server/lib/Server.js::setupHttps() will override your https-configuration if you pass https: https://github.com/webpack/webpack-dev-server/blob/ae2de0209c2ff3cae09286620bc08144c429a196/lib/Server.js#L460

With http2 = false and https!==true, webpack will still create node_modules/.cache/webpack-dev-server/server.pem based on your configuration (~/.symfony/certs/default.p12), because we passed on object https. That's great, but since we don't pass --https, you'll end up with http:// in your manifest.

When you configure http2=true or pass --https, it will get a certificate, which means looking into node_modules/.cache/webpack-dev-server/server.pem. Because we created this certificate while debugging, it works.

edit: well, this seems not 100% accurate, but I'm getting somewhere.

All 15 comments

Thanks for your detailed issue. I'm experiencing the same issue after upgrading to webpack-dev-server 4 beta.

I tried to use the "allow-insecure-localhost" flag in Chrome, but that flag has been removed in Chrome 88. I found a workaround by setting temporary-unexpire-flags-m87.

I think we need to get rid of the "https" argument (parse-runtime.js#L44) as specified on webpack/webpack-dev-server /CHANGELOG.md#400-beta0-2020-11-27, the https option is now an object, so I think we have a conflict, especially when we try to configure the https using the webpack.config.js file as below

Encore.configureDevServerOptions(options => {
        options.https = {
            pfx: '/path/to/.symfony/certs/default.p12'
        }
})

Then we should not run the command yarn encore dev-server --httpsas it will override the defined https option prepared in the config file, and if we remove that option from the command, the output file inside public/build/entrypoints.json file will contains invalid URLs without the https protocol

Hi everyone!

Thanks for the detailed report. I'm having some problems repeating the things here.

First, the --https option on Encore controls exactly 2 things:

1) It sets the devServer.https option to true. If you are calling Encore.configureDevServerOptions(options => { and setting options.https = {} inside of that, then you are completely overriding this (which is fine, just mentioning that for clarity).

2) The --https option also helps determine the "publicPath" config - making it https://.

So, if you pass --https AND also override the https config via Encore.configureDevServerOptions(), there is no conflict: you are just overriding the true value and passing additional configuration. And this is what you should do.

To clarify: to use https in the dev-server you should:

A) Continue passing the --https option
B) If you want to set the certificate, then use:

Encore.configureDevServerOptions(options => {
    options.https = {
        pfx: '/path/to/.symfony/certs/default.p12'
    }
})

When doing this, everything seems to work for me. There may still be a bug somewhere - but I'm not able to repeat the issue where some paths in entrypoints.json or manifest.json contain http: (or in paths in CSS files).

Cheers!

Thanks for clarifying. That's exactly what I did, but it didn't work. But now it does.

So either I was wrong and didn't do it that way, or some other magic (cache, other dependencies updated?) happened that made this problem disappear.

Well, shamefully I must also admit that it works as @weaverryan wrote now. I am certain it wasn't a few days ago when I was reporting the issue, but whatever was causing wrong behavior is gone here too.

Thanks for your time investigating and explaining expected behavior (couldn't find it in the docs) and I am closing the issue.

Ok, this problem still exists. I think I've found the problem and the reason why both @Lustmored and I thought the problem has been solved magically.

webpack-dev-server/lib/Server.js::setupHttps() will override your https-configuration if you pass https: https://github.com/webpack/webpack-dev-server/blob/ae2de0209c2ff3cae09286620bc08144c429a196/lib/Server.js#L460

With http2 = false and https!==true, webpack will still create node_modules/.cache/webpack-dev-server/server.pem based on your configuration (~/.symfony/certs/default.p12), because we passed on object https. That's great, but since we don't pass --https, you'll end up with http:// in your manifest.

When you configure http2=true or pass --https, it will get a certificate, which means looking into node_modules/.cache/webpack-dev-server/server.pem. Because we created this certificate while debugging, it works.

edit: well, this seems not 100% accurate, but I'm getting somewhere.

Thank you @stephanvierkant for this explanation, I was also surprised by the fact that it works for both of you, and I spent too much time debugging and trying to figure out what was the cause of this issue at least for me, I even tried it with a new/clean installation of symfony and encore bundle, but I get the same results. Thank you again !

While I understand the problem, I don't know how to fix this. The https flag overrides the configuration options: https://github.com/webpack/webpack-cli/blob/master/packages/serve/src/startDevServer.ts#L32

I think we should get rid of the required https flag.

@weaverryan WDYT?

Thanks for digging deeper - the fact that the --http flag causes the http config to be overridden INSIDE the dev-server would indeed explain things.

If we removed the https flag, Encore would still need a way to determine if it should make the dev server URL (which is used as the public path) use https - https://github.com/symfony/webpack-encore/blob/main/lib/config/parse-runtime.js#L58

So if we removed the https flag... I guess users would enable https via Encore.configureDevServerOptions? And then we would read that config to see if https has been enabled and "tweak" our public path accordingly?

Just my nitpick here, maybe that will help you everyone.

I do use the dev-server with HTTPS enabled like this:

  • I don't use --https flag from encore dev-server
  • I use the following dev server configuration:
Encore.configureDevServerOptions((options) => {
    options.https = {
      ...(options.https || {}), // not sure if it's needed in fact 
      cert: `${__dirname}/var/localhost.portfolio.yproximite.fr.pem`,
      key: `${__dirname}/var/localhost.portfolio.yproximite.fr-key.pem`,
    };
  })

@weaverryan Yes, that sounds sensible. The https flag overrides the https options right now and that's how it should be.

Just configuring https options (or just true) should be sufficient, like with other options: we don't need a http2 flag either.

@Kocal That will create a manifest.json file with http:// isn't it?

Nope, it create a manifest.json file with https://... because I use --public https://.... too, but that may be luck since I'm using Encore inside a virtual machine and need to specify a public URL:

Running encore dev-server --public https://my-domain:8080 --host 0.0.0.0 will create this kind of manifest.json file:

{
  "build/app.js": "https://my-domain:8080/build/app.js",
  "build/page.home.js": "https://my-domain:8080/build/page.home.js",
  "build/page.home.svg": "https://my-domain:8080/build/images/marker3.c5a075ce.svg",
  "build/page.home.png": "https://my-domain:8080/build/images/full_hd_thumbnail_loading.ee5e651c.png",
  "build/page.orphans.js": "https://my-domain:8080/build/page.orphans.js",
  "build/page.project_details.js": "https://my-domain:8080/build/page.project_details.js",
  "build/runtime.js": "https://my-domain:8080/build/runtime.js",
  // ...
}

Yea the --public option definitely changes things. Without that, we try to guess if we should use https:// for the public URL. So by NOT having the --https flag but YES having --public, you're "fixing" the public URL manually. That's likely a work around until we get this fixed.

Ok folks - I think #917 should fix this.

Thanks for the detailed conversation here - it helped me jump into fix the issue instead of first jumping in to understand the issue.

Cheers!

Hi!

This should be fixed in 1.0.5. If it's not, or you have any other issues, please open a new issue :).

Related docs for the fix: https://github.com/symfony/symfony-docs/pull/14930

So, enable https in webpack.config.js by setting the https config to an object. If you're using the Symfony binary, then it will look like:

const path = require('path');
// ...

     .configureDevServerOptions(options => {
         options.https = {
             pfx: path.join(process.env.HOME, '.symfony/certs/default.p12'),
         }
     })

Then, do NOT use the --https flag when running Encore. Just run:

yarn dev-server

And have a lovely weekend ;)

Was this page helpful?
0 / 5 - 0 ratings