Skip to content

Commit 9bfc65e

Browse files
committed
fix: avoid reload all css when hot load
1 parent 8bf0ad6 commit 9bfc65e

File tree

8 files changed

+1751
-18
lines changed

8 files changed

+1751
-18
lines changed

src/loader.js

+24-14
Original file line numberDiff line numberDiff line change
@@ -44,22 +44,31 @@ const MiniCssExtractPlugin = require("./index");
4444
* @returns {string}
4545
*/
4646
function hotLoader(content, context) {
47-
const accept = context.locals
48-
? ""
49-
: "module.hot.accept(undefined, cssReload);";
50-
47+
const localsJsonString = JSON.stringify(JSON.stringify(context.locals));
5148
return `${content}
5249
if(module.hot) {
53-
// ${Date.now()}
54-
var cssReload = require(${stringifyRequest(
55-
context.loaderContext,
56-
path.join(__dirname, "hmr/hotModuleReplacement.js")
57-
)})(module.id, ${JSON.stringify({
58-
...context.options,
59-
locals: !!context.locals,
60-
})});
61-
module.hot.dispose(cssReload);
62-
${accept}
50+
(function() {
51+
var localsJsonString = ${localsJsonString};
52+
// ${Date.now()}
53+
var cssReload = require(${stringifyRequest(
54+
context.loaderContext,
55+
path.join(__dirname, "hmr/hotModuleReplacement.js")
56+
)})(module.id, ${JSON.stringify(context.options)});
57+
// only invalidate when locals change
58+
if (
59+
module.hot.data &&
60+
module.hot.data.value &&
61+
module.hot.data.value !== localsJsonString
62+
) {
63+
module.hot.invalidate();
64+
} else {
65+
module.hot.accept();
66+
}
67+
module.hot.dispose(function(data) {
68+
data.value = localsJsonString;
69+
cssReload();
70+
});
71+
})();
6372
}
6473
`;
6574
}
@@ -554,3 +563,4 @@ function loader(content) {
554563

555564
module.exports = loader;
556565
module.exports.pitch = pitch;
566+
module.exports.hotLoaderForTest = hotLoader;

test/HMR.test.js

+26
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
/* eslint-disable no-console */
66

77
import hotModuleReplacement from "../src/hmr/hotModuleReplacement";
8+
import { hotLoaderForTest as hotLoader } from "../src/loader";
89

910
function getLoadEvent() {
1011
const event = document.createEvent("Event");
@@ -361,4 +362,29 @@ describe("HMR", () => {
361362
done();
362363
}, 100);
363364
});
365+
366+
it("hotLoader works for non-locals", () => {
367+
const o = Date.now;
368+
Date.now = () => 1;
369+
const code = hotLoader("//content;", {
370+
loaderContext: {
371+
context: __dirname,
372+
},
373+
});
374+
Date.now = o;
375+
expect(code).toMatchSnapshot();
376+
});
377+
378+
it("hotLoader works for locals", () => {
379+
const o = Date.now;
380+
Date.now = () => 1;
381+
const code = hotLoader("//content;", {
382+
loaderContext: {
383+
context: __dirname,
384+
},
385+
locals: { foo: "bar" },
386+
});
387+
Date.now = o;
388+
expect(code).toMatchSnapshot();
389+
});
364390
});

test/__snapshots__/HMR.test.js.snap

+52
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,57 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`HMR hotLoader works for locals 1`] = `
4+
"//content;
5+
if(module.hot) {
6+
(function() {
7+
var localsJsonString = \\"{\\\\\\"foo\\\\\\":\\\\\\"bar\\\\\\"}\\";
8+
// 1
9+
var cssReload = require(\\"../src/hmr/hotModuleReplacement.js\\")(module.id, undefined);
10+
// only invalidate when locals change
11+
if (
12+
module.hot.data &&
13+
module.hot.data.value &&
14+
module.hot.data.value !== localsJsonString
15+
) {
16+
module.hot.invalidate();
17+
} else {
18+
module.hot.accept();
19+
}
20+
module.hot.dispose(function(data) {
21+
data.value = localsJsonString;
22+
cssReload();
23+
});
24+
})();
25+
}
26+
"
27+
`;
28+
29+
exports[`HMR hotLoader works for non-locals 1`] = `
30+
"//content;
31+
if(module.hot) {
32+
(function() {
33+
var localsJsonString = undefined;
34+
// 1
35+
var cssReload = require(\\"../src/hmr/hotModuleReplacement.js\\")(module.id, undefined);
36+
// only invalidate when locals change
37+
if (
38+
module.hot.data &&
39+
module.hot.data.value &&
40+
module.hot.data.value !== localsJsonString
41+
) {
42+
module.hot.invalidate();
43+
} else {
44+
module.hot.accept();
45+
}
46+
module.hot.dispose(function(data) {
47+
data.value = localsJsonString;
48+
cssReload();
49+
});
50+
})();
51+
}
52+
"
53+
`;
54+
355
exports[`HMR should handle error event 1`] = `"[HMR] css reload %s"`;
456

557
exports[`HMR should handle error event 2`] = `"<link rel=\\"stylesheet\\" href=\\"/dist/main.css\\"><link rel=\\"stylesheet\\" href=\\"http://localhost/dist/main.css?1479427200000\\">"`;
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/*!************************************************************************************************!*\
2+
!*** css ../../../node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./index.css ***!
3+
\************************************************************************************************/
4+
.VoofDB21D_QzDbRdwMiY {
5+
color: red;
6+
}
7+

0 commit comments

Comments
 (0)