108

I'm trying to use webpack-dev-server to compile files and start up a dev web server.

In my package.json I have the script property set to:

"scripts": {
  "dev": "webpack-dev-server --hot --inline",
 }

So the --hot and --inline should enable the webserver and the hot reloading (as I understand it).

In my webpack.config.js file I set the entry, output, and devServer settings as well as add a loader to look for changes in .vue files:

module.exports = {
    entry: './src/index.js',
    output: {
        path: __dirname + '/public',
        publicPath: '/public',
        filename: 'bundle.js'
    },
    devtool: 'source-map',
    devServer:{
        contentBase: __dirname + '/public'
    },
    module:{
        loaders:[
            { test: /\.vue$/, loader: 'vue'}
        ]
    }
};

So with this setup, I run npm run dev. The webpack-dev-server starts up, the module loader test works (i.e. when I save any .vue file it causes webpack to recompile), but:

  • The browser never refreshes
  • The compiled javascript that gets stored in memory is never made available to the browser

On that second bullet, I can see this because in the browser window the vue placeholders are never replaced and if I open up the javascript console the Vue instance is never created or made available globally.

Gif of issue

What am I missing?

Community
  • 1
  • 1
Chris Schmitz
  • 20,160
  • 30
  • 81
  • 137
  • I think you have not made your webpack working properly, bundle.js is missing in your browser console. After that, you should have a clear look at the hot module replacement docs https://webpack.github.io/docs/webpack-dev-server.html#hot-module-replacement, suggest you start with the CLI mode first – mygoare Mar 17 '16 at 03:21
  • 6
    I did read through the documentation as I was building it out and personally I find the explanation a bit convoluted. Also when I stepped through the example they give in a fresh project it doesn't work. That said, I did some component isolation testing and figured out what was with the config. I'm going to type up a detailed answer today at lunch. – Chris Schmitz Mar 17 '16 at 14:02

15 Answers15

81

Two things were causing my problems here:

module.exports = {
    entry: './src/index.js',
    output: {

        // For some reason, the `__dirname` was not evaluating and `/public` was
        // trying to write files to a `public` folder at the root of my HD.
        path: __dirname + '/public', 

        // Public path refers to the location from the _browser's_ perspective, so 
        // `/public' would be referring to `mydomain.com/public/` instead of just
        // `mydomain.com`.
        publicPath: '/public',
        filename: 'bundle.js'
    },
    devtool: 'source-map',
    devServer:{

        // `contentBase` specifies what folder to server relative to the 
        // current directory. This technically isn't false since it's an absolute
        // path, but the use of `__dirname` isn't necessary. 
        contentBase: __dirname + '/public'
    },
    module:{
        loaders:[
            { test: /\.vue$/, loader: 'vue'}
        ]
    }
};

Here's the fixed webpack.config.js:

var path = require('path');

module.exports = {
    entry: [
        './src/PlaceMapper/index.js'
    ],
    output:{
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'public/')
    },
    devtool: 'source-map',
    devServer:{
        contentBase: 'public'
    },
    module:{
        loaders:[
            { test: /\.vue$/, loader: 'vue'}
        ]
    }
};
Chris Schmitz
  • 20,160
  • 30
  • 81
  • 137
  • 10
    The "publicPath" option is the most confusing part for dev server. Rules of thumb: if you did not set "publicPath" in the "output" block(webpack config), do not set the "publicPath" option in for your dev server – Alan Oct 04 '16 at 12:24
  • Thanks for mentioning the "publicPath" option. This really helped me! – Benny Code Aug 30 '17 at 22:25
  • 3
    The webpack guys should have your on their payroll! This is by far the best documentation on how to setup the server I have seen even a year later. – Ernie S Jan 24 '18 at 12:53
  • 1
    If this doesn't work for you, see also: https://github.com/webpack/webpack-dev-server/issues/875#issuecomment-362101506 and https://github.com/webpack/webpack-dev-server/issues/875#issuecomment-450073932 . – Yngvar Kristiansen Jan 09 '19 at 19:20
  • https://medium.com/code-oil/burning-questions-with-answers-to-why-webpack-dev-server-live-reload-does-not-work-6d6390277920 this helped me understand why it wasn't working. In my case I had publicPath set to '/' when it should have been '/js-lib/' and thats the reason it was never picking file changes, because I was serving static files in js-lib instead of the **in-memory** file in 'http:localhost:9001' + '/' (your webpack-dev-server host + publicPath) – Herz3h Jun 25 '20 at 06:29
24

After a long search I found the solution for my problem, in my case output path wasn't configured correctly.

This configuration solved my problem:

const path = require('path');

