Reputation: 11431
I have a front-end application bundled with webpack, which is served by and talks to a Node backend server.
Webpack hot dev server is running on 8080
.
Node backend is running on 1985
.
I want to serve index.html
from Node, but want assets served from the hot dev server during development. To achieve this I have:
Set an absolute publicPath value in webpack config:
output: {
publicPath: 'http://localhost:8080/'
},
And used absolute URLs in index.html
to point to the hot dev server:
<script src="http://localhost:8080/webpack-dev-server.js"></script>
<script src="http://localhost:8080/js/vendors.js"></script>
<script src="http://localhost:8080/js/bundle.js"></script>
So I can run the hot dev server and run my Node server and browse to http://localhost:1985
. Everything is great.
But when I come to deploy / run in production, this is definitely not what I want. I'd like relative URLs for vendors.js
and bundle.js
and I definitely don't want to include the webpack-dev-server.js
script.
I could use Handlebars or some other templating on the server to specify the absolute / relative paths, but it wouldn't provide a clean way of removing the hot dev server script. I could also have different index files for each setup, but this seems like it would quickly lead to bugs.
How can this be best be structured / deployed to enable use of the hot dev server in development, while still allowing for the whole thing to be deployed and served via Node in production?
Upvotes: 2
Views: 1319
Reputation: 7033
For this very reason I stopped using webpack-dev-server
and instead use the combination of webpack-dev-middleware
/ webpack-hot-middleware
as the latter allow you to mount them in an existing express server.
My server basically does this:
const express = require('express');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');
const config = require('./webpack.config.js');
const app = express();
if (process.env.WEBPACK_DEV_SERVER === 'true') {
const config = webpack(config);
app.use(webpackDevMiddleware(compiler));
app.use(webpackHotMiddleware(compiler));
} else {
app.use(express.static(path.join(__dirname, './dist'));
}
app.use((req, res) => {
res.status(200).send(`
<!doctype html>
<html>
<head>
<title>App</title>
</head>
<body>
<div id="root"></div>
<script src="/bundle.js"></script>
</body>
</html>
`);
});
You can see a complete example in the 60fram.es react boilerplate
Upvotes: 0
Reputation: 11
We're currently doing the templating approach you suggested for the paths and sorta mitigated the ugliness of the webpack-dev-server.js script tag by introducing an environment variable that specifies whether or not we're 'building' or 'developing'.
If you're using gulp as a task runner (we are), you can set them with process.env.NAME = VALUE
.
If you're using npm builds you can add them via the command line with --NAME VALUE
.
The very last step for our backend server then is to create the variables that then fit into our index.html template:
<%
// connect the hot-reload dev server
if (mode === 'dev') {
print("<script type='text/javascript' src='" + webpackURL + "/webpack-dev-server.js'></script>");
}
%>
<script type="text/javascript" src="<%= webpackURL %>/js/bundle.js"></script>
Upvotes: 1