Webpack - [HMR] Hot Module Replacement is disabled - javascript

I've looked around, but can't get any of the answers I've seen on stackoverflow to work.
I cannot use the command line for webpack or the webpack dev-server; I am restricted to using the Node API.
Below is how I am using webpack.
webpack.config.js
module.exports = {
entry: [
'webpack-dev-server/client?http://localhost:3000',
// i've also tried webpack/hot/dev-server here
'webpack/hot/only-dev-server',
path.join(__dirname, 'src', 'js', 'app.jsx')
],
output: {
path: path.join(__dirname, 'dist', 'js'),
filename: 'script.js',
publicPath: '/dist/'
},
module: {
loaders: [{
test: /\.(js|jsx)$/,
loaders: ['react-hot', 'babel']
}]
},
plugins: []
};
contained in a gulp task "start"
gulp.task('start', function (callback) {
var config = Object.create(require('webpack.config.js'));
config.plugins.push(new webpack.HotModuleReplacementPlugin());
var devServer = new webpackDevServer(webpack(config), {
stats: { colors: true },
contentBase: path.resolve(__dirname, 'dist'),
progress: true,
inline: true,
hot: true
});
});
What I expect
When I run gulp start, I expect the webpack dev server to spin up, allowing me to hit localhost:3000/. This should load an index.html from my project's /dist/ folder. So far so good. I expect that when I make a change to a file (e.g., app.jsx), that the change would be present.
What is actually happening
I am getting the error "[HMR] Hot Module Replacement is disabled", with no further explanation.
Any help would be appreciated. I have been trying to get hot reloading working for a full day.

in your webpack.config.js on the plugins section try this,
plugins: [new webpack.HotModuleReplacementPlugin()]
I know you are pushing the plugin in your gulp task but you have to use --hot --inline on cli or on your npm script

Try to run webpack as
webpack-dev-server --hot --inline in packge.json,
somehow official docs is wrong now.

Related

webpack-dev-server not recompiling (JS files AND SCSS files)

Good morning,
Rise and shine, the sun is already high in the sky and webpack is ruining my day!
I'm using webpack-dev-server (through a script in packages.json):
"scripts": {
"dev-server": "webpack-dev-server",
}
That I run with yarn run dev-server
What I want is the code to recompile and the browser to refresh whenever I save a file. I can live with the fact that it doesn't work with SCSS files, but recompiling "manually" on each change in my components is just physically painful. I tried a lot of solution found online (non-exhaustive list coming) before asking here, but the result is always the same:
ℹ 「wdm」: Compiled successfully
And nothing happens when I modify a file (JS or SCSS).
This is a simple React app, with SCSS for styling.
Here is my webpack config:
const path = require('path');
const MiniCSSExtractPlugin = require('mini-css-extract-plugin');
const mode = process.env.NODE_ENV || 'development';
module.exports = env => {
return {
entry: ['babel-polyfill', './src/app.js'],
output: {
path: path.join(__dirname, 'public', 'dist'),
filename: 'bundle.js'
},
module: {
rules: [{
loader: 'babel-loader',
test: /\.js$/,
exclude: /node_modules/
}, {
test: /\.s?css$/,
loader: [
mode === 'development' ? 'style-loader' : MiniCSSExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
}
]
},
plugins: [
new MiniCSSExtractPlugin({ filename: 'styles.css' })
],
devtool: env === 'production' ? 'source-map' : 'cheap-module-eval-source-map',
devServer: {
contentBase: path.join(__dirname, 'public'),
publicPath: '/dist/'
}
};
};
Here a list of things I tried:
Add --output-public-path=/dist/ to the script
Use the following content to the devServer config in webpack.config.js:
host: '0.0.0.0',
contentBase: path.join(__dirname, 'public'),
publicPath: '/dist/',
historyApiFallback: true,
compress: true,
port: 8080,
watchContentBase: true,
inline: true,
hot: true
Use HtmlWebpackConfig with the following config:
new HtmlWebpackPlugin({
title: 'Prognostic',
filename: './public/dist/index.html',
template: './public/index.html'
})
Remove / add webpack and webpack-dev-server
Use a global webpack-dev-server instead of the project one (npm i -g webpack-dev-server)
Certainly more things but I don't remember... Whoops
For information, here are the version I use:
Babel-loader#7
react#^16.8.6,
webpack-dev-server#^3.9.0
webpack#^4.41.2
So, I'd like two things to happen:
Automatic recompile when JS file changed
Automatic recompile when SCSS file changed (if possible)
If you can help me do that, I'll nominate you my Santa Dev of the year (yes, you can add that to your CV)
Thank you!
PS: great laugh when Grammarly told me that my text sounds "friendly"
Webpack dev server adds a watcher on your files to trigger the compilation when they have been modified.
Sometimes though, depending on the text editor you are using, this won't trigger at all.
I had the same problem, using sublimetext : when I saved my code the webpack dev server wouldn't rebuild.
So instead of using the default triggering mechanism, I'm using another option of webpack :
devServer: {
hot: true,
watchOptions: {
aggregateTimeout: 300,
poll: true
},
}
Every 300ms the server will check if files have changed and if so, rebuild.
I hope I am your Santa Dev of the year :]
I don't think you can do this by webpack you need to use library like react-hot-loader

Electron-Typescript: Bundling everything

