Skip to content

Commit d6736cc

Browse files
refactor: remove hmr option in favor Hot Module Replacement
1 parent f9c75ac commit d6736cc

File tree

10 files changed

+6958
-53
lines changed

10 files changed

+6958
-53
lines changed

README.md

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,6 @@ module.exports = {
218218
// you can specify a publicPath here
219219
// by default it uses publicPath in webpackOptions.output
220220
publicPath: '../',
221-
hmr: process.env.NODE_ENV === 'development',
222221
},
223222
},
224223
'css-loader',
@@ -280,29 +279,32 @@ Here is an example to have both HMR in `development` and your styles extracted i
280279
**webpack.config.js**
281280

282281
```js
282+
const webpack = require('webpack');
283283
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
284284
const devMode = process.env.NODE_ENV !== 'production';
285285

286+
const plugins = [
287+
new MiniCssExtractPlugin({
288+
// Options similar to the same options in webpackOptions.output
289+
// both options are optional
290+
filename: devMode ? '[name].css' : '[name].[hash].css',
291+
chunkFilename: devMode ? '[id].css' : '[id].[hash].css',
292+
}),
293+
];
294+
295+
if (devMode) {
296+
// only enable hot in development
297+
plugins.push(new webpack.HotModuleReplacementPlugin());
298+
}
299+
286300
module.exports = {
287-
plugins: [
288-
new MiniCssExtractPlugin({
289-
// Options similar to the same options in webpackOptions.output
290-
// both options are optional
291-
filename: devMode ? '[name].css' : '[name].[hash].css',
292-
chunkFilename: devMode ? '[id].css' : '[id].[hash].css',
293-
}),
294-
],
301+
plugins: plugins,
295302
module: {
296303
rules: [
297304
{
298305
test: /\.(sa|sc|c)ss$/,
299306
use: [
300-
{
301-
loader: MiniCssExtractPlugin.loader,
302-
options: {
303-
hmr: process.env.NODE_ENV === 'development',
304-
},
305-
},
307+
MiniCssExtractPlugin.loader,
306308
'css-loader',
307309
'postcss-loader',
308310
'sass-loader',
@@ -323,20 +325,32 @@ While we attempt to hmr css-modules. It is not easy to perform when code-splitti
323325
`reloadAll` is an option that should only be enabled if HMR isn't working correctly.
324326
The core challenge with css-modules is that when code-split, the chunk ids can and do end up different compared to the filename.
325327

328+
You should not use this plugin if you are using a `webpack-dev-server`.
329+
`webpack-dev-server` enables / disables HMR using `hot` option.
330+
326331
**webpack.config.js**
327332

328333
```js
334+
const webpack = require('webpack');
329335
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
336+
const devMode = process.env.NODE_ENV !== 'production';
337+
338+
const plugins = [
339+
new MiniCssExtractPlugin({
340+
// Options similar to the same options in webpackOptions.output
341+
// both options are optional
342+
filename: devMode ? '[name].css' : '[name].[hash].css',
343+
chunkFilename: devMode ? '[id].css' : '[id].[hash].css',
344+
}),
345+
];
346+
347+
if (devMode) {
348+
// only enable hot in development
349+
plugins.push(new webpack.HotModuleReplacementPlugin());
350+
}
330351

331352
module.exports = {
332-
plugins: [
333-
new MiniCssExtractPlugin({
334-
// Options similar to the same options in webpackOptions.output
335-
// both options are optional
336-
filename: '[name].css',
337-
chunkFilename: '[id].css',
338-
}),
339-
],
353+
plugins: plugins,
340354
module: {
341355
rules: [
342356
{
@@ -345,8 +359,6 @@ module.exports = {
345359
{
346360
loader: MiniCssExtractPlugin.loader,
347361
options: {
348-
// only enable hot in development
349-
hmr: process.env.NODE_ENV === 'development',
350362
// if hmr does not work, this is a forceful method.
351363
reloadAll: true,
352364
},

src/loader-options.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@
1515
"esModule": {
1616
"type": "boolean"
1717
},
18-
"hmr": {
19-
"type": "boolean"
20-
},
2118
"reloadAll": {
2219
"type": "boolean"
2320
}

src/loader.js

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

219219
let resultSource = `// extracted by ${pluginName}`;
220220

221-
resultSource += options.hmr
221+
resultSource += this.hot
222222
? hotLoader(result, { context: this.context, options, locals })
223223
: result;
224224

test/TestCases.test.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,40 @@ describe('TestCases', () => {
9595
`webpack-${webpack.version[0]}`
9696
);
9797

98+
if (/^hmr/.test(directory)) {
99+
let res = fs
100+
.readFileSync(path.resolve(outputDirectoryForCase, 'main.js'))
101+
.toString();
102+
103+
if (webpack.version[0] === '4') {
104+
const matchAll = res.match(/var hotCurrentHash = "([\d\w].*)"/i);
105+
const replacer = new Array(matchAll[1].length);
106+
107+
res = res.replace(
108+
/var hotCurrentHash = "([\d\w].*)"/i,
109+
`var hotCurrentHash = "${replacer.fill('x').join('')}"`
110+
);
111+
} else {
112+
const matchAll = res.match(
113+
/__webpack_require__\.h = \(\) => "([\d\w].*)"/i
114+
);
115+
116+
const replacer = new Array(matchAll[1].length);
117+
118+
res = res.replace(
119+
/__webpack_require__\.h = \(\) => "([\d\w].*)"/i,
120+
`__webpack_require__.h = () => "${replacer.fill('x').join('')}"`
121+
);
122+
}
123+
124+
res = res.replace(/\/\/ \d*\n/gim, '// replased\n');
125+
126+
fs.writeFileSync(
127+
path.resolve(outputDirectoryForCase, 'main.js'),
128+
res
129+
);
130+
}
131+
98132
if (fs.existsSync(expectedDirectoryByVersion)) {
99133
compareDirectory(
100134
outputDirectoryForCase,

test/__snapshots__/validate-loader-options.test.js.snap

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@ exports[`validate options should throw an error on the "esModule" option with "1
55
- options.esModule should be a boolean."
66
`;
77

8-
exports[`validate options should throw an error on the "hmr" option with "1" value 1`] = `
9-
"Invalid options object. Mini CSS Extract Plugin Loader has been initialized using an options object that does not match the API schema.
10-
- options.hmr should be a boolean."
11-
`;
12-
138
exports[`validate options should throw an error on the "publicPath" option with "true" value 1`] = `
149
"Invalid options object. Mini CSS Extract Plugin Loader has been initialized using an options object that does not match the API schema.
1510
- options.publicPath should be one of these:

0 commit comments

Comments
 (0)