UNPKG

vite

Version:

Native-ESM powered web dev build tool

1,406 lines (1,317 loc) 153 kB
/// <reference types="node" /> import { PluginHooks, RollupError, SourceMap, ModuleInfo, PartialResolvedId, RollupOptions, InputOption, ModuleFormat, WatcherOptions, RollupOutput, RollupWatcher, InputOptions, CustomPluginOptions, LoadResult, SourceDescription, PluginContextMeta, RollupLog, OutputBundle, OutputChunk, ObjectHook, ResolveIdResult, ExistingRawSourceMap, SourceMapInput, GetManualChunk } from 'rollup'; import * as rollup from 'rollup'; export { rollup as Rollup }; export { parseAst, parseAstAsync } from 'rollup/parseAst'; import * as http from 'node:http'; import { OutgoingHttpHeaders, ClientRequestArgs, IncomingMessage, ClientRequest, Agent, Server, 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 { ServerOptions as HttpsServerOptions, Server as HttpsServer } 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 { FetchFunctionOptions, FetchResult, ModuleRunnerOptions, ModuleRunnerHmr, ModuleEvaluator, ModuleRunner } from 'vite/module-runner'; export { FetchFunction, FetchResult } from 'vite/module-runner'; import { BuildOptions as esbuild_BuildOptions, TransformOptions as esbuild_TransformOptions, TransformResult as esbuild_TransformResult } from 'esbuild'; export { TransformOptions as EsbuildTransformOptions, version as esbuildVersion } from 'esbuild'; import { HotPayload, CustomPayload } from '../../types/hmrPayload.js'; export { ConnectedPayload, CustomPayload, ErrorPayload, FullReloadPayload, HMRPayload, HotPayload, PrunePayload, Update, UpdatePayload } from '../../types/hmrPayload.js'; import { InferCustomEventPayload } from '../../types/customEvent.js'; export { CustomEventMap, InferCustomEventPayload, InvalidatePayload } from '../../types/customEvent.js'; import { SecureContextOptions } from 'node:tls'; import { ZlibOptions } from 'node:zlib'; import * as PostCSS from 'postcss'; import { LightningCSSOptions } from '../../types/internal/lightningcssOptions.js'; export { LightningCSSOptions } from '../../types/internal/lightningcssOptions.js'; import { SassLegacyPreprocessBaseOptions, SassModernPreprocessBaseOptions, LessPreprocessorBaseOptions, StylusPreprocessorBaseOptions } from '../../types/internal/cssPreprocessorOptions.js'; import { M as ModuleRunnerTransport } from './moduleRunnerTransport.d-CXw_Ws6P.js'; export { GeneralImportGlobOptions, ImportGlobFunction, ImportGlobOptions, KnownAsTypeMap } from '../../types/importGlob.js'; export { ChunkMetadata } from '../../types/metadata.js'; 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 } type AnymatchFn = (testString: string) => boolean type AnymatchPattern = string | RegExp | AnymatchFn type AnymatchMatcher = AnymatchPattern | AnymatchPattern[] // Inlined to avoid extra dependency (chokidar is bundled in the published build) 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 } // Inlined to avoid extra dependency // MIT Licensed https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/LICENSE 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 } } // Inlined to avoid extra dependency // MIT Licensed https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/LICENSE 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 } } 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; } 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; 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)[]; type RequiredExceptFor<T, K extends keyof T> = Pick<T, K> & Required<Omit<T, K>>; 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: void, 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>; 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>; }; declare class PartialEnvironment { name: string; getTopLevelConfig(): ResolvedConfig; config: ResolvedConfig & ResolvedEnvironmentOptions; /** * @deprecated use environment.config instead **/ get options(): ResolvedEnvironmentOptions; logger: Logger; constructor(name: string, topLevelConfig: ResolvedConfig, options?: ResolvedEnvironmentOptions); } declare class BaseEnvironment extends PartialEnvironment { get plugins(): Plugin[]; 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"` specfically. It's * a placeholder for more possible environment types. */ declare class UnknownEnvironment extends BaseEnvironment { mode: "unknown"; } declare class ScanEnvironment extends BaseEnvironment { mode: "scan"; get pluginContainer(): EnvironmentPluginContainer; init(): Promise<void>; } 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 * @experimental */ 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>; interface TransformResult { code: string; map: SourceMap | { mappings: ''; } | null; ssr?: boolean; etag?: string; deps?: string[]; dynamicDeps?: string[]; } interface TransformOptions { /** * @deprecated inferred from environment */ ssr?: boolean; } 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; } 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'; 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; /** * @deprecated use this.environment in the hotUpdate hook instead **/ environment: DevEnvironment; } interface HmrContext { file: string; timestamp: number; modules: Array<ModuleNode>; read: () => string | Promise<string>; server: ViteDevServer; } interface HotChannelClient { send(payload: HotPayload): void; } /** @deprecated use `HotChannelClient` instead */ type HMRBroadcasterClient = HotChannelClient; type HotChannelListener<T extends string = string> = (data: InferCustomEventPayload<T>, client: HotChannelClient) => void; interface HotChannel<Api = any> { /** * Broadcast events to all clients */ send?(payload: 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; } /** @deprecated use `HotChannel` instead */ type HMRChannel = HotChannel; interface NormalizedHotChannelClient { /** * Send event to the client */ send(payload: HotPayload): void; /** * Send custom event */ send(event: string, payload?: CustomPayload['data']): void; } interface NormalizedHotChannel<Api = any> { /** * Broadcast events to all clients */ send(payload: 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: 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>; /** @deprecated use `ServerHotChannel` instead */ type ServerHMRChannel = ServerHotChannel; declare function createServerHotChannel(): ServerHotChannel; /** @deprecated use `environment.hot` instead */ interface HotBroadcaster extends NormalizedHotChannel { readonly channels: NormalizedHotChannel[]; /** * A noop. * @deprecated */ addChannel(channel: HotChannel): HotBroadcaster; close(): Promise<unknown[]>; } /** @deprecated use `environment.hot` instead */ type HMRBroadcaster = HotBroadcaster; // Modified and inlined to avoid extra dependency // Source: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/ws/index.d.ts declare const WebSocketAlias: typeof WebSocket interface WebSocketAlias extends WebSocket {} // 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.EventListenerOpti