-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
feat(utils): add setBundleModuleLoader runtime hook #5867
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
killagu
merged 9 commits into
eggjs:next
from
killagu:split/01-utils-bundle-module-loader
Apr 26, 2026
+165
−22
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
51304fc
feat(utils): add setBundleModuleLoader runtime hook
killagu 0221ad6
fix(utils): address bundle module loader review
killagu e193cb5
test(utils): cover bundle loader default branches
killagu 8709348
test(egg): harden raw bad request test
killagu c92b730
test(utils): clarify virtual bundle specifier case
killagu 5496988
refactor: move bundle loader global type
killagu d3ea364
refactor: include core global types in utils tsconfig
killagu 33294c5
fix: avoid ambient global dependency in utils
killagu 4800381
refactor: use shared typings for bundle loader
killagu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| import { strict as assert } from 'node:assert'; | ||
| import path from 'node:path'; | ||
|
|
||
| import { afterEach, describe, it } from 'vitest'; | ||
|
|
||
| import { importModule, setBundleModuleLoader } from '../src/import.ts'; | ||
| import { getFilepath } from './helper.ts'; | ||
|
|
||
| describe('test/bundle-import.test.ts', () => { | ||
| afterEach(() => { | ||
| setBundleModuleLoader(undefined); | ||
| }); | ||
|
|
||
| it('returns the real module when no bundle loader is registered', async () => { | ||
| const result = await importModule(getFilepath('esm')); | ||
| assert.ok(result); | ||
| assert.equal(typeof result, 'object'); | ||
| }); | ||
|
|
||
| it('intercepts importModule with the registered loader', async () => { | ||
| const seen: string[] = []; | ||
| const fakeModule = { default: { hello: 'bundle' }, other: 'stuff' }; | ||
| setBundleModuleLoader((p) => { | ||
| seen.push(p); | ||
| if (p.endsWith('/fixtures/esm')) return fakeModule; | ||
| }); | ||
|
|
||
| const result = await importModule(getFilepath('esm')); | ||
| assert.deepEqual(result, fakeModule); | ||
| assert.ok(seen.some((p) => p.endsWith('/fixtures/esm'))); | ||
| }); | ||
|
|
||
| it('honors importDefaultOnly when the bundle hit has a default key', async () => { | ||
| setBundleModuleLoader(() => ({ default: { greet: 'hi' }, other: 'x' })); | ||
|
|
||
| const result = await importModule(getFilepath('esm'), { importDefaultOnly: true }); | ||
| assert.deepEqual(result, { greet: 'hi' }); | ||
| }); | ||
|
|
||
| it('keeps non-default bundle hits when importDefaultOnly is enabled', async () => { | ||
| const fakeModule = { named: 'bundle' }; | ||
| setBundleModuleLoader(() => fakeModule); | ||
|
|
||
| const result = await importModule(getFilepath('esm'), { importDefaultOnly: true }); | ||
| assert.deepEqual(result, fakeModule); | ||
| }); | ||
|
|
||
| it('keeps null bundle hits when importDefaultOnly is enabled', async () => { | ||
| setBundleModuleLoader(() => null); | ||
|
|
||
| const result = await importModule(getFilepath('esm'), { importDefaultOnly: true }); | ||
| assert.equal(result, null); | ||
| }); | ||
|
|
||
| it('unwraps __esModule double-default shape', async () => { | ||
| setBundleModuleLoader(() => ({ | ||
| default: { __esModule: true, default: { fn: 'bundled' } }, | ||
| })); | ||
|
|
||
| const result = await importModule(getFilepath('esm')); | ||
| assert.equal(result.__esModule, true); | ||
| assert.deepEqual(result.default, { fn: 'bundled' }); | ||
| }); | ||
|
|
||
| it('falls through to normal import when loader returns undefined', async () => { | ||
| setBundleModuleLoader(() => undefined); | ||
|
|
||
| const result = await importModule(getFilepath('esm')); | ||
| assert.ok(result); | ||
| assert.equal(result.default.foo, 'bar'); | ||
| }); | ||
|
|
||
| it('serves virtual specifiers from the loader without requiring them on disk', async () => { | ||
| const fakeModule = { virtual: true }; | ||
| setBundleModuleLoader((p) => (p === 'virtual/not-on-disk' ? fakeModule : undefined)); | ||
|
|
||
| const result = await importModule('virtual/not-on-disk'); | ||
| assert.deepEqual(result, fakeModule); | ||
| }); | ||
|
|
||
| it('normalizes Windows-style bundle paths before loader lookup', async () => { | ||
| const fakeModule = { windows: true }; | ||
| const filepath = getFilepath('esm').split(path.posix.sep).join(path.win32.sep); | ||
|
|
||
| setBundleModuleLoader((p) => (p.endsWith('/fixtures/esm') ? fakeModule : undefined)); | ||
|
|
||
| const result = await importModule(filepath); | ||
| assert.deepEqual(result, fakeModule); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| export default { | ||
| __esModule: true, | ||
| default: { | ||
| foo: 'bar', | ||
| one: 1, | ||
| }, | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.