diff --git a/docs/guide/api-environment-instances.md b/docs/guide/api-environment-instances.md index 8f750d1638b99f..75af75c00f9ac3 100644 --- a/docs/guide/api-environment-instances.md +++ b/docs/guide/api-environment-instances.md @@ -85,6 +85,18 @@ class DevEnvironment { * so the modules are already processed when they are requested. */ async warmupRequest(url: string): Promise + + /** + * Called by the module runner to retrieve information about the specified + * module. Internally calls `transformRequest` and wraps the result in the + * format that the module runner understands. + * This method is not meant to be called manually. + */ + async fetchModule( + id: string, + importer?: string, + options?: FetchFunctionOptions, + ): Promise } ``` @@ -210,3 +222,69 @@ export class EnvironmentModuleGraph { getModuleByEtag(etag: string): EnvironmentModuleNode | undefined } ``` + +## `FetchResult` + +The `environment.fetchModule` method returns a `FetchResult` that is meant to be consumed by the module runner. `FetchResult` is a union of `CachedFetchResult`, `ExternalFetchResult`, and `ViteFetchResult`. + +`CachedFetchResult` is analogous to the `304` (Not Modified) HTTP status code. + +```ts +export interface CachedFetchResult { + /** + * If the module is cached in the runner, this confirms + * it was not invalidated on the server side. + */ + cache: true +} +``` + +`ExternalFetchResult` instructs the module runner to import the module using the `runExternalModule` method on the [`ModuleEvaluator`](/guide/api-environment-runtimes#moduleevaluator). In this case, the default module evaluator will use the runtime's native `import` instead of processing the file through Vite. + +```ts +export interface ExternalFetchResult { + /** + * The path to the externalized module starting with file://. + * By default this will be imported via a dynamic "import" + * instead of being transformed by Vite and loaded with the Vite runner. + */ + externalize: string + /** + * Type of the module. Used to determine if the import statement is correct. + * For example, if Vite needs to throw an error if a variable is not actually exported. + */ + type: 'module' | 'commonjs' | 'builtin' | 'network' +} +``` + +`ViteFetchResult` returns information about the current module, including the `code` to execute and the module's `id`, `file`, and `url`. + +The `invalidate` field instructs the module runner to invalidate the module before executing it again rather than serving it from cache. This is usually `true` when an HMR update was triggered. + +```ts +export interface ViteFetchResult { + /** + * Code that will be evaluated by the Vite runner. + * By default this will be wrapped in an async function. + */ + code: string + /** + * File path of the module on disk. + * This will be resolved as import.meta.url/filename. + * Will be `null` for virtual modules. + */ + file: string | null + /** + * Module ID in the server module graph. + */ + id: string + /** + * Module URL used in the import. + */ + url: string + /** + * Invalidate module on the client side. + */ + invalidate: boolean +} +``` diff --git a/packages/vite/src/node/server/environment.ts b/packages/vite/src/node/server/environment.ts index ace8cbb3af32dc..de0e62f45bd49e 100644 --- a/packages/vite/src/node/server/environment.ts +++ b/packages/vite/src/node/server/environment.ts @@ -210,6 +210,12 @@ export class DevEnvironment extends BaseEnvironment { warmupFiles(server, this) } + /** + * Called by the module runner to retrieve information about the specified + * module. Internally calls `transformRequest` and wraps the result in the + * format that the module runner understands. + * This method is not meant to be called manually. + */ fetchModule( id: string, importer?: string, diff --git a/packages/vite/src/node/ssr/fetchModule.ts b/packages/vite/src/node/ssr/fetchModule.ts index 5c9aac410eddfe..d64b8ea20ef8dc 100644 --- a/packages/vite/src/node/ssr/fetchModule.ts +++ b/packages/vite/src/node/ssr/fetchModule.ts @@ -18,7 +18,7 @@ export interface FetchModuleOptions { } /** - * Fetch module information for Vite runner. + * Fetch module information for Vite module runner. * @experimental */ export async function fetchModule( diff --git a/packages/vite/src/shared/invokeMethods.ts b/packages/vite/src/shared/invokeMethods.ts index 32793798949520..57b1993060105f 100644 --- a/packages/vite/src/shared/invokeMethods.ts +++ b/packages/vite/src/shared/invokeMethods.ts @@ -10,36 +10,36 @@ export type FetchResult = export interface CachedFetchResult { /** - * If module cached in the runner, we can just confirm - * it wasn't invalidated on the server side. + * If the module is cached in the runner, this confirms + * it was not invalidated on the server side. */ cache: true } export interface ExternalFetchResult { /** - * The path to the externalized module starting with file://, - * by default this will be imported via a dynamic "import" - * instead of being transformed by vite and loaded with vite runner + * The path to the externalized module starting with file://. + * By default this will be imported via a dynamic "import" + * instead of being transformed by Vite and loaded with the Vite runner. */ externalize: string /** - * Type of the module. Will be used to determine if import statement is correct. - * For example, if Vite needs to throw an error if variable is not actually exported + * Type of the module. Used to determine if the import statement is correct. + * For example, if Vite needs to throw an error if a variable is not actually exported. */ type: 'module' | 'commonjs' | 'builtin' | 'network' } export interface ViteFetchResult { /** - * Code that will be evaluated by vite runner - * by default this will be wrapped in an async function + * Code that will be evaluated by the Vite runner. + * By default this will be wrapped in an async function. */ code: string /** * File path of the module on disk. - * This will be resolved as import.meta.url/filename - * Will be equal to `null` for virtual modules + * This will be resolved as import.meta.url/filename. + * Will be `null` for virtual modules. */ file: string | null /**