I'm trying to create a web app using electron written in Typescript. I'm having problems when building my application. Specifically, I am not sure on how to combine: tsc (To convert my .ts file to .js) and then electron dist/main.js. Potentially, I want to run npm start which first compiles my .ts file and then run electron. Can anyone comment on what would be the best approach to achieve this?
Use ts-loader with webpack to bundle .ts files with config like below,
const path = require("path")
module.exports = {
entry: './src/index.ts',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
resolve: {
extensions: [ '.tsx', '.ts', '.js' ]
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
and then in your npm script include these,
{
"build-watch": "webpack -w",
"electron": "electon dist/main.js"
}
then start both using npm-run-all (or any other tool like concurrently),
npm-run-all start build-watch electron
I would suggest using https://webpack.electron.build/. It has instructions for adding typescript support here https://webpack.electron.build/add-ons#typescript

Webpack doesn't run clean when watch is set to true

This is my webpack.config.js file:
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const config = {
entry: {
bundle: './javascript/index.js'
},
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].[chunkhash].js'
},
module: {
rules: [
{
use: 'babel-loader',
test: /\.js$/,
exclude: /node_modules/
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
},
{
test: /\.(jpe?g|png|gif|svg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 40000
}
},
'image-webpack-loader'
]
}
]
},
plugins: [
new ExtractTextPlugin('style.css'),
new HtmlWebpackPlugin({
template: 'src/index.html'
})
],
watch: true
};
module.exports = config;
As you can tell from the last line I'm setting the watch option to true. In addition, I'm using chunkhash to generates a new javascript file when I make a change to any of my javascript files. However, it is not running my rinraf clean command when the watch option is set to 'true'.
Here is a portion of my package.json file that:
{
"name": "budgety",
"version": "1.0.0",
"description": "Budget app",
"main": "app.js",
"scripts": {
"clean": "rimraf build",
"build": "npm run clean && webpack"
},
.
.
.
Why is this happening?
My goal is to:
Have my compiled javascript be updated after I update any of my javascript files, so I don't need to run 'npm run build' every single time I make a change to my js files.
Clean the old javascript 'hashed' file which used be taken care of by 'rimraf' but for some reason it isn't cleaning the new hashed javascript files in watch mode.
The watch mode works in a way that it only recompiles the files that were changed. That's why, normally, during the watch mode the hash prefixes are not enabled (because the files are changed nearly every minute which makes it more complicated to track the changed hashes etc). In other words one should have a dev and prod environments that will behave slightly differently.
E.g. you need to pass an argument, see here how and then use them in your config file:
filename: env.withHashPrefixes ? '[name].[chunkhash].js' : '[name].js'
Now you will not need to clean anything because the filenames are always the same
Original answer
It does and it will not run your rimraf command because the watch happens inside of the webpack ind it has no idea what you did run outside of it.
Use clean-webpack-plugin which is as easy as
plugins: [
new CleanWebpackPlugin('build')
]
I've experienced the same problem that my assets in /assets/ folder were cleaned and not rebuilt when enabling output.clean.
I've worked around this by ignoring /assets/ from cleaning in webpack.config.js. However, it's not the perfect solution as obsolete assets would remain in the folder.
output: {
clean: {
keep: /assets\//,
},
},

Debugging webpack/browserify React app in IntelliJ/WebStorm

I followed almost all guides I found online and I can not make debugger in IntelliJ stop at breakpoints.
I am developing React app with router. Backend is in Play Framework.
I tried generating source map using. This is from gulpFiles:
var bundler = watchify(browserify('./frontend/app.jsx', { debug: true }).transform(babel, {
presets: ["es2015","react","stage-3"],
plugins: [
"transform-decorators-legacy",
"transform-runtime"
]
}));
Source maps were generated; I was able to debug in Chrome debugger but I am not able in IntelliJ. I only see console output.
I tried generating with webpack:
var webpack = require('webpack');
var path = require('path');
var BUILD_DIR = path.resolve(__dirname, 'public/javascripts');
var APP_DIR = path.resolve(__dirname, 'frontend');
var config = {
entry: APP_DIR + '/app.jsx',
output: {
path: BUILD_DIR,
filename: 'bundle.js'
},
module : {
loaders : [
{
test : /\.jsx?/,
include : APP_DIR,
loader : 'babel-loader'
}
]
},
devtool: "source-map"
};
module.exports = config;
Same thing I can not stop at breakpoints in IntelliJ.
I configured JavaScript debug like this:
Name: React Debug
URL: http://localhost:9000/index
Remote URLs of local files (optional) : ./frontend
Still no luck and breakpoints are not working. What am I missing??
I managed to get it working with Webpack.
I was using npm task to run webpack and instead of :
webpack -d --watch
as was suggested everywhere. I used this:
webpack --debug --output-pathinfo --watch

Webpack-dev-server compiles files but does not refresh or make compiled javascript available to browser

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?
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'}
]
}
};
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"
}....
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
}
};
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!
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]']
},
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.
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.
It can happen because of ExtractTextPlugin. Deactive the ExtractTextPlugin in development mode. Use it only for production build.
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.
What worked for me:
cache: false
https://webpack.js.org/configuration/cache/
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.
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.
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,
}
},
Your project tree is not clear, however the problem may be in contentBase setting. Try to set contentBase: __dirname

Categories