Skip to content

Commit fa25d76

Browse files
refactor: remove hmr option in favor Hot Module Replacement
1 parent b935f26 commit fa25d76

File tree

7 files changed

+5987
-63
lines changed

7 files changed

+5987
-63
lines changed

README.md

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,6 @@ module.exports = {
297297
// you can specify a publicPath here
298298
// by default it uses publicPath in webpackOptions.output
299299
publicPath: '../',
300-
hmr: process.env.NODE_ENV === 'development', // webpack 4 only
301300
},
302301
},
303302
'css-loader',
@@ -356,32 +355,37 @@ Here is an example to have both HMR in `development` and your styles extracted i
356355

357356
(Loaders options left out for clarity, adapt accordingly to your needs.)
358357

358+
You should not use `HotModuleReplacementPlugin` plugin if you are using a `webpack-dev-server`.
359+
`webpack-dev-server` enables / disables HMR using `hot` option.
360+
359361
**webpack.config.js**
360362

361363
```js
364+
const webpack = require('webpack');
362365
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
363366
const devMode = process.env.NODE_ENV !== 'production';
364367

368+
const plugins = [
369+
new MiniCssExtractPlugin({
370+
// Options similar to the same options in webpackOptions.output
371+
// both options are optional
372+
filename: devMode ? '[name].css' : '[name].[hash].css',
373+
chunkFilename: devMode ? '[id].css' : '[id].[hash].css',
374+
}),
375+
];
376+
if (devMode) {
377+
// only enable hot in development
378+
plugins.push(new webpack.HotModuleReplacementPlugin());
379+
}
380+
365381
module.exports = {
366-
plugins: [
367-
new MiniCssExtractPlugin({
368-
// Options similar to the same options in webpackOptions.output
369-
// both options are optional
370-
filename: devMode ? '[name].css' : '[name].[hash].css',
371-
chunkFilename: devMode ? '[id].css' : '[id].[hash].css',
372-
}),
373-
],
382+
plugins,
374383
module: {
375384
rules: [
376385
{
377386
test: /\.(sa|sc|c)ss$/,
378387
use: [
379-
{
380-
loader: MiniCssExtractPlugin.loader,
381-
options: {
382-
hmr: process.env.NODE_ENV === 'development', // webpack 4 only
383-
},
384-
},
388+
MiniCssExtractPlugin.loader,
385389
'css-loader',
386390
'postcss-loader',
387391
'sass-loader',
@@ -404,20 +408,30 @@ While we attempt to hmr css-modules. It is not easy to perform when code-splitti
404408
`reloadAll` is an option that should only be enabled if HMR isn't working correctly.
405409
The core challenge with css-modules is that when code-split, the chunk ids can and do end up different compared to the filename.
406410

411+
You should not use `HotModuleReplacementPlugin` plugin if you are using a `webpack-dev-server`.
412+
`webpack-dev-server` enables / disables HMR using `hot` option.
413+
407414
**webpack.config.js**
408415

409416
```js
417+
const webpack = require('webpack');
410418
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
411419

420+
const plugins = [
421+
new MiniCssExtractPlugin({
422+
// Options similar to the same options in webpackOptions.output
423+
// both options are optional
424+
filename: devMode ? '[name].css' : '[name].[hash].css',
425+
chunkFilename: devMode ? '[id].css' : '[id].[hash].css',
426+
}),
427+
];
428+
if (devMode) {
429+
// only enable hot in development
430+
plugins.push(new webpack.HotModuleReplacementPlugin());
431+
}
432+
412433
module.exports = {
413-
plugins: [
414-
new MiniCssExtractPlugin({
415-
// Options similar to the same options in webpackOptions.output
416-
// both options are optional
417-
filename: '[name].css',
418-
chunkFilename: '[id].css',
419-
}),
420-
],
434+
plugins,
421435
module: {
422436
rules: [
423437
{
@@ -426,8 +440,6 @@ module.exports = {
426440
{
427441
loader: MiniCssExtractPlugin.loader,
428442
options: {
429-
// only enable hot in development (webpack 4 only)
430-
hmr: process.env.NODE_ENV === 'development',
431443
// if hmr does not work, this is a forceful method.
432444
reloadAll: true,
433445
},

src/loader.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ export function pitch(request) {
241241

242242
let resultSource = `// extracted by ${pluginName}`;
243243

244-
resultSource += options.hmr
244+
resultSource += this.hot
245245
? hotLoader(result, { context: this.context, options, locals })
246246
: result;
247247

test/TestCases.test.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,43 @@ describe('TestCases', () => {
150150
`webpack-${webpack.version[0]}`
151151
);
152152

153+
if (/^hmr/.test(directory)) {
154+
let res = fs
155+
.readFileSync(path.resolve(outputDirectoryForCase, 'main.js'))
156+
.toString();
157+
158+
const date = Date.now().toString().slice(0, 6);
159+
const dateRegexp = new RegExp(`${date}\\d+`, 'gi');
160+
161+
res = res.replace(dateRegexp, '');
162+
163+
if (webpack.version[0] === '4') {
164+
const matchAll = res.match(/var hotCurrentHash = "([\d\w].*)"/i);
165+
const replacer = new Array(matchAll[1].length);
166+
167+
res = res.replace(
168+
/var hotCurrentHash = "([\d\w].*)"/i,
169+
`var hotCurrentHash = "${replacer.fill('x').join('')}"`
170+
);
171+
} else {
172+
const matchAll = res.match(
173+
/__webpack_require__\.h = \(\) => "([\d\w].*)"/i
174+
);
175+
176+
const replacer = new Array(matchAll[1].length);
177+
178+
res = res.replace(
179+
/__webpack_require__\.h = \(\) => "([\d\w].*)"/i,
180+
`__webpack_require__.h = () => "${replacer.fill('x').join('')}"`
181+
);
182+
}
183+
184+
fs.writeFileSync(
185+
path.resolve(outputDirectoryForCase, 'main.js'),
186+
res
187+
);
188+
}
189+
153190
if (fs.existsSync(expectedDirectoryByVersion)) {
154191
compareDirectory(
155192
outputDirectoryForCase,

0 commit comments

Comments
 (0)