I'm currently setting up a site that uses a webpack-dev-server and a backbone router.
Until today, everything seemed to be working (for example I could go to http://localhost:3333
for my home page and http://localhost:3333/login
for my login page.
But today I tried to go to my first nested url, http://localhost:3333/people/1
, and my console throw a 404 GET error.
The exact error was this:
http://localhost:3333/people/build/bundle.js 404 (Not Found)
It seems that my webpack server is trying to look for the correct files to server under the wrong directory. If this is correct, I have no idea how to fix this. I've looked at other stack overflow questions and github issues, but to no avail. Any thoughts?
I start the server using gulp. Here is my gulpfile:
var gulp = require("gulp");
var webpack = require("webpack");
var server = require("webpack-dev-server");
var config = require("./webpack.config");
gulp.task("serve", function() {
new server(webpack(config), {
publicPath: config.output.publicPath,
historyApiFallback: true,
hot: true,
quiet: false,
stats: { colors: true, progress: true },
}).listen(3333, "localhost", function (err, result) {
if (err) {
console.log(err);
} else {
console.log("Listening at localhost:3333!");
}
});
});
gulp.task("default", ["serve"]);
Here is my webpack config file:
var webpack = require("webpack");
module.exports = {
entry: [
__dirname + "/app/app.js",
"webpack/hot/dev-server",
"webpack-dev-server/client?http://localhost:3333/",
],
output: {
path: __dirname + "/build",
filename: "bundle.js",
publicPath: "http://localhost:3333/",
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
module: {
loaders: [
{ test: /\.jsx$/, exclude: /node_modules/, loader: "react-hot-loader!babel-loader" },
{ test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" },
{ test: /\.scss$/, exclude: /node_modules/, loader: "style!css!sass" },
]
},
resolve: {
root: __dirname,
extensions: ["", ".js", ".jsx"],
},
}
Edit: I've just found that I can directly hit the urls http://localhost:3333/#/people/1
or http://localhost:3333/#people/1
and everything works as expected.
Is there a setup that will allow me to not have to include the pound symbol in the url? Hope this helps give more context to my question.
Follow up: I have a global App
component that initializes a backbone router and calls Backbone.history.start({ pushState: true })
. Here's a code snippet.
class App {
constructor() {
console.log("starting up");
this.Router = new Router();
Backbone.history.start({ pushState: true });
}
}
module.exports = new App();
If you notice the console.log
in the constructor, this is called on non-nested pages that can render but not on nested pages that cannot.
I found the answer to my problem finally.
My index.html file that was loaded on every page used to look like this:
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
<script type="text/javascript" src="./build/bundle.js" charset="utf-8"></script>
</body>
</html>
Because the source of the script was a relative path, the script couldn't be found on nested urls.
Changing the source to this fixed it:
<script type="text/javascript" src="http://localhost:3333/build/bundle.js" charset="utf-8"></script>
I know this question has already been answered but I had the exact same problem and I thought I'd share my situation. Just like Warren's chosen solution, the bug was on my index.html. It originally looked like this:
<script src="./bundle.js"></script>
I saw the solution listed here to put in the full path but that won't work for me because I'd like to run this locally and in production. I simply changed it to look like this: (removed the '.')
<script src="/bundle.js"></script>
And it completely fixed the bug for me.
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