UNPKG

vite

Version:

Native-ESM powered web dev build tool

1,245 lines (1,202 loc) 144 kB
/// <reference types="node" /> import { ModuleRunnerTransport } from "./moduleRunnerTransport-BWUZBVLX.js"; import { ConnectedPayload, CustomPayload, CustomPayload as hmrPayload_CustomPayload, ErrorPayload, FullReloadPayload, HMRPayload, HotPayload, HotPayload as hmrPayload_HotPayload, PrunePayload, Update, UpdatePayload } from "../../types/hmrPayload.js"; import { CustomEventMap, InferCustomEventPayload, InferCustomEventPayload as hmrPayload_InferCustomEventPayload, InvalidatePayload } from "../../types/customEvent.js"; import * as Rollup from "rollup"; import { CustomPluginOptions, ExistingRawSourceMap, InputOption, InputOptions, LoadResult, MinimalPluginContext, ModuleFormat, ModuleInfo, ObjectHook, OutputBundle, OutputChunk, PartialResolvedId, PluginContext, PluginContextMeta, PluginHooks, ResolveIdResult, RollupError, RollupLog, RollupOptions, RollupOutput, RollupWatcher, SourceDescription, SourceMap, SourceMapInput, TransformPluginContext, WatcherOptions } from "rollup"; import { parseAst, parseAstAsync } from "rollup/parseAst"; import * as http from "node:http"; import { Agent, ClientRequest, ClientRequestArgs, OutgoingHttpHeaders, ServerResponse } from "node:http"; import { Http2SecureServer } from "node:http2"; import * as fs from "node:fs"; import * as events from "node:events"; import { EventEmitter } from "node:events"; import { Server as HttpsServer, ServerOptions as HttpsServerOptions } from "node:https"; import * as net from "node:net"; import * as url from "node:url"; import { URL } from "node:url"; import * as stream from "node:stream"; import { Duplex, DuplexOptions } from "node:stream"; import { FetchFunction, FetchFunctionOptions, FetchResult, FetchResult as moduleRunner_FetchResult, ModuleEvaluator, ModuleRunner, ModuleRunnerHmr, ModuleRunnerOptions } from "vite/module-runner"; import { BuildOptions as esbuild_BuildOptions, TransformOptions as EsbuildTransformOptions, TransformOptions as esbuild_TransformOptions, TransformResult as esbuild_TransformResult, version as esbuildVersion } from "esbuild"; import { SecureContextOptions } from "node:tls"; import { ZlibOptions } from "node:zlib"; import { Terser, TerserMinifyOptions } from "../../types/internal/terserOptions.js"; import * as PostCSS from "postcss"; import { LightningCSSOptions, LightningCSSOptions as lightningcssOptions_LightningCSSOptions } from "../../types/internal/lightningcssOptions.js"; import { LessPreprocessorBaseOptions, SassModernPreprocessBaseOptions, StylusPreprocessorBaseOptions } from "../../types/internal/cssPreprocessorOptions.js"; import { GeneralImportGlobOptions, ImportGlobFunction, ImportGlobOptions, KnownAsTypeMap } from "../../types/importGlob.js"; import { ChunkMetadata, CustomPluginOptionsVite } from "../../types/metadata.js"; //#region src/types/alias.d.ts interface Alias { find: string | RegExp; replacement: string; /** * Instructs the plugin to use an alternative resolving algorithm, * rather than the Rollup's resolver. * @default null */ customResolver?: ResolverFunction | ResolverObject | null; } type MapToFunction<T> = T extends Function ? T : never; type ResolverFunction = MapToFunction<PluginHooks['resolveId']>; interface ResolverObject { buildStart?: PluginHooks['buildStart']; resolveId: ResolverFunction; } /** * Specifies an `Object`, or an `Array` of `Object`, * which defines aliases used to replace values in `import` or `require` statements. * With either format, the order of the entries is important, * in that the first defined rules are applied first. * * This is passed to \@rollup/plugin-alias as the "entries" field * https://github.com/rollup/plugins/tree/master/packages/alias#entries */ type AliasOptions = readonly Alias[] | { [find: string]: string; }; //#endregion //#region src/types/anymatch.d.ts type AnymatchFn = (testString: string) => boolean; type AnymatchPattern = string | RegExp | AnymatchFn; type AnymatchMatcher = AnymatchPattern | AnymatchPattern[]; //#endregion //#region src/types/chokidar.d.ts declare class FSWatcher extends EventEmitter implements fs.FSWatcher { options: WatchOptions; /** * Constructs a new FSWatcher instance with optional WatchOptions parameter. */ constructor(options?: WatchOptions); /** * When called, requests that the Node.js event loop not exit so long as the fs.FSWatcher is active. * Calling watcher.ref() multiple times will have no effect. */ ref(): this; /** * When called, the active fs.FSWatcher object will not require the Node.js event loop to remain active. * If there is no other activity keeping the event loop running, the process may exit before the fs.FSWatcher object's callback is invoked. * Calling watcher.unref() multiple times will have no effect. */ unref(): this; /** * Add files, directories, or glob patterns for tracking. Takes an array of strings or just one * string. */ add(paths: string | ReadonlyArray<string>): this; /** * Stop watching files, directories, or glob patterns. Takes an array of strings or just one * string. */ unwatch(paths: string | ReadonlyArray<string>): this; /** * Returns an object representing all the paths on the file system being watched by this * `FSWatcher` instance. The object's keys are all the directories (using absolute paths unless * the `cwd` option was used), and the values are arrays of the names of the items contained in * each directory. */ getWatched(): { [directory: string]: string[]; }; /** * Removes all listeners from watched files. */ close(): Promise<void>; on(event: 'add' | 'addDir' | 'change', listener: (path: string, stats?: fs.Stats) => void): this; on(event: 'all', listener: (eventName: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir', path: string, stats?: fs.Stats) => void): this; /** * Error occurred */ on(event: 'error', listener: (error: Error) => void): this; /** * Exposes the native Node `fs.FSWatcher events` */ on(event: 'raw', listener: (eventName: string, path: string, details: any) => void): this; /** * Fires when the initial scan is complete */ on(event: 'ready', listener: () => void): this; on(event: 'unlink' | 'unlinkDir', listener: (path: string) => void): this; on(event: string, listener: (...args: any[]) => void): this; } interface WatchOptions { /** * Indicates whether the process should continue to run as long as files are being watched. If * set to `false` when using `fsevents` to watch, no more events will be emitted after `ready`, * even if the process continues to run. */ persistent?: boolean; /** * ([anymatch](https://github.com/micromatch/anymatch)-compatible definition) Defines files/paths to * be ignored. The whole relative or absolute path is tested, not just filename. If a function * with two arguments is provided, it gets called twice per path - once with a single argument * (the path), second time with two arguments (the path and the * [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) object of that path). */ ignored?: AnymatchMatcher; /** * If set to `false` then `add`/`addDir` events are also emitted for matching paths while * instantiating the watching as chokidar discovers these file paths (before the `ready` event). */ ignoreInitial?: boolean; /** * When `false`, only the symlinks themselves will be watched for changes instead of following * the link references and bubbling events through the link's path. */ followSymlinks?: boolean; /** * The base directory from which watch `paths` are to be derived. Paths emitted with events will * be relative to this. */ cwd?: string; /** * If set to true then the strings passed to .watch() and .add() are treated as literal path * names, even if they look like globs. * * @default false */ disableGlobbing?: boolean; /** * Whether to use fs.watchFile (backed by polling), or fs.watch. If polling leads to high CPU * utilization, consider setting this to `false`. It is typically necessary to **set this to * `true` to successfully watch files over a network**, and it may be necessary to successfully * watch files in other non-standard situations. Setting to `true` explicitly on OS X overrides * the `useFsEvents` default. */ usePolling?: boolean; /** * Whether to use the `fsevents` watching interface if available. When set to `true` explicitly * and `fsevents` is available this supersedes the `usePolling` setting. When set to `false` on * OS X, `usePolling: true` becomes the default. */ useFsEvents?: boolean; /** * If relying upon the [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) object that * may get passed with `add`, `addDir`, and `change` events, set this to `true` to ensure it is * provided even in cases where it wasn't already available from the underlying watch events. */ alwaysStat?: boolean; /** * If set, limits how many levels of subdirectories will be traversed. */ depth?: number; /** * Interval of file system polling. */ interval?: number; /** * Interval of file system polling for binary files. ([see list of binary extensions](https://gi * thub.com/sindresorhus/binary-extensions/blob/master/binary-extensions.json)) */ binaryInterval?: number; /** * Indicates whether to watch files that don't have read permissions if possible. If watching * fails due to `EPERM` or `EACCES` with this set to `true`, the errors will be suppressed * silently. */ ignorePermissionErrors?: boolean; /** * `true` if `useFsEvents` and `usePolling` are `false`. Automatically filters out artifacts * that occur when using editors that use "atomic writes" instead of writing directly to the * source file. If a file is re-added within 100 ms of being deleted, Chokidar emits a `change` * event rather than `unlink` then `add`. If the default of 100 ms does not work well for you, * you can override it by setting `atomic` to a custom value, in milliseconds. */ atomic?: boolean | number; /** * can be set to an object in order to adjust timing params: */ awaitWriteFinish?: AwaitWriteFinishOptions | boolean; } interface AwaitWriteFinishOptions { /** * Amount of time in milliseconds for a file size to remain constant before emitting its event. */ stabilityThreshold?: number; /** * File size polling interval. */ pollInterval?: number; } /** * produces an instance of `FSWatcher`. */ //#endregion //#region src/types/connect.d.ts declare namespace Connect { export type ServerHandle = HandleFunction | http.Server; export class IncomingMessage extends http.IncomingMessage { originalUrl?: http.IncomingMessage['url'] | undefined; } export type NextFunction = (err?: any) => void; export type SimpleHandleFunction = (req: IncomingMessage, res: http.ServerResponse) => void; export type NextHandleFunction = (req: IncomingMessage, res: http.ServerResponse, next: NextFunction) => void; export type ErrorHandleFunction = (err: any, req: IncomingMessage, res: http.ServerResponse, next: NextFunction) => void; export type HandleFunction = SimpleHandleFunction | NextHandleFunction | ErrorHandleFunction; export interface ServerStackItem { route: string; handle: ServerHandle; } export interface Server extends NodeJS.EventEmitter { (req: http.IncomingMessage, res: http.ServerResponse, next?: Function): void; route: string; stack: ServerStackItem[]; /** * Utilize the given middleware `handle` to the given `route`, * defaulting to _/_. This "route" is the mount-point for the * middleware, when given a value other than _/_ the middleware * is only effective when that segment is present in the request's * pathname. * * For example if we were to mount a function at _/admin_, it would * be invoked on _/admin_, and _/admin/settings_, however it would * not be invoked for _/_, or _/posts_. */ use(fn: NextHandleFunction): Server; use(fn: HandleFunction): Server; use(route: string, fn: NextHandleFunction): Server; use(route: string, fn: HandleFunction): Server; /** * Handle server requests, punting them down * the middleware stack. */ handle(req: http.IncomingMessage, res: http.ServerResponse, next: Function): void; /** * Listen for connections. * * This method takes the same arguments * as node's `http.Server#listen()`. * * HTTP and HTTPS: * * If you run your application both as HTTP * and HTTPS you may wrap them individually, * since your Connect "server" is really just * a JavaScript `Function`. * * var connect = require('connect') * , http = require('http') * , https = require('https'); * * var app = connect(); * * http.createServer(app).listen(80); * https.createServer(options, app).listen(443); */ listen(port: number, hostname?: string, backlog?: number, callback?: Function): http.Server; listen(port: number, hostname?: string, callback?: Function): http.Server; listen(path: string, callback?: Function): http.Server; listen(handle: any, listeningListener?: Function): http.Server; } } //#endregion //#region src/types/http-proxy.d.ts declare namespace HttpProxy { export type ProxyTarget = ProxyTargetUrl | ProxyTargetDetailed; export type ProxyTargetUrl = string | Partial<url.Url>; export interface ProxyTargetDetailed { host: string; port: number; protocol?: string | undefined; hostname?: string | undefined; socketPath?: string | undefined; key?: string | undefined; passphrase?: string | undefined; pfx?: Buffer | string | undefined; cert?: string | undefined; ca?: string | undefined; ciphers?: string | undefined; secureProtocol?: string | undefined; } export type ErrorCallback = (err: Error, req: http.IncomingMessage, res: http.ServerResponse, target?: ProxyTargetUrl) => void; export class Server extends events.EventEmitter { /** * Creates the proxy server with specified options. * @param options - Config object passed to the proxy */ constructor(options?: ServerOptions); /** * Used for proxying regular HTTP(S) requests * @param req - Client request. * @param res - Client response. * @param options - Additional options. * @param callback - Error callback. */ web(req: http.IncomingMessage, res: http.ServerResponse, options?: ServerOptions, callback?: ErrorCallback): void; /** * Used for proxying regular HTTP(S) requests * @param req - Client request. * @param socket - Client socket. * @param head - Client head. * @param options - Additional options. * @param callback - Error callback. */ ws(req: http.IncomingMessage, socket: unknown, head: unknown, options?: ServerOptions, callback?: ErrorCallback): void; /** * A function that wraps the object in a webserver, for your convenience * @param port - Port to listen on */ listen(port: number): Server; /** * A function that closes the inner webserver and stops listening on given port */ close(callback?: () => void): void; /** * Creates the proxy server with specified options. * @param options - Config object passed to the proxy * @returns Proxy object with handlers for `ws` and `web` requests */ static createProxyServer(options?: ServerOptions): Server; /** * Creates the proxy server with specified options. * @param options - Config object passed to the proxy * @returns Proxy object with handlers for `ws` and `web` requests */ static createServer(options?: ServerOptions): Server; /** * Creates the proxy server with specified options. * @param options - Config object passed to the proxy * @returns Proxy object with handlers for `ws` and `web` requests */ static createProxy(options?: ServerOptions): Server; addListener(event: string, listener: () => void): this; on(event: string, listener: () => void): this; on(event: 'error', listener: ErrorCallback): this; on(event: 'start', listener: (req: http.IncomingMessage, res: http.ServerResponse, target: ProxyTargetUrl) => void): this; on(event: 'proxyReq', listener: (proxyReq: http.ClientRequest, req: http.IncomingMessage, res: http.ServerResponse, options: ServerOptions) => void): this; on(event: 'proxyRes', listener: (proxyRes: http.IncomingMessage, req: http.IncomingMessage, res: http.ServerResponse) => void): this; on(event: 'proxyReqWs', listener: (proxyReq: http.ClientRequest, req: http.IncomingMessage, socket: net.Socket, options: ServerOptions, head: any) => void): this; on(event: 'econnreset', listener: (err: Error, req: http.IncomingMessage, res: http.ServerResponse, target: ProxyTargetUrl) => void): this; on(event: 'end', listener: (req: http.IncomingMessage, res: http.ServerResponse, proxyRes: http.IncomingMessage) => void): this; on(event: 'close', listener: (proxyRes: http.IncomingMessage, proxySocket: net.Socket, proxyHead: any) => void): this; once(event: string, listener: () => void): this; removeListener(event: string, listener: () => void): this; removeAllListeners(event?: string): this; getMaxListeners(): number; setMaxListeners(n: number): this; listeners(event: string): Array<() => void>; emit(event: string, ...args: any[]): boolean; listenerCount(type: string): number; } export interface ServerOptions { /** URL string to be parsed with the url module. */ target?: ProxyTarget | undefined; /** URL string to be parsed with the url module. */ forward?: ProxyTargetUrl | undefined; /** Object to be passed to http(s).request. */ agent?: any; /** Object to be passed to https.createServer(). */ ssl?: any; /** If you want to proxy websockets. */ ws?: boolean | undefined; /** Adds x- forward headers. */ xfwd?: boolean | undefined; /** Verify SSL certificate. */ secure?: boolean | undefined; /** Explicitly specify if we are proxying to another proxy. */ toProxy?: boolean | undefined; /** Specify whether you want to prepend the target's path to the proxy path. */ prependPath?: boolean | undefined; /** Specify whether you want to ignore the proxy path of the incoming request. */ ignorePath?: boolean | undefined; /** Local interface string to bind for outgoing connections. */ localAddress?: string | undefined; /** Changes the origin of the host header to the target URL. */ changeOrigin?: boolean | undefined; /** specify whether you want to keep letter case of response header key */ preserveHeaderKeyCase?: boolean | undefined; /** Basic authentication i.e. 'user:password' to compute an Authorization header. */ auth?: string | undefined; /** Rewrites the location hostname on (301 / 302 / 307 / 308) redirects, Default: null. */ hostRewrite?: string | undefined; /** Rewrites the location host/ port on (301 / 302 / 307 / 308) redirects based on requested host/ port.Default: false. */ autoRewrite?: boolean | undefined; /** Rewrites the location protocol on (301 / 302 / 307 / 308) redirects to 'http' or 'https'.Default: null. */ protocolRewrite?: string | undefined; /** rewrites domain of set-cookie headers. */ cookieDomainRewrite?: false | string | { [oldDomain: string]: string; } | undefined; /** rewrites path of set-cookie headers. Default: false */ cookiePathRewrite?: false | string | { [oldPath: string]: string; } | undefined; /** object with extra headers to be added to target requests. */ headers?: { [header: string]: string; } | undefined; /** Timeout (in milliseconds) when proxy receives no response from target. Default: 120000 (2 minutes) */ proxyTimeout?: number | undefined; /** Timeout (in milliseconds) for incoming requests */ timeout?: number | undefined; /** Specify whether you want to follow redirects. Default: false */ followRedirects?: boolean | undefined; /** If set to true, none of the webOutgoing passes are called and it's your responsibility to appropriately return the response by listening and acting on the proxyRes event */ selfHandleResponse?: boolean | undefined; /** Buffer */ buffer?: stream.Stream | undefined; } } //#endregion //#region src/node/server/middlewares/proxy.d.ts interface ProxyOptions extends HttpProxy.ServerOptions { /** * rewrite path */ rewrite?: (path: string) => string; /** * configure the proxy server (e.g. listen to events) */ configure?: (proxy: HttpProxy.Server, options: ProxyOptions) => void; /** * webpack-dev-server style bypass function */ bypass?: (req: http.IncomingMessage, /** undefined for WebSocket upgrade requests */ res: http.ServerResponse | undefined, options: ProxyOptions) => void | null | undefined | false | string | Promise<void | null | undefined | boolean | string>; /** * rewrite the Origin header of a WebSocket request to match the target * * **Exercise caution as rewriting the Origin can leave the proxying open to [CSRF attacks](https://owasp.org/www-community/attacks/csrf).** */ rewriteWsOrigin?: boolean | undefined; } //#endregion //#region src/node/logger.d.ts type LogType = 'error' | 'warn' | 'info'; type LogLevel = LogType | 'silent'; interface Logger { info(msg: string, options?: LogOptions): void; warn(msg: string, options?: LogOptions): void; warnOnce(msg: string, options?: LogOptions): void; error(msg: string, options?: LogErrorOptions): void; clearScreen(type: LogType): void; hasErrorLogged(error: Error | RollupError): boolean; hasWarned: boolean; } interface LogOptions { clear?: boolean; timestamp?: boolean; environment?: string; } interface LogErrorOptions extends LogOptions { error?: Error | RollupError | null; } interface LoggerOptions { prefix?: string; allowClearScreen?: boolean; customLogger?: Logger; console?: Console; } declare function createLogger(level?: LogLevel, options?: LoggerOptions): Logger; //#endregion //#region src/node/http.d.ts interface CommonServerOptions { /** * Specify server port. Note if the port is already being used, Vite will * automatically try the next available port so this may not be the actual * port the server ends up listening on. */ port?: number; /** * If enabled, vite will exit if specified port is already in use */ strictPort?: boolean; /** * Specify which IP addresses the server should listen on. * Set to 0.0.0.0 to listen on all addresses, including LAN and public addresses. */ host?: string | boolean; /** * The hostnames that Vite is allowed to respond to. * `localhost` and subdomains under `.localhost` and all IP addresses are allowed by default. * When using HTTPS, this check is skipped. * * If a string starts with `.`, it will allow that hostname without the `.` and all subdomains under the hostname. * For example, `.example.com` will allow `example.com`, `foo.example.com`, and `foo.bar.example.com`. * * If set to `true`, the server is allowed to respond to requests for any hosts. * This is not recommended as it will be vulnerable to DNS rebinding attacks. */ allowedHosts?: string[] | true; /** * Enable TLS + HTTP/2. * Note: this downgrades to TLS only when the proxy option is also used. */ https?: HttpsServerOptions; /** * Open browser window on startup */ open?: boolean | string; /** * Configure custom proxy rules for the dev server. Expects an object * of `{ key: options }` pairs. * Uses [`http-proxy`](https://github.com/http-party/node-http-proxy). * Full options [here](https://github.com/http-party/node-http-proxy#options). * * Example `vite.config.js`: * ``` js * module.exports = { * proxy: { * // string shorthand: /foo -> http://localhost:4567/foo * '/foo': 'http://localhost:4567', * // with options * '/api': { * target: 'http://jsonplaceholder.typicode.com', * changeOrigin: true, * rewrite: path => path.replace(/^\/api/, '') * } * } * } * ``` */ proxy?: Record<string, string | ProxyOptions>; /** * Configure CORS for the dev server. * Uses https://github.com/expressjs/cors. * * When enabling this option, **we recommend setting a specific value * rather than `true`** to avoid exposing the source code to untrusted origins. * * Set to `true` to allow all methods from any origin, or configure separately * using an object. * * @default false */ cors?: CorsOptions | boolean; /** * Specify server response headers. */ headers?: OutgoingHttpHeaders; } /** * https://github.com/expressjs/cors#configuration-options */ interface CorsOptions { /** * Configures the Access-Control-Allow-Origin CORS header. * * **We recommend setting a specific value rather than * `true`** to avoid exposing the source code to untrusted origins. */ origin?: CorsOrigin | ((origin: string | undefined, cb: (err: Error, origins: CorsOrigin) => void) => void); methods?: string | string[]; allowedHeaders?: string | string[]; exposedHeaders?: string | string[]; credentials?: boolean; maxAge?: number; preflightContinue?: boolean; optionsSuccessStatus?: number; } type CorsOrigin = boolean | string | RegExp | (string | RegExp)[]; //#endregion //#region src/node/typeUtils.d.ts type RequiredExceptFor<T, K extends keyof T> = Pick<T, K> & Required<Omit<T, K>>; //#endregion //#region src/node/preview.d.ts interface PreviewOptions extends CommonServerOptions {} interface ResolvedPreviewOptions extends RequiredExceptFor<PreviewOptions, 'host' | 'https' | 'proxy'> {} interface PreviewServer { /** * The resolved vite config object */ config: ResolvedConfig; /** * Stop the server. */ close(): Promise<void>; /** * A connect app instance. * - Can be used to attach custom middlewares to the preview server. * - Can also be used as the handler function of a custom http server * or as a middleware in any connect-style Node.js frameworks * * https://github.com/senchalabs/connect#use-middleware */ middlewares: Connect.Server; /** * native Node http server instance */ httpServer: HttpServer; /** * The resolved urls Vite prints on the CLI (URL-encoded). Returns `null` * if the server is not listening on any port. */ resolvedUrls: ResolvedServerUrls | null; /** * Print server urls */ printUrls(): void; /** * Bind CLI shortcuts */ bindCLIShortcuts(options?: BindCLIShortcutsOptions<PreviewServer>): void; } type PreviewServerHook = (this: MinimalPluginContextWithoutEnvironment, server: PreviewServer) => (() => void) | void | Promise<(() => void) | void>; /** * Starts the Vite server in preview mode, to simulate a production deployment */ declare function preview(inlineConfig?: InlineConfig): Promise<PreviewServer>; //#endregion //#region src/node/shortcuts.d.ts type BindCLIShortcutsOptions<Server = ViteDevServer | PreviewServer> = { /** * Print a one-line shortcuts "help" hint to the terminal */ print?: boolean; /** * Custom shortcuts to run when a key is pressed. These shortcuts take priority * over the default shortcuts if they have the same keys (except the `h` key). * To disable a default shortcut, define the same key but with `action: undefined`. */ customShortcuts?: CLIShortcut<Server>[]; }; type CLIShortcut<Server = ViteDevServer | PreviewServer> = { key: string; description: string; action?(server: Server): void | Promise<void>; }; //#endregion //#region src/node/baseEnvironment.d.ts declare class PartialEnvironment { name: string; getTopLevelConfig(): ResolvedConfig; config: ResolvedConfig & ResolvedEnvironmentOptions; logger: Logger; constructor(name: string, topLevelConfig: ResolvedConfig, options?: ResolvedEnvironmentOptions); } declare class BaseEnvironment extends PartialEnvironment { get plugins(): readonly Plugin$1[]; constructor(name: string, config: ResolvedConfig, options?: ResolvedEnvironmentOptions); } /** * This class discourages users from inversely checking the `mode` * to determine the type of environment, e.g. * * ```js * const isDev = environment.mode !== 'build' // bad * const isDev = environment.mode === 'dev' // good * ``` * * You should also not check against `"unknown"` specifically. It's * a placeholder for more possible environment types. */ declare class UnknownEnvironment extends BaseEnvironment { mode: "unknown"; } //#endregion //#region src/node/optimizer/scan.d.ts declare class ScanEnvironment extends BaseEnvironment { mode: "scan"; get pluginContainer(): EnvironmentPluginContainer; init(): Promise<void>; } //#endregion //#region src/node/optimizer/index.d.ts type ExportsData = { hasModuleSyntax: boolean; exports: readonly string[]; jsxLoader?: boolean; }; interface DepsOptimizer { init: () => Promise<void>; metadata: DepOptimizationMetadata; scanProcessing?: Promise<void>; registerMissingImport: (id: string, resolved: string) => OptimizedDepInfo; run: () => void; isOptimizedDepFile: (id: string) => boolean; isOptimizedDepUrl: (url: string) => boolean; getOptimizedDepId: (depInfo: OptimizedDepInfo) => string; close: () => Promise<void>; options: DepOptimizationOptions; } interface DepOptimizationConfig { /** * Force optimize listed dependencies (must be resolvable import paths, * cannot be globs). */ include?: string[]; /** * Do not optimize these dependencies (must be resolvable import paths, * cannot be globs). */ exclude?: string[]; /** * Forces ESM interop when importing these dependencies. Some legacy * packages advertise themselves as ESM but use `require` internally * @experimental */ needsInterop?: string[]; /** * Options to pass to esbuild during the dep scanning and optimization * * Certain options are omitted since changing them would not be compatible * with Vite's dep optimization. * * - `external` is also omitted, use Vite's `optimizeDeps.exclude` option * - `plugins` are merged with Vite's dep plugin * * https://esbuild.github.io/api */ esbuildOptions?: Omit<esbuild_BuildOptions, 'bundle' | 'entryPoints' | 'external' | 'write' | 'watch' | 'outdir' | 'outfile' | 'outbase' | 'outExtension' | 'metafile'>; /** * List of file extensions that can be optimized. A corresponding esbuild * plugin must exist to handle the specific extension. * * By default, Vite can optimize `.mjs`, `.js`, `.ts`, and `.mts` files. This option * allows specifying additional extensions. * * @experimental */ extensions?: string[]; /** * Deps optimization during build was removed in Vite 5.1. This option is * now redundant and will be removed in a future version. Switch to using * `optimizeDeps.noDiscovery` and an empty or undefined `optimizeDeps.include`. * true or 'dev' disables the optimizer, false or 'build' leaves it enabled. * @default 'build' * @deprecated * @experimental */ disabled?: boolean | 'build' | 'dev'; /** * Automatic dependency discovery. When `noDiscovery` is true, only dependencies * listed in `include` will be optimized. The scanner isn't run for cold start * in this case. CJS-only dependencies must be present in `include` during dev. * @default false */ noDiscovery?: boolean; /** * When enabled, it will hold the first optimized deps results until all static * imports are crawled on cold start. This avoids the need for full-page reloads * when new dependencies are discovered and they trigger the generation of new * common chunks. If all dependencies are found by the scanner plus the explicitly * defined ones in `include`, it is better to disable this option to let the * browser process more requests in parallel. * @default true * @experimental */ holdUntilCrawlEnd?: boolean; } type DepOptimizationOptions = DepOptimizationConfig & { /** * By default, Vite will crawl your `index.html` to detect dependencies that * need to be pre-bundled. If `build.rollupOptions.input` is specified, Vite * will crawl those entry points instead. * * If neither of these fit your needs, you can specify custom entries using * this option - the value should be a tinyglobby pattern or array of patterns * (https://github.com/SuperchupuDev/tinyglobby) that are relative from * vite project root. This will overwrite default entries inference. */ entries?: string | string[]; /** * Force dep pre-optimization regardless of whether deps have changed. * @experimental */ force?: boolean; }; interface OptimizedDepInfo { id: string; file: string; src?: string; needsInterop?: boolean; browserHash?: string; fileHash?: string; /** * During optimization, ids can still be resolved to their final location * but the bundles may not yet be saved to disk */ processing?: Promise<void>; /** * ExportData cache, discovered deps will parse the src entry to get exports * data used both to define if interop is needed and when pre-bundling */ exportsData?: Promise<ExportsData>; } interface DepOptimizationMetadata { /** * The main hash is determined by user config and dependency lockfiles. * This is checked on server startup to avoid unnecessary re-bundles. */ hash: string; /** * This hash is determined by dependency lockfiles. * This is checked on server startup to avoid unnecessary re-bundles. */ lockfileHash: string; /** * This hash is determined by user config. * This is checked on server startup to avoid unnecessary re-bundles. */ configHash: string; /** * The browser hash is determined by the main hash plus additional dependencies * discovered at runtime. This is used to invalidate browser requests to * optimized deps. */ browserHash: string; /** * Metadata for each already optimized dependency */ optimized: Record<string, OptimizedDepInfo>; /** * Metadata for non-entry optimized chunks and dynamic imports */ chunks: Record<string, OptimizedDepInfo>; /** * Metadata for each newly discovered dependency after processing */ discovered: Record<string, OptimizedDepInfo>; /** * OptimizedDepInfo list */ depInfoList: OptimizedDepInfo[]; } /** * Scan and optimize dependencies within a project. * Used by Vite CLI when running `vite optimize`. * * @deprecated the optimization process runs automatically and does not need to be called */ declare function optimizeDeps(config: ResolvedConfig, force?: boolean | undefined, asCommand?: boolean): Promise<DepOptimizationMetadata>; //#endregion //#region src/node/server/transformRequest.d.ts interface TransformResult { code: string; map: SourceMap | { mappings: ''; } | null; ssr?: boolean; etag?: string; deps?: string[]; dynamicDeps?: string[]; } interface TransformOptions { /** * @deprecated inferred from environment */ ssr?: boolean; } //#endregion //#region src/node/server/moduleGraph.d.ts declare class EnvironmentModuleNode { environment: string; /** * Public served url path, starts with / */ url: string; /** * Resolved file system path + query */ id: string | null; file: string | null; type: 'js' | 'css'; info?: ModuleInfo; meta?: Record<string, any>; importers: Set<EnvironmentModuleNode>; importedModules: Set<EnvironmentModuleNode>; acceptedHmrDeps: Set<EnvironmentModuleNode>; acceptedHmrExports: Set<string> | null; importedBindings: Map<string, Set<string>> | null; isSelfAccepting?: boolean; transformResult: TransformResult | null; ssrModule: Record<string, any> | null; ssrError: Error | null; lastHMRTimestamp: number; lastInvalidationTimestamp: number; /** * @param setIsSelfAccepting - set `false` to set `isSelfAccepting` later. e.g. #7870 */ constructor(url: string, environment: string, setIsSelfAccepting?: boolean); } type ResolvedUrl = [url: string, resolvedId: string, meta: object | null | undefined]; declare class EnvironmentModuleGraph { environment: string; urlToModuleMap: Map<string, EnvironmentModuleNode>; idToModuleMap: Map<string, EnvironmentModuleNode>; etagToModuleMap: Map<string, EnvironmentModuleNode>; fileToModulesMap: Map<string, Set<EnvironmentModuleNode>>; constructor(environment: string, resolveId: (url: string) => Promise<PartialResolvedId | null>); getModuleByUrl(rawUrl: string): Promise<EnvironmentModuleNode | undefined>; getModuleById(id: string): EnvironmentModuleNode | undefined; getModulesByFile(file: string): Set<EnvironmentModuleNode> | undefined; onFileChange(file: string): void; onFileDelete(file: string): void; invalidateModule(mod: EnvironmentModuleNode, seen?: Set<EnvironmentModuleNode>, timestamp?: number, isHmr?: boolean, ): void; invalidateAll(): void; /** * Update the module graph based on a module's updated imports information * If there are dependencies that no longer have any importers, they are * returned as a Set. * * @param staticImportedUrls Subset of `importedModules` where they're statically imported in code. * This is only used for soft invalidations so `undefined` is fine but may cause more runtime processing. */ updateModuleInfo(mod: EnvironmentModuleNode, importedModules: Set<string | EnvironmentModuleNode>, importedBindings: Map<string, Set<string>> | null, acceptedModules: Set<string | EnvironmentModuleNode>, acceptedExports: Set<string> | null, isSelfAccepting: boolean, ): Promise<Set<EnvironmentModuleNode> | undefined>; ensureEntryFromUrl(rawUrl: string, setIsSelfAccepting?: boolean): Promise<EnvironmentModuleNode>; createFileOnlyEntry(file: string): EnvironmentModuleNode; resolveUrl(url: string): Promise<ResolvedUrl>; updateModuleTransformResult(mod: EnvironmentModuleNode, result: TransformResult | null): void; getModuleByEtag(etag: string): EnvironmentModuleNode | undefined; } //#endregion //#region src/node/server/mixedModuleGraph.d.ts declare class ModuleNode { _moduleGraph: ModuleGraph; _clientModule: EnvironmentModuleNode | undefined; _ssrModule: EnvironmentModuleNode | undefined; constructor(moduleGraph: ModuleGraph, clientModule?: EnvironmentModuleNode, ssrModule?: EnvironmentModuleNode); _get<T extends keyof EnvironmentModuleNode>(prop: T): EnvironmentModuleNode[T]; _set<T extends keyof EnvironmentModuleNode>(prop: T, value: EnvironmentModuleNode[T]): void; _wrapModuleSet(prop: ModuleSetNames, module: EnvironmentModuleNode | undefined): Set<ModuleNode>; _getModuleSetUnion(prop: 'importedModules' | 'importers'): Set<ModuleNode>; _getModuleInfoUnion(prop: 'info'): ModuleInfo | undefined; _getModuleObjectUnion(prop: 'meta'): Record<string, any> | undefined; get url(): string; set url(value: string); get id(): string | null; set id(value: string | null); get file(): string | null; set file(value: string | null); get type(): 'js' | 'css'; get info(): ModuleInfo | undefined; get meta(): Record<string, any> | undefined; get importers(): Set<ModuleNode>; get clientImportedModules(): Set<ModuleNode>; get ssrImportedModules(): Set<ModuleNode>; get importedModules(): Set<ModuleNode>; get acceptedHmrDeps(): Set<ModuleNode>; get acceptedHmrExports(): Set<string> | null; get importedBindings(): Map<string, Set<string>> | null; get isSelfAccepting(): boolean | undefined; get transformResult(): TransformResult | null; set transformResult(value: TransformResult | null); get ssrTransformResult(): TransformResult | null; set ssrTransformResult(value: TransformResult | null); get ssrModule(): Record<string, any> | null; get ssrError(): Error | null; get lastHMRTimestamp(): number; set lastHMRTimestamp(value: number); get lastInvalidationTimestamp(): number; get invalidationState(): TransformResult | 'HARD_INVALIDATED' | undefined; get ssrInvalidationState(): TransformResult | 'HARD_INVALIDATED' | undefined; } declare class ModuleGraph { urlToModuleMap: Map<string, ModuleNode>; idToModuleMap: Map<string, ModuleNode>; etagToModuleMap: Map<string, ModuleNode>; fileToModulesMap: Map<string, Set<ModuleNode>>; private moduleNodeCache; constructor(moduleGraphs: { client: () => EnvironmentModuleGraph; ssr: () => EnvironmentModuleGraph; }); getModuleById(id: string): ModuleNode | undefined; getModuleByUrl(url: string, _ssr?: boolean): Promise<ModuleNode | undefined>; getModulesByFile(file: string): Set<ModuleNode> | undefined; onFileChange(file: string): void; onFileDelete(file: string): void; invalidateModule(mod: ModuleNode, seen?: Set<ModuleNode>, timestamp?: number, isHmr?: boolean, ): void; invalidateAll(): void; ensureEntryFromUrl(rawUrl: string, ssr?: boolean, setIsSelfAccepting?: boolean): Promise<ModuleNode>; createFileOnlyEntry(file: string): ModuleNode; resolveUrl(url: string, ssr?: boolean): Promise<ResolvedUrl>; updateModuleTransformResult(mod: ModuleNode, result: TransformResult | null, ssr?: boolean): void; getModuleByEtag(etag: string): ModuleNode | undefined; getBackwardCompatibleBrowserModuleNode(clientModule: EnvironmentModuleNode): ModuleNode; getBackwardCompatibleServerModuleNode(ssrModule: EnvironmentModuleNode): ModuleNode; getBackwardCompatibleModuleNode(mod: EnvironmentModuleNode): ModuleNode; getBackwardCompatibleModuleNodeDual(clientModule?: EnvironmentModuleNode, ssrModule?: EnvironmentModuleNode): ModuleNode; } type ModuleSetNames = 'acceptedHmrDeps' | 'importedModules'; //#endregion //#region src/node/server/hmr.d.ts interface HmrOptions { protocol?: string; host?: string; port?: number; clientPort?: number; path?: string; timeout?: number; overlay?: boolean; server?: HttpServer; } interface HotUpdateOptions { type: 'create' | 'update' | 'delete'; file: string; timestamp: number; modules: Array<EnvironmentModuleNode>; read: () => string | Promise<string>; server: ViteDevServer; } interface HmrContext { file: string; timestamp: number; modules: Array<ModuleNode>; read: () => string | Promise<string>; server: ViteDevServer; } interface HotChannelClient { send(payload: hmrPayload_HotPayload): void; } type HotChannelListener<T extends string = string> = (data: InferCustomEventPayload<T>, client: HotChannelClient) => void; interface HotChannel<Api = any> { /** * Broadcast events to all clients */ send?(payload: hmrPayload_HotPayload): void; /** * Handle custom event emitted by `import.meta.hot.send` */ on?<T extends string>(event: T, listener: HotChannelListener<T>): void; on?(event: 'connection', listener: () => void): void; /** * Unregister event listener */ off?(event: string, listener: Function): void; /** * Start listening for messages */ listen?(): void; /** * Disconnect all clients, called when server is closed or restarted. */ close?(): Promise<unknown> | void; api?: Api; } interface NormalizedHotChannelClient { /** * Send event to the client */ send(payload: hmrPayload_HotPayload): void; /** * Send custom event */ send(event: string, payload?: hmrPayload_CustomPayload['data']): void; } interface NormalizedHotChannel<Api = any> { /** * Broadcast events to all clients */ send(payload: hmrPayload_HotPayload): void; /** * Send custom event */ send<T extends string>(event: T, payload?: InferCustomEventPayload<T>): void; /** * Handle custom event emitted by `import.meta.hot.send` */ on<T extends string>(event: T, listener: (data: InferCustomEventPayload<T>, client: NormalizedHotChannelClient) => void): void; on(event: 'connection', listener: () => void): void; /** * Unregister event listener */ off(event: string, listener: Function): void; handleInvoke(payload: hmrPayload_HotPayload): Promise<{ result: any; } | { error: any; }>; /** * Start listening for messages */ listen(): void; /** * Disconnect all clients, called when server is closed or restarted. */ close(): Promise<unknown> | void; api?: Api; } type ServerHotChannelApi = { innerEmitter: EventEmitter; outsideEmitter: EventEmitter; }; type ServerHotChannel = HotChannel<ServerHotChannelApi>; type NormalizedServerHotChannel = NormalizedHotChannel<ServerHotChannelApi>; declare function createServerHotChannel(): ServerHotChannel; //#endregion //#region src/types/ws.d.ts // WebSocket socket. declare class WebSocket extends EventEmitter { /** The connection is not yet open. */ static readonly CONNECTING: 0; /** The connection is open and ready to communicate. */ static readonly OPEN: 1; /** The connection is in the process of closing. */ static readonly CLOSING: 2; /** The connection is closed. */ static readonly CLOSED: 3; binaryType: 'nodebuffer' | 'arraybuffer' | 'fragments'; readonly bufferedAmount: number; readonly extensions: string; /** Indicates whether the websocket is paused */ readonly isPaused: boolean; readonly protocol: string; /** The current state of the connection */ readonly readyState: typeof WebSocket.CONNECTING | typeof WebSocket.OPEN | typeof WebSocket.CLOSING | typeof WebSocket.CLOSED; readonly url: string; /** The connection is not yet open. */ readonly CONNECTING: 0; /** The connection is open and ready to communicate. */ readonly OPEN: 1; /** The connection is in the process of closing. */ readonly CLOSING: 2; /** The connection is closed. */ readonly CLOSED: 3; onopen: ((event: WebSocket.Event) => void) | null; onerror: ((event: WebSocket.ErrorEvent) => void) | null; onclose: ((event: WebSocket.CloseEvent) => void) | null; onmessage: ((event: WebSocket.MessageEvent) => void) | null; constructor(address: null); constructor(address: string | URL, options?: WebSocket.ClientOptions | ClientRequestArgs); constructor(address: string | URL, protocols?: string | string[], options?: WebSocket.ClientOptions | ClientRequestArgs); close(code?: number, data?: string | Buffer): void; ping(data?: any, mask?: boolean, cb?: (err: Error) => void): void; pong(data?: any, mask?: boolean, cb?: (err: Error) => void): void; send(data: any, cb?: (err?: Error) => void): void; send(data: any, options: { mask?: boolean | undefined; binary?: boolean | undefined; compress?: boolean | undefined; fin?: boolean | undefined; }, cb?: (err?: Error) => void): void; terminate(): void; /** * Pause the websocket causing it to stop emitting events. Some events can still be * emitted after this is called, until all buffered data is consumed. This method * is a noop if the ready state is `CONNECTING` or `CLOSED`. */ pause(): void; /** * Make a paused socket resume emitting events. This method is a noop if the ready * state is `CONNECTING` or `CLOSED`. */ resume(): void; // HTML5 WebSocket events addEventListener(method: 'message', cb: (event: WebSocket.MessageEvent) => void, options?: WebSocket.EventListenerOptions): void; addEventListener(method: 'close', cb: (event: WebSocket.CloseEvent) => void, options?: WebSocket.EventListenerOptions): void; addEventListener(method: 'error', cb: (event: WebSocket.ErrorEvent) => void, options?: WebSocket.EventListenerOptions): void; addEventListener(method: 'open', cb: (event: WebSocket.Event) => void, options?: WebSocket.EventListenerOptions): void; removeEventListener(method: 'message', cb: (event: WebSocket.MessageEvent) => void): void; removeEventListener(method: 'close', cb: (event: WebSocket.CloseEvent) => void): void; removeEventListener(method: 'error', cb: (event: WebSocket.ErrorEvent) => void): void; removeEventListener(method: 'open', cb: (event: WebSocket.Event) => void): void; // Events on(event: 'close', listener: (this: WebSocket, code: number, reason: Buffer) => void): this; on(event: 'error', listener: (this: WebSocket, err: Error) => void): this; on(event: 'upgrade', listener: (this: WebSocket, request: http.IncomingMessage) => void): this; on(event: 'message', listener: (this: WebSocket, data: WebSocket.RawData, isBinary: boolean) => void): this; on(event: 'open', listener: (this: WebSocket) => void): this; on(event: 'ping' | 'pong', listener: (this: WebSocket, data: Buffer) => void): this; on(event: 'unexpected-response', listener: (this: WebSocket, request: ClientRequest, response: http.IncomingMessage) => void): this; on(event: string | symbol, listener: (this: WebSocket, ...args: any[]) => void): this; once(event: 'close', listener: (this: WebSocket, code: number, reason: Buffer) => void): this; once(event: 'error', listener: (this: WebSocket, err: Error) => void): this; once(event: 'upgrade', listener: (this: WebSocket, request: http.IncomingMessage) => void): this; once(event: 'message', listener: (this: WebSocket, data: WebSocket.RawData, isBinary: boolean) => void): this; once(event: 'open', listener: (this: WebSocket) => void): this; once(event: 'ping' | 'pong', listener: (this: WebSocket, data: Buffer) => void): this; once(event: 'unexpected-response', listener: (this: WebSocket, request: ClientRequest, response: http.IncomingMessage) => void): this; once(event: string | symbol, listener: (this: WebSocket, ...args: any[]) => void): this; off(e