From 7cf15cc7f6246abc437e047305c2021d5ab8a27b Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Tue, 27 Feb 2024 20:09:43 +0100 Subject: [PATCH] fix: parser hook calls for compiler plugins --- lib/optimize/InnerGraph.js | 3 +- test/CompilerParserHooks.test.js | 76 +++++++++++++++++++++++++++++ test/fixtures/top-level-symbols.mjs | 4 ++ 3 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 test/CompilerParserHooks.test.js create mode 100644 test/fixtures/top-level-symbols.mjs diff --git a/lib/optimize/InnerGraph.js b/lib/optimize/InnerGraph.js index 68ce4f3661c..25548e9c578 100644 --- a/lib/optimize/InnerGraph.js +++ b/lib/optimize/InnerGraph.js @@ -266,12 +266,11 @@ exports.tagTopLevelSymbol = (parser, name) => { const innerGraphState = getState(parser.state); if (!innerGraphState) return; - parser.defineVariable(name); - const existingTag = /** @type {TopLevelSymbol} */ ( parser.getTagData(name, topLevelSymbolTag) ); if (existingTag) { + parser.defineVariable(name); return existingTag; } diff --git a/test/CompilerParserHooks.test.js b/test/CompilerParserHooks.test.js new file mode 100644 index 00000000000..e4f2ffffb07 --- /dev/null +++ b/test/CompilerParserHooks.test.js @@ -0,0 +1,76 @@ +"use strict"; + +require("./helpers/warmup-webpack"); + +const path = require("path"); +const { createFsFromVolume, Volume } = require("memfs"); +const { JAVASCRIPT_MODULE_TYPE_ESM } = require("../lib/ModuleTypeConstants"); +const pluginName = "CompilerParserHooksTest"; + +describe("Compiler Parser Plugin", () => { + function runWebpackWithEntry(entry, setupParser) { + return new Promise((resolve, reject) => { + const webpack = require(".."); + const compiler = webpack({ + context: path.join(__dirname, "fixtures"), + entry: entry, + output: { + path: "/directory", + filename: "bundle.js" + }, + plugins: [ + { + apply(compiler) { + compiler.hooks.thisCompilation.tap( + pluginName, + (_, { normalModuleFactory }) => { + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(pluginName, parser => { + setupParser(parser); + }); + } + ); + } + } + ] + }); + compiler.outputFileSystem = createFsFromVolume(new Volume()); + compiler.run(err => { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); + } + + describe("top level symbol", () => { + it("should trigger new hook for classes", async () => { + let foundExpression; + await runWebpackWithEntry("./top-level-symbols.mjs", parser => { + parser.hooks.new.for("TopLevelClass").tap(pluginName, expr => { + foundExpression = expr; + }); + }); + expect(foundExpression).toBeTruthy(); + expect(foundExpression.type).toBe("NewExpression"); + expect(foundExpression.callee.type).toBe("Identifier"); + expect(foundExpression.callee.name).toBe("TopLevelClass"); + }); + + it("should trigger call hooks for functions", async () => { + let foundExpression; + await runWebpackWithEntry("./top-level-symbols.mjs", parser => { + parser.hooks.call.for("topLevelFunction").tap(pluginName, expr => { + foundExpression = expr; + }); + }); + expect(foundExpression).toBeTruthy(); + expect(foundExpression.type).toBe("CallExpression"); + expect(foundExpression.callee.type).toBe("Identifier"); + expect(foundExpression.callee.name).toBe("topLevelFunction"); + }); + }); +}); diff --git a/test/fixtures/top-level-symbols.mjs b/test/fixtures/top-level-symbols.mjs new file mode 100644 index 00000000000..fe9a6b22d8c --- /dev/null +++ b/test/fixtures/top-level-symbols.mjs @@ -0,0 +1,4 @@ +class TopLevelClass { } +function topLevelFunction() { } +new TopLevelClass(); +topLevelFunction(); \ No newline at end of file