Skip to content

Commit

Permalink
Merge pull request #15196 from webpack/bugfix/lazy-compilation-hmr
Browse files Browse the repository at this point in the history
fix HMR when experiments.lazyCompilation is enabled
  • Loading branch information
sokra committed Jan 18, 2022
2 parents f16e746 + a9477c2 commit f875826
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 23 deletions.
64 changes: 44 additions & 20 deletions lib/hmr/LazyCompilationPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const { registerNotSerializable } = require("../util/serialization");
/** @typedef {import("../RequestShortener")} RequestShortener */
/** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
/** @typedef {import("../WebpackError")} WebpackError */
/** @typedef {import("../dependencies/HarmonyImportDependency")} HarmonyImportDependency */
/** @typedef {import("../util/Hash")} Hash */
/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */

Expand All @@ -38,7 +39,7 @@ const { registerNotSerializable } = require("../util/serialization");
* @property {function(Module): { client: string, data: string, active: boolean }} module
*/

const IGNORED_DEPENDENCY_TYPES = new Set([
const HMR_DEPENDENCY_TYPES = new Set([
"import.meta.webpackHot.accept",
"import.meta.webpackHot.decline",
"module.hot.accept",
Expand Down Expand Up @@ -351,32 +352,55 @@ class LazyCompilationPlugin {
"LazyCompilationPlugin",
(originalModule, createData, resolveData) => {
if (
resolveData.dependencies.every(
resolveData.dependencies.every(dep =>
HMR_DEPENDENCY_TYPES.has(dep.type)
)
) {
// for HMR only resolving, try to determine if the HMR accept/decline refers to
// an import() or not
const hmrDep = resolveData.dependencies[0];
const originModule =
compilation.moduleGraph.getParentModule(hmrDep);
const isReferringToDynamicImport = originModule.blocks.some(
block =>
block.dependencies.some(
dep =>
dep.type === "import()" &&
/** @type {HarmonyImportDependency} */ (dep).request ===
hmrDep.request
)
);
if (!isReferringToDynamicImport) return;
} else if (
!resolveData.dependencies.every(
dep =>
IGNORED_DEPENDENCY_TYPES.has(dep.type) ||
HMR_DEPENDENCY_TYPES.has(dep.type) ||
(this.imports &&
(dep.type === "import()" ||
dep.type === "import() context element")) ||
(this.entries && dep.type === "entry")
) &&
!/webpack[/\\]hot[/\\]|webpack-dev-server[/\\]client/.test(
)
)
return;
if (
/webpack[/\\]hot[/\\]|webpack-dev-server[/\\]client/.test(
resolveData.request
) &&
checkTest(this.test, originalModule)
) {
const moduleInfo = backend.module(originalModule);
if (!moduleInfo) return;
const { client, data, active } = moduleInfo;
) ||
!checkTest(this.test, originalModule)
)
return;
const moduleInfo = backend.module(originalModule);
if (!moduleInfo) return;
const { client, data, active } = moduleInfo;

return new LazyCompilationProxyModule(
compiler.context,
originalModule,
resolveData.request,
client,
data,
active
);
}
return new LazyCompilationProxyModule(
compiler.context,
originalModule,
resolveData.request,
client,
data,
active
);
}
);
compilation.dependencyFactories.set(
Expand Down
18 changes: 15 additions & 3 deletions test/hotCases/lazy-compilation/simple/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,21 @@ it("should compile to lazy imported module", done => {
expect(generation).toBe(1);
import("./module").then(result => {
expect(result).toHaveProperty("default", 43);
setTimeout(() => {
done();
}, 1000);
expect(generation).toBe(1);
module.hot.accept("./module", () => {
generation += 10;
});
NEXT(
require("../../update")(done, true, () => {
import("./module").then(result => {
expect(result).toHaveProperty("default", 44);
expect(generation).toBe(11);
setTimeout(() => {
done();
}, 1000);
}, done);
})
);
}, done);
})
);
Expand Down
2 changes: 2 additions & 0 deletions test/hotCases/lazy-compilation/simple/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ export default 42;
export default 42;
---
export default 43;
---
export default 44;
25 changes: 25 additions & 0 deletions test/hotCases/lazy-compilation/unrelated/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import value from "./module";

const neverCalled = () => import("./lazy");

it("should compile to lazy imported module", done => {
let generation = 0;
module.hot.accept("./module", () => {
generation++;
});
expect(value).toBe(42);
expect(generation).toBe(0);
NEXT(
require("../../update")(done, true, () => {
expect(value).toBe(43);
expect(generation).toBe(1);
NEXT(
require("../../update")(done, true, () => {
expect(value).toBe(44);
expect(generation).toBe(2);
done();
})
);
})
);
});
1 change: 1 addition & 0 deletions test/hotCases/lazy-compilation/unrelated/lazy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 123;
5 changes: 5 additions & 0 deletions test/hotCases/lazy-compilation/unrelated/module.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default 42;
---
export default 43;
---
export default 44;
10 changes: 10 additions & 0 deletions test/hotCases/lazy-compilation/unrelated/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"use strict";

/** @type {import("../../../../").Configuration} */
module.exports = {
experiments: {
lazyCompilation: {
entries: false
}
}
};

0 comments on commit f875826

Please sign in to comment.