Skip to content

Commit 8a01dfe

Browse files
refactor: deduplicate export presence logic in Harmony dependency classes (#20521)
1 parent b9fc7b3 commit 8a01dfe

File tree

13 files changed

+130
-39
lines changed

13 files changed

+130
-39
lines changed

.prettierignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,7 @@ examples/**
4545
!examples/**/test.filter.js
4646

4747
.vscode/**/*.*
48+
49+
# Ignore local working files
50+
pr.md
51+
issue.md

lib/dependencies/HarmonyExportDependencyParserPlugin.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,10 @@ module.exports = class HarmonyExportDependencyParserPlugin {
3939
*/
4040
constructor(options) {
4141
this.options = options;
42-
this.exportPresenceMode =
43-
options.reexportExportsPresence !== undefined
44-
? ExportPresenceModes.fromUserOption(options.reexportExportsPresence)
45-
: options.exportsPresence !== undefined
46-
? ExportPresenceModes.fromUserOption(options.exportsPresence)
47-
: options.strictExportPresence
48-
? ExportPresenceModes.ERROR
49-
: ExportPresenceModes.AUTO;
42+
this.exportPresenceMode = ExportPresenceModes.resolveFromOptions(
43+
options.reexportExportsPresence,
44+
options
45+
);
5046
}
5147

5248
/**

lib/dependencies/HarmonyImportDependency.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,38 @@ const ExportPresenceModes = {
5353
default:
5454
throw new Error(`Invalid export presence value ${str}`);
5555
}
56+
},
57+
/**
58+
* Resolve export presence mode from parser options with a specific key and shared fallbacks.
59+
* @param {string | false | undefined} specificValue the type-specific option value (e.g. importExportsPresence or reexportExportsPresence)
60+
* @param {import("../../declarations/WebpackOptions").JavascriptParserOptions} options parser options
61+
* @returns {ExportPresenceMode} resolved mode
62+
*/
63+
resolveFromOptions(specificValue, options) {
64+
if (specificValue !== undefined) {
65+
return ExportPresenceModes.fromUserOption(specificValue);
66+
}
67+
if (options.exportsPresence !== undefined) {
68+
return ExportPresenceModes.fromUserOption(options.exportsPresence);
69+
}
70+
return options.strictExportPresence
71+
? ExportPresenceModes.ERROR
72+
: ExportPresenceModes.AUTO;
5673
}
5774
};
5875

76+
/**
77+
* Get the non-optional leading part of a member chain.
78+
* @param {string[]} members members
79+
* @param {boolean[]} membersOptionals optionality for each member
80+
* @returns {string[]} the non-optional prefix
81+
*/
82+
const getNonOptionalPart = (members, membersOptionals) => {
83+
let i = 0;
84+
while (i < members.length && membersOptionals[i] === false) i++;
85+
return i !== members.length ? members.slice(0, i) : members;
86+
};
87+
5988
/** @typedef {string[]} Ids */
6089

6190
class HarmonyImportDependency extends ModuleDependency {
@@ -427,3 +456,4 @@ HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends
427456
};
428457

429458
module.exports.ExportPresenceModes = ExportPresenceModes;
459+
module.exports.getNonOptionalPart = getNonOptionalPart;

lib/dependencies/HarmonyImportDependencyParserPlugin.js

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ const HarmonyAcceptDependency = require("./HarmonyAcceptDependency");
1818
const HarmonyAcceptImportDependency = require("./HarmonyAcceptImportDependency");
1919
const HarmonyEvaluatedImportSpecifierDependency = require("./HarmonyEvaluatedImportSpecifierDependency");
2020
const HarmonyExports = require("./HarmonyExports");
21-
const { ExportPresenceModes } = require("./HarmonyImportDependency");
21+
const {
22+
ExportPresenceModes,
23+
getNonOptionalPart
24+
} = require("./HarmonyImportDependency");
2225
const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency");
2326
const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDependency");
2427
const { ImportPhaseUtils, createGetImportPhase } = require("./ImportPhase");
@@ -82,14 +85,10 @@ module.exports = class HarmonyImportDependencyParserPlugin {
8285
constructor(options) {
8386
this.options = options;
8487
/** @type {ExportPresenceMode} */
85-
this.exportPresenceMode =
86-
options.importExportsPresence !== undefined
87-
? ExportPresenceModes.fromUserOption(options.importExportsPresence)
88-
: options.exportsPresence !== undefined
89-
? ExportPresenceModes.fromUserOption(options.exportsPresence)
90-
: options.strictExportPresence
91-
? ExportPresenceModes.ERROR
92-
: ExportPresenceModes.AUTO;
88+
this.exportPresenceMode = ExportPresenceModes.resolveFromOptions(
89+
options.importExportsPresence,
90+
options
91+
);
9392
this.strictThisContextOnImports = options.strictThisContextOnImports;
9493
}
9594

@@ -119,17 +118,6 @@ module.exports = class HarmonyImportDependencyParserPlugin {
119118
apply(parser) {
120119
const getImportPhase = createGetImportPhase(this.options.deferImport);
121120

122-
/**
123-
* @param {Members} members members
124-
* @param {MembersOptionals} membersOptionals members Optionals
125-
* @returns {Ids} a non optional part
126-
*/
127-
function getNonOptionalPart(members, membersOptionals) {
128-
let i = 0;
129-
while (i < members.length && membersOptionals[i] === false) i++;
130-
return i !== members.length ? members.slice(0, i) : members;
131-
}
132-
133121
/**
134122
* @param {MemberExpression} node member expression
135123
* @param {number} count count

lib/dependencies/ImportParserPlugin.js

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const {
1414
} = require("../javascript/JavascriptParser");
1515
const traverseDestructuringAssignmentProperties = require("../util/traverseDestructuringAssignmentProperties");
1616
const ContextDependencyHelpers = require("./ContextDependencyHelpers");
17+
const { getNonOptionalPart } = require("./HarmonyImportDependency");
1718
const ImportContextDependency = require("./ImportContextDependency");
1819
const ImportDependency = require("./ImportDependency");
1920
const ImportEagerDependency = require("./ImportEagerDependency");
@@ -178,17 +179,6 @@ class ImportParserPlugin {
178179
* @returns {void}
179180
*/
180181
apply(parser) {
181-
/**
182-
* @param {Members} members members
183-
* @param {MembersOptionals} membersOptionals members Optionals
184-
* @returns {string[]} a non optional part
185-
*/
186-
function getNonOptionalPart(members, membersOptionals) {
187-
let i = 0;
188-
while (i < members.length && membersOptionals[i] === false) i++;
189-
return i !== members.length ? members.slice(0, i) : members;
190-
}
191-
192182
parser.hooks.collectDestructuringAssignmentProperties.tap(
193183
PLUGIN_NAME,
194184
(expr) => {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { NoNo } from "../stub";
2+
export { NotHere } from "../stub";
3+
4+
export default `${typeof NoNo}`;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
"use strict";
2+
3+
module.exports = [
4+
{
5+
moduleName: /eee/,
6+
message: /NoNo.+not found/
7+
},
8+
{
9+
moduleName: /fff/,
10+
message: /NotHere.+not found/
11+
}
12+
];
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { NoNo } from "../stub";
2+
export { NotHere } from "../stub";
3+
4+
export default `${typeof NoNo}`;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import eee from "./eee/index.js";
2+
import fff from "./fff/index.js";
3+
4+
it("should resolve presence overrides correctly", () => {
5+
expect(eee).toBe("undefined");
6+
expect(fff).toBe("undefined");
7+
});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const foo = "bar";
2+
3+
export default foo;

0 commit comments

Comments
 (0)