Webpack-dev-server compiles files but does not refresh or make compiled javascript available to browser
JavascriptWebpackvue.jsWebpack Dev-ServerJavascript Problem Overview
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.
What am I missing?
Javascript Solutions
Solution 1 - Javascript
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'}
]
}
};
Solution 2 - Javascript
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"
}....
Solution 3 - Javascript
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
}
};
Solution 4 - Javascript
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!
Solution 5 - Javascript
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]']
},
Solution 6 - Javascript
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.
Solution 7 - Javascript
It can happen because of ExtractTextPlugin. Deactive the ExtractTextPlugin in development mode. Use it only for production build.
Solution 8 - Javascript
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.
Solution 9 - Javascript
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.
Solution 10 - Javascript
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.
Solution 11 - Javascript
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.
Solution 12 - Javascript
Your project tree is not clear, however the problem may be in contentBase setting. Try to set contentBase: __dirname
Solution 13 - Javascript
If you have any errors in your code reload wouldn't work. Spent 1 hour realise it
Solution 14 - Javascript
devServer:{ watchContentBase: true }