fix HMR when experiments.lazyCompilation is enabled

This commit is contained in:
Tobias Koppers 2022-01-18 12:26:43 +01:00
parent 10b38b3726
commit a9477c2409
7 changed files with 102 additions and 23 deletions

View File

@ -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 */
@ -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",
@ -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(

View File

@ -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);
})
);

View File

@ -3,3 +3,5 @@ export default 42;
export default 42;
---
export default 43;
---
export default 44;

View File

@ -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();
})
);
})
);
});

View File

@ -0,0 +1 @@
export default 123;

View File

@ -0,0 +1,5 @@
export default 42;
---
export default 43;
---
export default 44;

View File

@ -0,0 +1,10 @@
"use strict";
/** @type {import("../../../../").Configuration} */
module.exports = {
experiments: {
lazyCompilation: {
entries: false
}
}
};