import type { ModuleRunner, ModuleRunnerImportMeta, ModuleRunnerOptions } from 'vite/module-runner'; type ModuleRunnerModule = typeof import('vite/module-runner'); /** creates a module runner with Deno import and `import.meta` support */ export type CreateModuleRunner = (options: Pick) => ModuleRunner; /** * loads the dev server's Vite module runner. * * @param url URL of `vite/module-runner` * @returns Deno module runner factory */ export const loadModuleRunner = async (url: string): Promise => { const { createDefaultImportMeta, ESModulesEvaluator, ModuleRunner }: ModuleRunnerModule = await import(url); class DenoEvaluator extends ESModulesEvaluator { // import here because Deno doesn't resolve jsr: specifiers from inside npm packages such as Vite override runExternalModule(file: string): Promise { return import(file); } } // Deno lacks the node:module hooks used by Vite's createNodeImportMeta const createImportMeta = (modulePath: string): ModuleRunnerImportMeta => { const meta = createDefaultImportMeta(modulePath); return { ...meta, // evaluated modules are imports, not the process entrypoint main: false, resolve(specifier: string) { if (/^\.\.?\//.test(specifier)) { return new URL(specifier, meta.url).href; } // match externalized imports: resolve from the runner, not the evaluated module return import.meta.resolve(specifier); }, }; }; return (options) => new ModuleRunner({ ...options, createImportMeta }, new DenoEvaluator()); };