diff --git a/lib/NormalModule.js b/lib/NormalModule.js index 6605cb86734..71ffe6533da 100644 --- a/lib/NormalModule.js +++ b/lib/NormalModule.js @@ -276,6 +276,8 @@ class NormalModule extends Module { this._source = null; /** @private @type {Map | undefined} **/ this._sourceSizes = undefined; + /** @private @type {Set} */ + this._sourceTypes = undefined; // Cache this._lastSuccessfulBuildMeta = {}; @@ -347,12 +349,19 @@ class NormalModule extends Module { this.resource = m.resource; this.matchResource = m.matchResource; this.loaders = m.loaders; + this._sourceTypes = m._sourceTypes; + this._sourceSizes = m._sourceSizes; } /** * Assuming this module is in the cache. Remove internal references to allow freeing some memory. */ cleanupForCache() { + // Make sure to cache types and sizes before cleanup + if (this._sourceTypes === undefined) this.getSourceTypes(); + for (const type of this._sourceTypes) { + this.size(type); + } super.cleanupForCache(); this.parser = undefined; this.parserOptions = undefined; @@ -390,6 +399,7 @@ class NormalModule extends Module { this.type, this.generatorOptions ); + // we assume the generator behaves identically and keep cached sourceTypes/Sizes } /** @@ -873,6 +883,7 @@ class NormalModule extends Module { this._forceBuild = false; this._source = null; if (this._sourceSizes !== undefined) this._sourceSizes.clear(); + this._sourceTypes = undefined; this._ast = null; this.error = null; this.clearWarningsAndErrors(); @@ -1075,7 +1086,10 @@ class NormalModule extends Module { * @returns {Set} types available (do not mutate) */ getSourceTypes() { - return this.generator.getTypes(this); + if (this._sourceTypes === undefined) { + this._sourceTypes = this.generator.getTypes(this); + } + return this._sourceTypes; } /** @@ -1264,7 +1278,6 @@ class NormalModule extends Module { const { write } = context; // deserialize write(this._source); - write(this._sourceSizes); write(this.error); write(this._lastSuccessfulBuildMeta); write(this._forceBuild); @@ -1296,7 +1309,6 @@ class NormalModule extends Module { deserialize(context) { const { read } = context; this._source = read(); - this._sourceSizes = read(); this.error = read(); this._lastSuccessfulBuildMeta = read(); this._forceBuild = read(); diff --git a/test/Compiler.test.js b/test/Compiler.test.js index 35e6f63c507..9f8903cac75 100644 --- a/test/Compiler.test.js +++ b/test/Compiler.test.js @@ -467,11 +467,12 @@ describe("Compiler", () => { } }); compiler.outputFileSystem = createFsFromVolume(new Volume()); - compiler.run((err, stats) => { + compiler.run((err, stats1) => { if (err) return done(err); - compiler.run((err, stats) => { + compiler.run((err, stats2) => { if (err) return done(err); + expect(stats1.toString({ all: true })).toBeTypeOf("string"); done(); }); }); diff --git a/test/WatchTestCases.test.js b/test/WatchTestCases.test.js index cb30887f2bf..2e21996f02a 100644 --- a/test/WatchTestCases.test.js +++ b/test/WatchTestCases.test.js @@ -169,10 +169,11 @@ describe("WatchTestCases", () => { }, (err, stats) => { if (err) return compilationFinished(err); - if (!stats) + if (!stats) { return compilationFinished( new Error("No stats reported from Compiler") ); + } if (stats.hash === lastHash) return; lastHash = stats.hash; if (run.done && lastHash !== stats.hash) { @@ -192,6 +193,7 @@ describe("WatchTestCases", () => { } if (waitMode) return; run.done = true; + run.stats = stats; if (err) return compilationFinished(err); const statOptions = { preset: "verbose", @@ -383,6 +385,10 @@ describe("WatchTestCases", () => { ); run.it = _it; run.getNumberOfTests = getNumberOfTests; + it(`${run.name} should allow to read stats`, done => { + if (run.stats) run.stats.toString({ all: true }); + done(); + }); } afterAll(() => {