Skip to content

Commit 390333f

Browse files
authored
fix: set .name to "default" for anonymous default exports per ES spec (#20773)
`export default class {}` and `export default function() {}` should have `.name === "default"` per the ES specification. Webpack's renaming to `__WEBPACK_DEFAULT_EXPORT__` caused name inference to assign the wrong name.
1 parent 91aa5da commit 390333f

File tree

4 files changed

+39
-12
lines changed

4 files changed

+39
-12
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"webpack": patch
3+
---
4+
5+
Set `.name` to `"default"` for anonymous default export functions and classes per ES spec

lib/dependencies/HarmonyExportDependencyParserPlugin.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,13 @@ module.exports = class HarmonyExportDependencyParserPlugin {
137137
}
138138
: undefined
139139
);
140+
dep.isAnonymousDefault =
141+
node.type === "ArrowFunctionExpression" ||
142+
((node.type === "FunctionDeclaration" ||
143+
node.type === "FunctionExpression" ||
144+
node.type === "ClassDeclaration" ||
145+
node.type === "ClassExpression") &&
146+
!node.id);
140147
dep.loc = Object.create(
141148
/** @type {DependencyLocation} */ (statement.loc)
142149
);

lib/dependencies/HarmonyExportExpressionDependency.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"use strict";
77

88
const ConcatenationScope = require("../ConcatenationScope");
9+
const InitFragment = require("../InitFragment");
910
const RuntimeGlobals = require("../RuntimeGlobals");
1011
const makeSerializable = require("../util/makeSerializable");
1112
const { propertyAccess } = require("../util/property");
@@ -36,6 +37,7 @@ class HarmonyExportExpressionDependency extends NullDependency {
3637
this.rangeStatement = rangeStatement;
3738
this.prefix = prefix;
3839
this.declarationId = declarationId;
40+
this.isAnonymousDefault = false;
3941
}
4042

4143
get type() {
@@ -74,6 +76,7 @@ class HarmonyExportExpressionDependency extends NullDependency {
7476
write(this.rangeStatement);
7577
write(this.prefix);
7678
write(this.declarationId);
79+
write(this.isAnonymousDefault);
7780
super.serialize(context);
7881
}
7982

@@ -86,6 +89,7 @@ class HarmonyExportExpressionDependency extends NullDependency {
8689
this.rangeStatement = read();
8790
this.prefix = read();
8891
this.declarationId = read();
92+
this.isAnonymousDefault = read();
8993
super.deserialize(context);
9094
}
9195
}
@@ -153,6 +157,18 @@ HarmonyExportExpressionDependency.Template = class HarmonyExportDependencyTempla
153157
dep.range[0] - 1,
154158
`/* harmony default export */ ${dep.prefix}`
155159
);
160+
161+
if (typeof declarationId !== "string" && dep.isAnonymousDefault) {
162+
// Fix .name for anonymous default export function declarations
163+
// see test/test262-cases/test/language/module-code/instn-named-bndng-dflt-fun-anon.js cspell:disable-line
164+
initFragments.push(
165+
new InitFragment(
166+
`Reflect.defineProperty(${name}, "name", { value: "default", configurable: true });\n`,
167+
InitFragment.STAGE_HARMONY_EXPORTS,
168+
2
169+
)
170+
);
171+
}
156172
} else {
157173
/** @type {string} */
158174
let content;
@@ -199,7 +215,17 @@ HarmonyExportExpressionDependency.Template = class HarmonyExportDependencyTempla
199215
dep.range[0] - 1,
200216
`${content}(${dep.prefix}`
201217
);
202-
source.replace(dep.range[1], dep.rangeStatement[1] - 0.5, ");");
218+
if (dep.isAnonymousDefault) {
219+
// Fix .name for anonymous default export expressions
220+
// see test/test262-cases/test/language/module-code/eval-export-dflt-cls-anon.js cspell:disable-line
221+
source.replace(
222+
dep.range[1],
223+
dep.rangeStatement[1] - 0.5,
224+
`);\nReflect.getOwnPropertyDescriptor(${name}, "name").writable || Reflect.defineProperty(${name}, "name", { value: "default", configurable: true });`
225+
);
226+
} else {
227+
source.replace(dep.range[1], dep.rangeStatement[1] - 0.5, ");");
228+
}
203229
return;
204230
}
205231

test/test262.spectest.js

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -853,10 +853,6 @@ const knownBugs = [
853853

854854
// Replacing `export default` will remove `default` name by spec, need to `static name = "default";` if doesn't exist
855855
"expressions/class/elements/class-name-static-initializer-default-export.js",
856-
"module-code/eval-export-dflt-cls-anon.js",
857-
"module-code/eval-export-dflt-expr-cls-anon.js",
858-
"module-code/eval-export-dflt-expr-fn-anon.js",
859-
"module-code/eval-export-dflt-expr-gen-anon.js",
860856

861857
// improve test runner to keep dynamic import for such case
862858
"expressions/dynamic-import/assign-expr-get-value-abrupt-throws.js",
@@ -895,9 +891,6 @@ const knownBugs = [
895891
// Not a bug, we need to improve our test runner
896892
"statements/async-function/evaluation-body.js",
897893

898-
"module-code/instn-named-bndng-dflt-gen-anon.js",
899-
"module-code/instn-named-bndng-dflt-fun-anon.js",
900-
901894
// Do we need to call `Object.setPrototypeOf(__webpack_exports__, null);` for namespace imports and other things
902895
"module-code/namespace/internals/get-own-property-str-found-init.js",
903896
"module-code/namespace/internals/get-own-property-str-found-uninit.js",
@@ -1008,10 +1001,6 @@ const knownBugs = [
10081001
"expressions/dynamic-import/catch/nested-while-import-catch-instn-iee-err-circular.js",
10091002
"expressions/dynamic-import/catch/top-level-import-catch-instn-iee-err-circular.js",
10101003

1011-
"expressions/dynamic-import/eval-export-dflt-cls-anon.js",
1012-
"expressions/dynamic-import/eval-export-dflt-expr-cls-anon.js",
1013-
"expressions/dynamic-import/eval-export-dflt-expr-fn-anon.js",
1014-
"expressions/dynamic-import/eval-export-dflt-expr-gen-anon.js",
10151004
"expressions/dynamic-import/eval-self-once-script.js",
10161005
"expressions/dynamic-import/for-await-resolution-and-error-agen-yield.js",
10171006
"expressions/dynamic-import/import-errored-module.js",

0 commit comments

Comments
 (0)