webpack/webpack-dev-server

hot-update.json 404 (Not Found)

josh08h opened this issue ยท 41 comments

Reproducible test repos:

Shortly: publichPath in webpack-dev-server doesn't override publisPath in webpack

Need search way how better handle publicPath


#1591 (comment)

#1591 (comment)

  • Operating System: El Capitan 10.11.6
  • Node Version: 8.9.3
  • NPM Version: 5.5.1
  • webpack Version: 4.6.0
  • webpack-dev-server Version: 3.1.3
  • This is a bug
  • This is a modification request

Code

const path = require('path');
const fs = require("fs");
const dir = d => path.join(process.cwd(), d);

module.exports = {
  entry: {
    application: './src/application',
    test: './src/test'
  },
  output: {
    path: dir('../public/assets/client'),
    filename: "[name].bundle.js"
  },
  devServer: {
    stats: 'errors-only',
    https: true,
    key: './path_to_pemfile.pem',
    cert: './path_to_pemfile.pem',
    headers: {
      'Access-Control-Allow-Origin': '*'
    },
    port: 9092,
    host: 'broker-gateway-webpack.firstbanco.dev'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      }
    ]
  }
};



"scripts": {
    "start": "webpack-dev-server --hot --mode development"
}

Expected Behavior

I would expect HMR to work.

Actual Behavior

When I save a change in a js file a request is made for application.bundle.js:33 GET https://broker-gateway.firstbanco.dev/1a00a5ecc216afcb2106.hot-update.json 404 (Not Found).

As you can see the correct port number has not been specified for the requested resource.

If I manually execute a GET request to https://brokergateway.firstbanco.dev:9092/1a00a5ecc216afcb2106.hot-update.json (note I have added correct port) then I get the resource fine.

For Bugs; How can we reproduce the behavior?

As explained.. use above webpack config and change a js file under application or test entry points.

For Features; What is the motivation and/or use-case for the feature?

Ease of development.

Looks port is not respected when dev server try to load hot updated

PR welcome

I'd just like to second that I believe am running into this problem(or a similar one) as well. My webpack config is as follows:

const webpack = require('webpack');
const path = require('path');
const proxy = 'localhost:22850/clients/dev/default.aspx/'

