Skip to content

Commit

Permalink
fix: handle default for import context element dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
ahabhgk committed Sep 4, 2024
1 parent 27cf3e5 commit 860eb4a
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 6 deletions.
39 changes: 33 additions & 6 deletions lib/dependencies/ContextElementDependency.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const ModuleDependency = require("./ModuleDependency");

/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */
/** @typedef {import("../ModuleGraph")} ModuleGraph */
/** @typedef {import("../Module")} Module */
/** @typedef {import("../Module").BuildMeta} BuildMeta */
/** @typedef {import("../ContextModule")} ContextModule */
/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
Expand Down Expand Up @@ -67,12 +70,36 @@ class ContextElementDependency extends ModuleDependency {
* @returns {(string[] | ReferencedExport)[]} referenced exports
*/
getReferencedExports(moduleGraph, runtime) {
return this.referencedExports
? this.referencedExports.map(e => ({
name: e,
canMangle: false
}))
: Dependency.EXPORTS_OBJECT_REFERENCED;
if (!this.referencedExports) return Dependency.EXPORTS_OBJECT_REFERENCED;
const refs = [];
for (const referencedExport of this.referencedExports) {
if (
this._typePrefix === "import()" &&
referencedExport[0] === "default"
) {
const selfModule =
/** @type {ContextModule} */
(moduleGraph.getParentModule(this));
const importedModule =
/** @type {Module} */
(moduleGraph.getModule(this));
const exportsType = importedModule.getExportsType(
moduleGraph,
selfModule.options.namespaceObject === "strict"
);
if (
exportsType === "default-only" ||
exportsType === "default-with-named"
) {
return Dependency.EXPORTS_OBJECT_REFERENCED;
}
}
refs.push({
name: referencedExport,
canMangle: false
});
}
return refs;
}

/**
Expand Down
2 changes: 2 additions & 0 deletions test/cases/chunks/destructuring-assignment/dir3/a.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
exports.a = 1;
exports.b = 2;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
["a"]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"a": 1}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"a"
13 changes: 13 additions & 0 deletions test/cases/chunks/destructuring-assignment/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,16 @@ it("should not tree-shake default export for exportsType=default module", async
const { default: a } = await import("./dir2/a");
expect(a).toEqual({ a: 1, b: 2 });
});

it("should not tree-shake default export for exportsType=default context module", async () => {
const dir = "json";
const { default: object } = await import(`./dir3/${dir}/object.json`);
const { default: array } = await import(`./dir3/${dir}/array.json`);
const { default: primitive } = await import(`./dir3/${dir}/primitive.json`);
expect(object).toEqual({ a: 1 });
expect(array).toEqual(["a"]);
expect(primitive).toBe("a");
const file = "a";
const { default: a } = await import(`./dir3/${file}`);
expect(a).toEqual({ a: 1, b: 2 });
});
2 changes: 2 additions & 0 deletions test/cases/chunks/inline-options/dir16/a.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
exports.a = 1;
exports.b = 2;
1 change: 1 addition & 0 deletions test/cases/chunks/inline-options/dir16/json/array.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
["a"]
1 change: 1 addition & 0 deletions test/cases/chunks/inline-options/dir16/json/object.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"a": 1}
1 change: 1 addition & 0 deletions test/cases/chunks/inline-options/dir16/json/primitive.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"a"
17 changes: 17 additions & 0 deletions test/cases/chunks/inline-options/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,23 @@ if (process.env.NODE_ENV === "production") {
expect(a.a).toBe(1);
expect(a.b).toBe(2);
})

it("should not tree-shake default export for exportsType=default context module", async function () {
const dir = "json";
const jsonObject = await import(/* webpackExports: ["default"] */ `./dir16/${dir}/object.json`);
const jsonArray = await import(/* webpackExports: ["default"] */ `./dir16/${dir}/array.json`);
const jsonPrimitive = await import(/* webpackExports: ["default"] */ `./dir16/${dir}/primitive.json`);
expect(jsonObject.default).toEqual({ a: 1 });
expect(jsonObject.a).toEqual(1);
expect(jsonArray.default).toEqual(["a"]);
expect(jsonArray[0]).toBe("a");
expect(jsonPrimitive.default).toBe("a");
const file = "a";
const a = await import(/* webpackExports: ["default"] */`./dir16/${file}`);
expect(a.default).toEqual({ a: 1, b: 2 });
expect(a.a).toBe(1);
expect(a.b).toBe(2);
})
}

function testChunkLoading(load, expectedSyncInitial, expectedSyncRequested) {
Expand Down

0 comments on commit 860eb4a

Please sign in to comment.