I am using webpack and the HtmlWebpackPlugin to inject bundled js and css into an html template file.
new HtmlWebpackPlugin({
template: 'client/index.tpl.html',
inject: 'body',
filename: 'index.html'
}),
And it produces the following html file.
<!doctype html>
<html lang="en">
<head>
...
<link href="main-295c5189923694ec44ac.min.css" rel="stylesheet">
</head>
<body>
<div id="app"></div>
<script src="main-295c5189923694ec44ac.min.js"></script>
</body>
</html>
This works fine when visiting the root of the app localhost:3000/, but fails when I try to visit the app from another URL, for example, localhost:3000/items/1 because the bundled files are not injected with an absolute path. When the html file is loaded, it will look for the js file inside the non-exist /items directory because react-router hasn't loaded yet.
How can I get HtmlWebpackPlugin to inject the files with an absolute path, so express will look for them at the root of my /dist directory and not at /dist/items/main-295c5189923694ec44ac.min.js? Or maybe I can change my express server to work around the issue?
app.use(express.static(__dirname + '/../dist'));
app.get('*', function response(req, res) {
res.sendFile(path.join(__dirname, '../dist/index.html'));
});
I found the solution to my issue. It works if I add output.publicPath = '/' to my webpack config, as suggested by Magnus Sjungare on StackOverflow.
@aherriot thanks you saved my day
Great, thank you! Webpack configuration is vague, as usual :-)
My build includes the protocol, host and even port hardcoded. That works for localhost, but as soon as I want to deploy it to a public test server. It's broken:
Mixed Content: The page at 'https://helios-isufgnuhwy.now.sh/' was loaded over HTTPS, but requested an insecure script 'http://localhost:8080/app.c449ece83e150f803b0b.js'. This request has been blocked; the content must be served over HTTPS.
html
<!DOCTYPE html>
<html lang="de-CH">
<head>
<title>Helios</title>
<meta charset="utf-8">
<meta content="width=device-width,initial-scale=1,shrink-to-fit=no,user-scalable=no,minimum-scale=1,maximum-scale=1" name="viewport">
<link href="http://localhost:8080/favicon.ico" rel="shortcut icon">
</head>
<body>
<div id="cqcanvas">
<div data-helios="" data-helios-api="/api/bot.de.json" data-helios-cta-url="https://www.axa.ch/de/formulare/beratungsanfrage.html?overwriteData=_4CGPh5MCR-PI3pYy9Vy5Us1glbOicneVALmq2Atza8" data-helios-i18n-url="/i18n/de.json" data-helios-locale="de-CH" data-prefill="{ "GENDER": "MALE", "NAME": "Test" }"></div>
</div>
<script src="http://localhost:8080/vendor.c449ece83e150f803b0b.js" type="text/javascript">
</script>
<script src="http://localhost:8080/app.c449ece83e150f803b0b.js" type="text/javascript">
</script>
</body>
</html>
Instead he protocol, host and port should be omitted, because they will be automatically provided by the browser itself and correctly.
Seems that NODE_ENV was not set to "production" on my test deployment...
@aherriot is the best answer according my situation , it will not break the hot-reload don't worry
entry: {
//....
},
output: {
publicPath: '/'
}
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
I found the solution to my issue. It works if I add
output.publicPath = '/'to my webpack config, as suggested by Magnus Sjungare on StackOverflow.