From 50844eae3b77b3b5e127f82a13ca2506f4fd9ab6 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 13 Jan 2021 20:35:33 +0100 Subject: [PATCH] add test case for ESM tracking --- test/BuildDependencies.test.js | 54 +++++++- .../fixtures/buildDependencies/esm-cjs-dep.js | 1 + test/fixtures/buildDependencies/esm-dep.mjs | 1 + test/fixtures/buildDependencies/esm.mjs | 5 + test/fixtures/buildDependencies/index.js | 2 + test/fixtures/buildDependencies/run.js | 124 ++++++++++-------- 6 files changed, 128 insertions(+), 59 deletions(-) create mode 100644 test/fixtures/buildDependencies/esm-cjs-dep.js create mode 100644 test/fixtures/buildDependencies/esm-dep.mjs create mode 100644 test/fixtures/buildDependencies/esm.mjs diff --git a/test/BuildDependencies.test.js b/test/BuildDependencies.test.js index 2228012e236..fcf227a4233 100644 --- a/test/BuildDependencies.test.js +++ b/test/BuildDependencies.test.js @@ -24,7 +24,6 @@ const exec = (n, options = {}) => { if (code === 0) { if (!options.ignoreErrors && /<[ew]>/.test(stdout)) return reject(stdout); - console.log(stdout); resolve(stdout); } else { reject(new Error(`Code ${code}: ${stdout}`)); @@ -34,6 +33,8 @@ const exec = (n, options = {}) => { }); }; +const supportsEsm = +process.versions.modules >= 83; + describe("BuildDependencies", () => { beforeEach(done => { rimraf(cacheDirectory, done); @@ -57,6 +58,14 @@ describe("BuildDependencies", () => { path.resolve(inputDirectory, "config-dependency.js"), "module.exports = 0;" ); + fs.writeFileSync( + path.resolve(inputDirectory, "esm-dependency.js"), + "module.exports = 0;" + ); + fs.writeFileSync( + path.resolve(inputDirectory, "esm-async-dependency.mjs"), + "export default 0;" + ); await exec("0", { invalidBuildDepdencies: true, buildTwice: true, @@ -70,14 +79,18 @@ describe("BuildDependencies", () => { path.resolve(inputDirectory, "config-dependency.js"), "module.exports = 1;" ); + fs.writeFileSync( + path.resolve(inputDirectory, "esm-dependency.js"), + "module.exports = 1;" + ); await exec("1"); fs.writeFileSync( path.resolve(inputDirectory, "loader-dependency.js"), "module.exports = Date.now();" ); const now1 = Date.now(); - await exec("2"); - await exec("3"); + expect(await exec("2")).toMatch(/Captured build dependencies/); + expect(await exec("3")).not.toMatch(/Captured build dependencies/); fs.writeFileSync( path.resolve(inputDirectory, "config-dependency"), "module.exports = Date.now();" @@ -86,7 +99,22 @@ describe("BuildDependencies", () => { await exec("4"); const now3 = Date.now(); await exec("5"); - const results = Array.from({ length: 6 }).map((_, i) => + let now4, now5; + if (supportsEsm) { + fs.writeFileSync( + path.resolve(inputDirectory, "esm-dependency.js"), + "module.exports = Date.now();" + ); + now4 = Date.now(); + await exec("6"); + fs.writeFileSync( + path.resolve(inputDirectory, "esm-async-dependency.mjs"), + "export default Date.now();" + ); + now5 = Date.now(); + await exec("7"); + } + const results = Array.from({ length: supportsEsm ? 8 : 6 }).map((_, i) => require(`./js/buildDeps/${i}/main.js`) ); for (const r of results) { @@ -96,26 +124,44 @@ describe("BuildDependencies", () => { } expect(results[0].loader).toBe(0); expect(results[0].config).toBe(0); + if (supportsEsm) expect(results[0].esmConfig).toBe(0); expect(results[0].uncached).toBe(0); // 0 -> 1 should not cache at all because of invalid buildDeps expect(results[1].loader).toBe(1); expect(results[1].config).toBe(1); + expect(results[1].esmConfig).toBe(1); expect(results[1].uncached).toBe(1); // 1 -> 2 should be invalidated expect(results[2].loader).toBeGreaterThan(now1); expect(results[2].config).toBe(1); + expect(results[2].esmConfig).toBe(1); expect(results[2].uncached).toBe(1); // 2 -> 3 should stay cached expect(results[3].loader).toBe(results[2].loader); expect(results[3].config).toBe(1); + expect(results[3].esmConfig).toBe(1); expect(results[3].uncached).toBe(1); // 3 -> 4 should be invalidated expect(results[4].loader).toBeGreaterThan(now2); expect(results[4].config).toBeGreaterThan(now2); + expect(results[4].esmConfig).toBe(1); expect(results[4].uncached).toBe(results[4].config); // 4 -> 5 should stay cached, but uncacheable module still rebuilds expect(results[5].loader).toBe(results[4].loader); expect(results[5].config).toBe(results[4].config); expect(results[5].uncached).toBeGreaterThan(now3); + if (supportsEsm) { + // 5 -> 6 should be invalidated + expect(results[6].loader).toBeGreaterThan(now4); + expect(results[6].config).toBeGreaterThan(now4); + expect(results[6].esmConfig).toBeGreaterThan(now4); + expect(results[6].uncached).toBeGreaterThan(now4); + // 6 -> 7 should be invalidated + expect(results[7].loader).toBeGreaterThan(now5); + expect(results[7].config).toBeGreaterThan(now5); + expect(results[7].esmConfig).toBeGreaterThan(now5); + expect(results[7].esmAsyncConfig).toBeGreaterThan(now5); + expect(results[7].uncached).toBeGreaterThan(now5); + } }, 100000); }); diff --git a/test/fixtures/buildDependencies/esm-cjs-dep.js b/test/fixtures/buildDependencies/esm-cjs-dep.js new file mode 100644 index 00000000000..52d586a0e0e --- /dev/null +++ b/test/fixtures/buildDependencies/esm-cjs-dep.js @@ -0,0 +1 @@ +module.exports = require("../../js/buildDepsInput/esm-dependency"); diff --git a/test/fixtures/buildDependencies/esm-dep.mjs b/test/fixtures/buildDependencies/esm-dep.mjs new file mode 100644 index 00000000000..03e99c08cf8 --- /dev/null +++ b/test/fixtures/buildDependencies/esm-dep.mjs @@ -0,0 +1 @@ +export { default } from "./esm-cjs-dep.js"; diff --git a/test/fixtures/buildDependencies/esm.mjs b/test/fixtures/buildDependencies/esm.mjs new file mode 100644 index 00000000000..cd233797b08 --- /dev/null +++ b/test/fixtures/buildDependencies/esm.mjs @@ -0,0 +1,5 @@ +export { default } from "./esm-dep.mjs"; + +export const asyncDep = ( + await import("../../js/buildDepsInput/esm-async-dependency.mjs") +).default; diff --git a/test/fixtures/buildDependencies/index.js b/test/fixtures/buildDependencies/index.js index 9270c4df5ca..9f6bb68b7d7 100644 --- a/test/fixtures/buildDependencies/index.js +++ b/test/fixtures/buildDependencies/index.js @@ -3,5 +3,7 @@ module.exports = { loader: require("./loader!"), config: VALUE, + esmConfig: VALUE2, + esmAsyncConfig: VALUE3, uncached: require("./module") }; diff --git a/test/fixtures/buildDependencies/run.js b/test/fixtures/buildDependencies/run.js index 1e61e5ed113..d5e9df835a8 100644 --- a/test/fixtures/buildDependencies/run.js +++ b/test/fixtures/buildDependencies/run.js @@ -7,63 +7,77 @@ process.exitCode = 1; const options = JSON.parse(process.argv[3]); -const compiler = webpack( - { - mode: "development", - context: __dirname, - entry: "./index", - output: { - path: path.resolve(__dirname, "../../js/buildDeps/" + process.argv[2]), - libraryTarget: "commonjs2" - }, - plugins: [ - new webpack.DefinePlugin({ - VALUE: JSON.stringify(value), - VALUE_UNCACHEABLE: webpack.DefinePlugin.runtimeValue( - () => JSON.stringify(value), - true - ) - }) - ], - infrastructureLogging: { - level: "verbose" - }, - cache: { - type: "filesystem", - cacheDirectory: path.resolve(__dirname, "../../js/buildDepsCache"), - buildDependencies: { - config: [ - __filename, - path.resolve(__dirname, "../../../node_modules/.yarn-integrity") - ], - invalid: options.invalidBuildDepdencies ? ["should-fail-resolving"] : [] +const esm = +process.versions.modules >= 83; + +if (esm) { + import("./esm.mjs").then(module => { + run(module); + }); +} else { + run({ default: 1, asyncDep: 1 }); +} + +function run({ default: value2, asyncDep: value3 }) { + const compiler = webpack( + { + mode: "development", + context: __dirname, + entry: "./index", + output: { + path: path.resolve(__dirname, "../../js/buildDeps/" + process.argv[2]), + libraryTarget: "commonjs2" + }, + plugins: [ + new webpack.DefinePlugin({ + VALUE: JSON.stringify(value), + VALUE2: JSON.stringify(value2), + VALUE3: JSON.stringify(value3), + VALUE_UNCACHEABLE: webpack.DefinePlugin.runtimeValue( + () => JSON.stringify(value), + true + ) + }) + ], + infrastructureLogging: { + level: "verbose", + debug: /PackFile/ + }, + cache: { + type: "filesystem", + cacheDirectory: path.resolve(__dirname, "../../js/buildDepsCache"), + buildDependencies: { + config: [ + __filename, + path.resolve(__dirname, "../../../node_modules/.yarn-integrity") + ].concat(esm ? ["./esm.mjs"] : []), + invalid: options.invalidBuildDepdencies + ? ["should-fail-resolving"] + : [] + } } }, - snapshot: { - managedPaths: [path.resolve(__dirname, "../../../node_modules")] - } - }, - (err, stats) => { - if (err) { - return console.log(err); - } - if (stats.hasErrors()) { - return console.log(stats.toString({ all: false, errors: true })); - } - if (options.buildTwice) { - compiler.run((err, stats) => { - if (err) { - return console.log(err); - } - if (stats.hasErrors()) { - return console.log(stats.toString({ all: false, errors: true })); - } + (err, stats) => { + if (err) { + return console.log(err); + } + if (stats.hasErrors()) { + return console.log(stats.toString({ all: false, errors: true })); + } + if (options.buildTwice) { + compiler.run((err, stats) => { + if (err) { + return console.log(err); + } + if (stats.hasErrors()) { + return console.log(stats.toString({ all: false, errors: true })); + } + process.exitCode = 0; + console.log("OK"); + }); + } else { process.exitCode = 0; console.log("OK"); - }); - } else { - process.exitCode = 0; - console.log("OK"); + } } - } -); + ); +}