Skip to content

Commit 1c6f7b0

Browse files
authored
fix: Explicitly named exports should be exported over export * (#103)
Closes #102
1 parent 29f51f6 commit 1c6f7b0

7 files changed

+53
-11
lines changed

hook.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,15 +129,32 @@ function isBareSpecifier (specifier) {
129129
*/
130130
async function processModule ({ srcUrl, context, parentGetSource, parentResolve, excludeDefault }) {
131131
const exportNames = await getExports(srcUrl, context, parentGetSource)
132-
const duplicates = new Set()
132+
const starExports = new Set()
133133
const setters = new Map()
134134

135-
const addSetter = (name, setter) => {
136-
// When doing an `import *` duplicates become undefined, so do the same
135+
const addSetter = (name, setter, isStarExport = false) => {
137136
if (setters.has(name)) {
138-
duplicates.add(name)
139-
setters.delete(name)
140-
} else if (!duplicates.has(name)) {
137+
if (isStarExport) {
138+
// If there's already a matching star export, delete it
139+
if (starExports.has(name)) {
140+
setters.delete(name)
141+
}
142+
// and return so this is excluded
143+
return
144+
}
145+
146+
// if we already have this export but it is from a * export, overwrite it
147+
if (starExports.has(name)) {
148+
starExports.delete(name)
149+
setters.set(name, setter)
150+
}
151+
} else {
152+
// Store export * exports so we know they can be overridden by explicit
153+
// named exports
154+
if (isStarExport) {
155+
starExports.add(name)
156+
}
157+
141158
setters.set(name, setter)
142159
}
143160
}
@@ -165,7 +182,7 @@ async function processModule ({ srcUrl, context, parentGetSource, parentResolve,
165182
excludeDefault: true
166183
})
167184
for (const [name, setter] of setters.entries()) {
168-
addSetter(name, setter)
185+
addSetter(name, setter, true)
169186
}
170187
} else {
171188
addSetter(n, `

test/fixtures/duplicate-b.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export const foo = 'a'
1+
export const foo = 'b'

test/fixtures/duplicate-c.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const foo = 'c'

test/fixtures/duplicate-explicit.mjs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export * from './duplicate-a.mjs'
2+
export * from './duplicate-b.mjs'
3+
export { foo } from './duplicate-c.mjs'
4+
export * from './duplicate-a.mjs'
5+
export * from './duplicate-b.mjs'
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import * as lib from '../fixtures/duplicate-explicit.mjs'
2+
import { strictEqual } from 'assert'
3+
import Hook from '../../index.js'
4+
5+
Hook((exports, name) => {
6+
if (name.endsWith('duplicate-explicit.mjs')) {
7+
strictEqual(exports.foo, 'c')
8+
exports.foo += '-wrapped'
9+
}
10+
})
11+
12+
// foo should not be exported because there are duplicate exports
13+
strictEqual(lib.foo, 'c-wrapped')

test/hook/duplicate-exports.mjs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import Hook from '../../index.js'
44

55
Hook((exports, name) => {
66
if (name.match(/duplicate\.mjs/)) {
7-
// foo should not be exported because there are duplicate exports
8-
strictEqual(exports.foo, undefined)
7+
// foo should not be exported because there are duplicate * exports
8+
strictEqual('foo' in exports, false)
99
// default should be exported
1010
strictEqual(exports.default, 'foo')
1111
}
@@ -14,6 +14,6 @@ Hook((exports, name) => {
1414
notEqual(lib, undefined)
1515

1616
// foo should not be exported because there are duplicate exports
17-
strictEqual(lib.foo, undefined)
17+
strictEqual('foo' in lib, false)
1818
// default should be exported
1919
strictEqual(lib.default, 'foo')

test/hook/v18.19-openai.mjs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,9 @@ Hook((exports, name) => {
88
})
99

1010
console.assert(OpenAI)
11+
12+
const openAI = new OpenAI({
13+
apiKey: 'doesnt-matter'
14+
})
15+
16+
console.assert(openAI)

0 commit comments

Comments
 (0)