I am using webpack2 and react hot loader3 with express. I am getting an error of
Uncaught SyntaxError: Unexpected token < in dist/index.html
Here is my configuration file
webpack.config.js
const isDevelopment = process.argv.indexOf('--development') !== -1;
const VENDOR_LIBS = [
'react', 'react-dom', 'redux', 'react-redux',
'react-router', 'react-router-redux', 'lodash',
'express',
];
const entryPath = path.join(__dirname, 'src/index.js');
const config = {
entry: {
bundle: isDevelopment ? [
'webpack-hot-middleware/client?reload=true',
'react-hot-loader/patch',
entryPath
] : entryPath,
vendor: VENDOR_LIBS
},
output: {
path: path.resolve(__dirname, 'dist'),
publicPath: '',
filename: isDevelopment ? '[name].js' : '[name].[chunkhash].js',
},
module: {
rules: [
{
loader: ExtractTextPlugin.extract({
loader: 'css-loader'
}),
test: /\.css$/,
},
{
use: ['babel-loader'],
test: /\.js$/,
exclude: /node_modules/,
},
{
use: [
{
loader: 'url-loader',
options: { limit: 40000 }
},
'image-webpack-loader'
],
test: /\.(jpe?g|png|gif|svg|woff|woff2|eot|otf|ttf)$/,
},
],
},
node: {
fs: 'empty',
net: 'empty',
tls: 'empty'
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
}),
new HtmlWebpackPlugin({
inject: true,
template: 'src/index.html',
minify: {
removeComments: false,
collapseWhitespace: false,
}
}),
new ExtractTextPlugin('style.css'),
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'manifest']
}),
],
};
isDevelopment && config.plugins.push(
new webpack.optimize.UglifyJsPlugin({
output: {
comments: false,
screw_ie8: true
},
})
);
module.exports = config;
server.js
const isDevelopment = process.argv.indexOf('--development') !== -1;
if (isDevelopment) {
const webpack = require('webpack');
const webpackConfig = require('./webpack.config');
const compiler = webpack(webpackConfig);
app.use(require('webpack-dev-middleware')(compiler, {
noInfo: true,
hot: true,
stats: {
colors: true
}
}));
app.use(require('webpack-hot-middleware')(compiler));
} else {
app.use(express.static(__dirname + '/src/assets/'));
}
app.get('*', function (request, response) {
response.sendFile(__dirname + '/dist/index.html');
});
app.listen(port);
console.log(`server started on port: ${port}`);
package.json
"scripts": {
"pre-start": "webpack",
"start-dev": "node server.js --development",
"start-prod": "rimraf dist && webpack && node server.js --production"
},
"dependencies": {
"express": "^4.14.0",
"lodash": "^4.17.4",
"react": "^15.4.2",
"react-dom": "^15.4.2",
"react-redux": "^5.0.2",
"react-router": "^3.0.2",
"react-router-redux": "^4.0.7",
"redux": "^3.6.0",
"reselect": "^2.5.4"
},
"devDependencies": {
"babel-core": "^6.21.0",
"babel-loader": "^6.2.10",
"babel-preset-es2015": "^6.18.0",
"babel-preset-react": "^6.16.0",
"babel-preset-stage-3": "^6.17.0",
"css-loader": "^0.26.1",
"extract-text-webpack-plugin": "2.0.0-beta.4",
"html-webpack-plugin": "^2.26.0",
"image-webpack-loader": "^3.1.0",
"react-hot-loader": "next",
"rimraf": "^2.5.4",
"style-loader": "^0.13.1",
"webpack": "beta",
"webpack-dev-middleware": "^1.9.0",
"webpack-dev-server": "beta",
"webpack-hot-middleware": "^2.15.0"
}
}
Here is the screenshot of an error that is shown in console
What might be the cause for this error? Is it problem with htmlWebpackPlugin or extract-text-webpack-plugin?
UPDATE using publicPath and manifest.hash.js my index.html of dist will be
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Pogimon</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<script type="text/javascript" src="manifest.79b84dc7d02a392424d5.js"></script>
<script type="text/javascript" src="/manifest.6dcd342a4568f6b57de6.js"></script><script type="text/javascript" src="/vendor.a79b5bc95a09216321bd.js"></script><script type="text/javascript" src="/bundle.d03400470aaca7bf8a0d.js"></script></body>
</html>
You may be hit by a common issue which appears in combination of react-router and browser-history, when the script urls in index.html are not absolute.
Because of relative script src, if you (or Webpack reload) happen to refresh the browser when your history is on a route, the browser will now try to load the scripts from your route's url, e.g. if the route is /login
and a reload/refresh occurs, the browser will ask for /login/manifest.<hash etc>.js
and your express will then return it index.html because there's a *
route handler there :).
The fix is to change your scripts' src inside index.html to /manifest.<hash etc>.js
to make it absolute. This will ensure they are served by the static module.
More details are available in this answer - HtmlWebpackPlugin injects relative path files which breaks when loading non-root website paths.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With