Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webpack dev server cannot load nested urls (GET 404 error)

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.

like image 884
Warren Avatar asked May 03 '15 06:05

Warren


2 Answers

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>

like image 94
Warren Avatar answered Sep 28 '22 07:09

Warren


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.

like image 22
jmancherje Avatar answered Sep 28 '22 07:09

jmancherje