module.exports = {
  "entry": ['./app/index.js'],
  "output": {
    path: path.join(__dirname, 'build'),
    publicPath: "/build/",
    "filename": "bundle.js"
  }....
Serdar D.
  • 3,055
  • 1
  • 30
  • 23
  • 10
    Adding the publicPath property fixed it for me – Borjante Sep 04 '17 at 12:11
  • 1
    The problem was solved by adding a slash before the folder name in the publicPath property. ` output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist/'), publicPath: '/dist', }` – n4ks Feb 25 '21 at 13:01
21

the right solution

Tell dev-server to watch the files served by the devServer.watchContentBase option.

It is disabled by default.

When enabled, file changes will trigger a full page reload.

Example:

module.exports = {
  //...
  devServer: {
    // ...
    watchContentBase: true
  }
};
Shakiba Moshiri
  • 21,040
  • 2
  • 34
  • 44
  • 3
    I have tried by hours, your suggestion works finally. Dear Developers, Actually HMR worked for my project. But I associated webpack-dev-server with firebase-serve via proxy. When I apply this suggestion, my problem has been resolved. So thanks. – Arda Zaman Feb 15 '20 at 18:32
12

I also had a problem with my devserver which stopping working. Previously it had worked, then I added a ton of extras to get a production build. Then when I came back to devserver it didn't work any more.

Took lots of sleuthing - eventually starting with a prior commit in git, then reintroducing changes one-by-one until I figured it out.

Turns out it was a change I had made to package.json, specifically this line:

  "browserslist": "> 1%, not dead",

This was useful to guide postcss, regarding the browsers to target.

But, it stops devserver working. Workaround is to add this to the dev webpack config:

target: 'web', 

I found the solution here: https://github.com/webpack/webpack-dev-server/issues/2812

Hope that saves someone a few hours of trouble!

curious_monk
  • 143
  • 1
  • 6
6

Somehow, for my case, removing "--hot" makes it work. So, I removed hot: true

webpack.dev.js

module.exports = merge(common, {
  mode: 'development',
  devtool: 'inline-source-map',
  devServer: {
    publicPath: '/js/',
    contentBase: path.resolve(__dirname, 'docs'),
    watchContentBase: true,
  }
});

webpack.common.js

  output: {
    path: path.resolve(__dirname, 'docs/js'),
    filename: '[name].min.js',
    library: ['[name]']
  },
Polv
  • 1,918
  • 1
  • 20
  • 31
4

I had the same problem and I find that in addition to all those points, we also have to put the index.html together with the output bundle.js in the same folder and set the contentBase to this folder, either the root or a subfolder.

Bing
  • 83
  • 4
4

This happened to me as well after running two different applications on the same webpack-dev-server port after one another. This happened even though the other project was shut down. When I changed to a port that had not been used it started working directly.

devServer: {
    proxy: {
        '*': {
            target: 'http://localhost:1234'
        }
    },
    port: 8080,
    host: '0.0.0.0',
    hot: true,
    historyApiFallback: true,
},

If you use Chrome like me then just open Developer Tools and click on Clear site data. You can also see if this is the problem by running the site in incognito mode.

enter image description here

Ogglas
  • 62,132
  • 37
  • 328
  • 418
3

It can happen because of ExtractTextPlugin. Deactive the ExtractTextPlugin in development mode. Use it only for production build.

Serdar D.
  • 3,055
  • 1
  • 30
  • 23
  • This was my issue. Apparently it's stated in the ExtraTextPlugin documentation that it doesn't support hot reload. You might want to try this though: https://stackoverflow.com/a/49932664/1319182 – user1319182 May 21 '19 at 23:58
1

I experienced a similar situation where webpack-dev-server was serving my index.html file but not updating. After reading a few posts I realized that webpack-dev-server does not generate a new js file but instead injects one into index.html.

I added the html-webpack-plugin to my app and with the following configuration in my webpack.config.js file:

const HtmlWebpackPlugin = require('html-webpack-plugin')

plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.html',
      inject: true
    })
  ]

I then commented out the script tag referencing my entry js file in index.html. I can now run webpack-dev-server without any additional flags and any changes to my files will display in the browser instantly.

nflauria
  • 847
  • 13
  • 22
0

My case was that I got so deep into experimenting with Webpack features, but totally forgot that I had set inject to be false the entire time like so...

 new HTMLWebpackPlugin({
        inject: false,
        ...
 }),

Switching that on was my ticket.

klewis
  • 7,459
  • 15
  • 58
  • 102
0

I'll add my own special tale of Webpack --watch woe to the wall of suffering here.

I was running

webpack --watch

in order to build a Typescript project. The compiled .js files would update, but the bundle that the browser was seeing would not. So I was basically in the same position as the OP.

My problem came down to the watchOptions.ignored parameter. The original author of the build config had set up ignored as a filter function, which turns out to not be a valid value for that parameter. Replacing the filter function with an appropriate RegExp got the --watch build working again for me.

tel
  • 13,005
  • 2
  • 44
  • 62
0

What worked for me:

cache: false

https://webpack.js.org/configuration/cache/

Warning: Re-compiling may take huge amount of time, especially in large repos.

laggingreflex
  • 32,948
  • 35
  • 141
  • 196
  • I had the scenario where the first save updated correctly, but subsequent changes were ignored. This answer sorted my problem. – Neil Stenton Jun 07 '22 at 08:36
  • This is not the desired state, are re-compiling will take huge amount of time, especially in large repos – konsalex Apr 05 '23 at 13:19
  • @konsalex Good catch! I've added that as a warning. I resorted to this only because none of the other solutions here worked for me. – laggingreflex Apr 06 '23 at 14:50
0

What helped me was introducing devServer.devMiddleware. For example, in webpack-dev-server 4.10.0, property contentBase was not available anymore.

devServer: {
 devMiddleware: {
  index: true,
  publicPath: './build/static/',
  serverSideRender: true,
  writeToDisk: true,
 }
},
MaxLAB
  • 13
  • 9
0

This is an old question and most config options got renamed by now in webpack-cli v5. However the one that worked for me was {watchFiles}

  • options.watchFiles should be one of these: [non-empty string | object { paths?, options? }, ...] | non-empty string | object { paths?, options? } -> Allows to configure list of globs/directories/files to watch for file changes. -> Read more at https://webpack.js.org/configuration/dev-server/#devserverwatchfiles
    Details:
    • options.watchFiles should be an array: [non-empty string | object { paths?, options? }, ...]
    • options.watchFiles should be a non-empty string.
    • options.watchFiles should be an object: object { paths?, options? }
  devServer: {
    watchFiles: "./src/index.html",
    ...
  }
Orkan
  • 76
  • 4
-1

Your project tree is not clear, however the problem may be in contentBase setting. Try to set contentBase: __dirname