Skip to content

Commit af93ca6

Browse files
committed
feat(mod): allow custom import fn
1 parent c79bbc5 commit af93ca6

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

src/mod/import.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,34 @@ export interface DynamicImportFileOptions {
196196
* @default false
197197
*/
198198
bustCache?: boolean
199+
200+
/**
201+
* Custom import function to use instead of native `import()`.
202+
*
203+
* Useful for bundlers like Vite that provide their own module resolution
204+
* which can handle features Node.js native ESM cannot, such as:
205+
* - Resolving `.js` → `.ts` extensions
206+
* - TypeScript path aliases
207+
* - Virtual modules
208+
*
209+
* @example Vite 5 (ssrLoadModule)
210+
* ```ts
211+
* // In Vite plugin configureServer():
212+
* Mod.dynamicImportFile(path, {
213+
* importFn: (url) => server.ssrLoadModule(url)
214+
* })
215+
* ```
216+
*
217+
* @example Vite 6+ (ModuleRunner)
218+
* ```ts
219+
* // In Vite plugin configureServer():
220+
* const runner = createServerModuleRunner(server.environments.ssr)
221+
* Mod.dynamicImportFile(path, {
222+
* importFn: (url) => runner.import(url)
223+
* })
224+
* ```
225+
*/
226+
importFn?: (url: string) => Promise<unknown>
199227
}
200228

201229
/**
@@ -255,8 +283,13 @@ export const dynamicImportFile = <
255283
): DynamicImportFileResult<$Module, $Options> => {
256284
const importUrl = Fs.Path.toFileUrl(path)
257285

286+
// Use custom importFn if provided, otherwise native import()
287+
const performImport = options?.importFn
288+
? () => options.importFn!(importUrl.href)
289+
: () => import(importUrl.href)
290+
258291
const doImport = Effect.tryPromise({
259-
try: () => import(importUrl.href),
292+
try: performImport,
260293
catch: (cause) => createImportError(path, cause instanceof Error ? cause : new Error(String(cause))),
261294
}) as Effect.Effect<$Module, ImportError>
262295

0 commit comments

Comments
 (0)