module.exports = {
	entry: [
		'react-hot-loader/patch',
		'./components/App.js',
		'./css/main.scss'
	],
	mode: 'development',
	module: {
		rules: [
		  {
			test: /\.(js|jsx)$/,
			exclude: /node_modules/,
			use: ['babel-loader']
			},
			{
				test: /\.(scss|sass|css|)$/,
				use: [
					'style-loader',
					"css-loader",
					"sass-loader"
				]
			},
			{
				test: /\.(jpe?g|png|gif|woff|woff2|eot|ttf|svg)(\?[a-z0-9=.]+)?$/,
				use: [
					{
						loader: 'url-loader',
						options: {
							limit: 8192,
							fallback: 'file-loader',
							relativePathName: true,
							publicPath: 'http://localhost:8080/'
						}
					}
				]
			}
		]
	  },
	  resolve: {
			extensions: ['*', '.js', '.jsx',  '.png', '.woff', '.woff2']
	  },
	output: {
		path: path.resolve(__dirname, '/dist'),
		filename: 'bundle.js',
		publicPath: '/'
	},
	devtool: 'source-map',
	devServer: {
		// https://stackoverflow.com/questions/43544077/react-with-typescript-hot-reload-iis-webserver
		proxy: {
			'*' : {
				target: 'http://' + proxy
			}
		},
		port: 8080,
		host: '0.0.0.0',
		publicPath: 'http://localhost:8080',
		hot: true,
		headers: {'Access-Control-Allow-Origin': '*'}
	},
	plugins: [
		new webpack.HotModuleReplacementPlugin(),
		new webpack.NamedModulesPlugin(),
		new webpack.NoEmitOnErrorsPlugin()
	],
	node: {
		console: true // needed for html5-history package
	}

When using hotOnly: true, the hotupdate is using localhost:22850 and 404's, but if I manually make the get request using localhost:8080 I receive a response.

I am observing the same issue although the server responds with a 200 okay response and serves an html file.

Suddenly got this issue as well. Seems to have happened after some change I did while developing caused the dev server update to fail, after which it started serving successful updates from the wrong port number (the one used for serving the site, not the default port 8080).

Anything happening on this one? Started a different project and have updated to all the lastest webpack packages and still having this problem...

Invalid configuration, please create minimum reproducible test repo

I also get the page to serve setting the port manually with say PORT=1111 npm run dev ...

set a publicPath in your 'output' and 'devserver' which is the URL of output.path from the view of the HTML page.

Duplicate #1785?

Somebody can create minimum reproducible test repo?

@evilebottnawi This seems to be a combination of 2 problems, as I fully explain here: https://github.com/Loonride/webpack-issue-repro

  • The publicPath issue is correct: #1785
  • Maybe we should close this and open an "incorrect port for hot-update" issue

EDIT: the problem is here - https://github.com/webpack/webpack/blob/master/lib/web/JsonpMainTemplate.runtime.js#L31
I guess a Webpack issue is needed

@Loonride is there a PR for the fix? I'm trying to to find out where the path query param passed to webpack as an entry is stored, webpack-hot-middleware allows a full URL to be passed as argument but seems to ignore it when fetching hot-update.json.
e.g.:
https://github.com/webpack-contrib/webpack-hot-middleware/blob/cb29abb9dde435a1ac8e9b19f82d7d36b1093198/example/webpack.config.js#L10

@evilebottnawi This seems to be a combination of 2 problems, as I fully explain here: https://github.com/Loonride/webpack-issue-repro

* The `publicPath` issue is correct: #1785

* Maybe we should close this and open an "incorrect port for hot-update" issue

EDIT: the problem is here - https://github.com/webpack/webpack/blob/master/lib/web/JsonpMainTemplate.runtime.js#L31
I guess a Webpack issue is needed

That line on runtime evaluates to something like /edcd5a7afc1eede0fb52.hot-update.jsonso the fix would be to include the port/domain of the queryParam (if set as full URL ) as mentioned above

Also, why the heck there are object's with a single letter as a name? ๐Ÿค”

@arthurgeron there's a PR here #1514, hasn't been active in a while though. It seems like it can possibly be solved without touching this by altering the Webpack compiler config publicPath.

Not really sure about the single letter naming. My guess is it is to prevent the user from accidentally using a variable that is exposed to their bundle.

@arnihermann please create minimum reproducible test repo, i think something wrong in your setup

@krzystof why you use hotOnly instead hot?

yep, it is bug, need search way how we can solve this without breaking

While this is not at all a solution to the issue, if you just want to hack your way around it to get the hot-update.json working again - this is what I did. My issue was that I am running my (vue) devServer on a different port (and url) as I want to run it under https.

What I did was to simply edit the node_modules/webpack/lib/web/JsonpMainTemplate.runtime.js file manually. Horrible, but it works for me ๐Ÿ˜‰ . I'm showing the methods here, but, to be clear I only edited this line and this line.

In the hotDownloadUpdateChunk I just fixed the src attribute manually.

	function hotDownloadUpdateChunk(chunkId) {
		var script = document.createElement("script");
		script.charset = "utf-8";
		script.src = 'https://fake.vueserver:8080/' + $hotChunkFilename$;
		if ($crossOriginLoading$) script.crossOrigin = $crossOriginLoading$;
		document.head.appendChild(script);
	}

And similarly in the hotDownloadManifest method.

	// eslint-disable-next-line no-unused-vars
	function hotDownloadManifest(requestTimeout) {
		requestTimeout = requestTimeout || 10000;
		return new Promise(function(resolve, reject) {
			if (typeof XMLHttpRequest === "undefined") {
				return reject(new Error("No browser support"));
			}
			try {
				var request = new XMLHttpRequest();
				var requestPath = 'https://fake.vueserver:8080/' + $hotMainFilename$;

@evilebottnawi 3.7.0 is released but this issue is in 3.7.0 milestone?

@e-cloud it should be fixed, what is problem? It is not closed because we should add tests from this case

I use vue-cli. and webpack-dev-server 3.7.1.

I have the following vue.config.js

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

module.exports = {
  publicPath: '',
  lintOnSave: true,
  productionSourceMap: false,
  devServer: {
    port: 8080,
    disableHostCheck: true,
    historyApiFallback: {
      rewrites: [{ from: /.*/, to: '/index.html' }],
    },
    https: {
      key: fs.readFileSync(path.join(__dirname, './certs/server.key')),
      cert: fs.readFileSync(path.join(__dirname, './certs/server.crt')),
    },
    sockHost: 'localhost',
    sockPort: '8080',
  }
}

However, when i launch https://localhost:8080, errors prompt
image

because my server crt is only authorized for localhost:8080.

@josh08h how about this?

const path = require('path')

module.exports = {
  mode: 'development',
  entry: path.join(__dirname, 'bundle.js'),
+ output: {
+   publicPath: 'http://0.0.0.0:9000/dist/',
+ },
  devServer: {
    contentBase: __dirname,
-   publicPath: '/dist/',
    compress: true,
    port: 9000,
    hotOnly: true,
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
  }
}

We have to change the port which provides hot-update from 8080 to 9000 even if we access localhost:8080.

I'm actually getting this same error but everything seems to be served from the right url and the file is available on the server side. It just ends up with a 404, does anyone else have this issue? My app is running on a docker container if that is relevant

@josh08h how about this?

const path = require('path')

module.exports = {
  mode: 'development',
  entry: path.join(__dirname, 'bundle.js'),
+ output: {
+   publicPath: 'http://0.0.0.0:9000/dist/',
+ },
  devServer: {
    contentBase: __dirname,
-   publicPath: '/dist/',
    compress: true,
    port: 9000,
    hotOnly: true,
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
  }
}

We have to change the port which provides hot-update from 8080 to 9000 even if we access localhost:8080.

It works!Thanks!

test it:

  output: {
            publicPath: '/public/assets/client/',
            filename: "[name].bundle.js"
        },

I was having this same issue using dev-server with Electron. The fix @josh08h posted worked like a charm.

Somebody can create minimum reproducible test repo?

Somebody can create minimum reproducible test repo?

@evilebottnawi Here: https://github.com/Loonride/webpack-issue-repro

I have solved the issue here: #2055. It is on next because there are potential breaking changes.

tvkit commented

My app is running on a docker container if that is relevant

Also noticing the issue when proxying the connection via a docker/envoy container.

For me the problem was that the index.html file was in the src folder instead of the project's root, so I opened http://localhost:8080/src instead of just http://localhost:8080 thus the app tried to fetch http://localhost:8080/src for the hot-update.json file but that is served from the root.

for me, the main weird thing is that it works when my hotUpdateMainFilename is without [hash], but when I put [hash] on filename, 404 all the time.

I think I may have found the issue.. not sure if its the same. I only found that hot module loading worked on / and any sub page /foo or /bar but if you go one level deeper say /foo/bar then it will try to load /foo/hash.hot-update.json while the server would be hosting it at /hash.hot-update.json and the GET would fail. Once I solved that path issue the same was happening with /foo/main.hash.hot-update.js

Some experimenting later I found node_modules\webpack\lib\web\JsonpMainTemplate.runtime.js to be the culprit.

line 40:

// script.src = $require$.p + $hotChunkFilename$;
script.src = window.location.origin + '/' + $hotChunkFilename$;

line 24. I swapped

// script.src = $require$.p + $hotChunkFilename$;
script.src = window.location.origin + '/' + $hotChunkFilename$;

I want to prepare this for a PR but can anyone advise if I'm fixing this correctly and what is $require$.p ?

I had encountered with this issue. but the big problem was it's consequence. Infinite reloading page again and again.
My project was fine in my laptop (MacBook Pro) but not on my VPS(Ubuntu 16).
I checked every things from DNS Server to dirty codes in packages and absolutely I tried many options for build section in nuxt.config.js file and all of those was with no success.
Finally by adding some missing options in site nginx config, Infinite reloading was resolved.
So for the same situation, It may help you to check nginx configuration first.
Here are my site nginx configuration. It's configured to support only https with ssl. Please notice you should change it based on your needs.

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 302 https://$server_name$request_uri;
}

server {

    # SSL configuration

    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    ssl        on;
    ssl_certificate         /etc/ssl/certs/example.pem;
    ssl_certificate_key     /etc/ssl/private/examplekey.pem;

    error_log   /home/ubuntu/example/site/nginx_error.log;
    server_name example.com www.example.com;
    index index.html index.htm index.nginx-debian.html;

    ### Added 
    gzip            on;
    gzip_types      text/plain application/xml text/css application/javascript;
    gzip_min_length 1000;
    ### End

   location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;


        ### Added 
        proxy_redirect                      off;
        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_read_timeout          1m;
        proxy_connect_timeout       1m;
        ### End

    }
}

try

    devServer: {
        host: '0.0.0.0', port: 8080,
        public: '0.0.0.0:8080',
    }

maybe useful

ydax commented

Mid-September 2020

FWIW something about Chrome's recent update has been broken a few things for me, and this is a new issue for us. We were able to get everything working again by restarting the browser.

In my case, I am developing an ASP.NET MVC Core (2.1) with a Microsoft npm module aspnet-webpack

Unfortunately, the aspnet-webpack module targets older version of webpack (^4.0.0). If I get the peer dependency wrong (webpack 5.2.0) then this error appears.

Downgrading to webpack 4.x resolves the issue.

Let's close, should be fixed, if somebody faced with this issue again, feel free to open the new issue, in most cases this error, means you have invalid publicPath

r4j4h commented

Just to keep things together I think #2164 (comment) might be related

@alexander-akait doesn't webpack-dev-server automatically choose the port if you don't provide one and the default is already used? To have a configuration that is the most flexible, following webpack's behavior, is it possible to set the correct publicPath dynamically to reflect the dev server's current port?