question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cannot use https with webpack-dev-server

See original GitHub issue
  • Laravel Mix Version: 6.0.9
  • Node Version (node -v): 14.15.0
  • NPM Version (npm -v): 6.14.9
  • OS: catalina

Description:

I’m trying to upgrade my Laravel Mix project. I am running webpack-dev-server over https, however, all hot updates are coming back as http and thus not working (I get a mixed content warning as the json is served over HTTP).

Steps To Reproduce:

This is my config:

mix
  .options({
    hmrOptions: {
      host,
      port: 8080,
    },
  })
  .webpackConfig({
    devServer: {
      host,
      port: 8080,
      https: {
        cert: // path to cert,
        key:  // path to key,
    },
});

When I run mix watch --hot it loads correctly initially. However, subsequent hot updates receive a mixed content warning that it is served over HTTP.

I see this line which suggests to me that --https needs to be in the command. However, when I pass that command I get either “unknown option --https” … or if I do mix watch --hot -- --https it is not respecting my key and cert and host as specified in my webpack config.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:6
  • Comments:8

github_iconTop GitHub Comments

5reactions
juslintekcommented, Feb 26, 2021

@silvioiannone your suggestion does not work it completely ignores it as well you cannot pass config to webpack options if you still want to use laravel mix. publicPath is available with mix.options({ publicPath }), but its functionality is completely different. So will this be solved? I want to test webShare API locally… Guess with laravel mix hmr its not possible…

After a lot of trial and error made it work like that: webpack.config.js

const path = require('path');
const fs = require('fs');

module.exports = {
    resolve: {
        alias: {
            '@': path.resolve(__dirname, 'resources/js'),
        },
        extensions: ['*', '.vue', '.js', '.json'],
    },
    devServer: {
        public: `${process.env.APP_URL}:${process.env.APP_PORT}/`,
        https: {
            key: fs.readFileSync(process.env.APP_SSL_KEY),
            cert: fs.readFileSync(process.env.APP_SSL_CERT),
        },
        injectHot: (config) => {
            config.output.publicPath = `${process.env.APP_URL}:${process.env.APP_PORT}/`;
            return true;
        },
        headers: {
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
            "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
        }
    }
};

webpack.mix.js

const mix = require('laravel-mix');
const fs = require('fs');
const path = require('path');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel applications. By default, we are compiling the CSS
 | file for the application as well as bundling up all the JS files.
 |
 */

process.argv.push(
    '--https',
    '--key ' + process.env.APP_SSL_KEY,
    '--cert ' + process.env.APP_SSL_CERT
);

mix.js('resources/js/app.js', 'public/js').vue()
    .postCss('resources/css/app.css', 'public/css', [
        require('postcss-import'),
        require('tailwindcss'),
        require('autoprefixer'),
    ])
    .options({
        hmrOptions: {
            host: process.env.APP_URL.replace(/https?:\/\//, ''),
            port: process.env.APP_PORT,
        },
        https: true,
        autoprefixer: { remove: false }
    })
    .webpackConfig(require('./webpack.config'))
    .sourceMaps(false);

mix.alias({
    '@': path.join(__dirname, 'resources/js'),
    vue$: path.join(__dirname, 'node_modules/vue/dist/vue.esm.js')
});

if (mix.inProduction()) {
    mix.version();
}

The most important part is here:

        injectHot: (config) => {
            config.output.publicPath = `${process.env.APP_URL}:${process.env.APP_PORT}/`;
            return true;
        },

Seems that injectHot is the last point before config json is returned to frontend. So you still can override config.output.publicPath, for some reason no matter how many places i tried to make publicPath to be https it always went back to http… Seems like something was splitting url into parts and putting back default schema…

But this helped. With lots of console.log saw what each part of config object contains. And noticed that this specific part was http, after changing it to https it worked.

process.env.APP_URL is basically full base url: https://domain.tld

3reactions
silvioiannonecommented, Jan 14, 2021

I figured out that there are a few steps involved in fixing this problem. I’m writing my understanding of things and the steps I performed in order to fix it.

First of all: Laravel Mix, as you have noticed, looks at the presence of the --https command line option in order to toggle HTTPS support. The problem is that if we specify the --https flag then webpack-dev-server probably expects the certificate and key to passed via CLI (--key and --cert options). If those CLI options are not present then webpack-dev-server will generate its own self-signed certificates.

process.argv.push(
    '--https',
    '--key ' + process.env.APP_SSL_KEY,
    '--cert ' + process.env.APP_SSL_CERT
);

Secondly, we need to update the Webpack configuration so that it looks a bit like this:

{
    config: {
        publicPath: 'https://' + process.env.APP_DOMAIN + ':8080/',
    },
    devServer: {
        https: {
            key: fs.readFileSync(process.env.APP_SSL_KEY),
            cert: fs.readFileSync(process.env.APP_SSL_CERT)
        }
    }
}

We can easily merge our own Webpack configuration using mix.webpackConfig(config).

P.S. Laravel Mix 6 uses the ^4.0.0-beta.0 version of the webpack-dev-server which introduces some breaking changes.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to enable HTTPS on Webpack Dev Server - Bleext
In this tutorial I'm going to show you how to run webpack dev server under a secure connection using HTTPS on your localhost....
Read more >
Webpack Dev Server running on HTTPS/Web Sockets Secure
I tried this and now http doesn't work anymore. Is there a way how I can use both https and http? – Eschon....
Read more >
Cannot use https with webpack-dev-server #2770 - GitHub
I'm trying to upgrade my Laravel Mix project. I am running webpack-dev-server over https, however, all hot updates are coming back as http...
Read more >
Set up a local security certificate - App development
Set up a local security certificate · Step 1: Install mkcert · Step 3: Generate the certificate · Step 4: Configure webpack-dev-server ·...
Read more >
DevServer - webpack
See here for an example of how to use webpack-dev-server through the Node.js API. warning. You cannot use the second compiler argument (a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found