vite
Version:
Native-ESM powered web dev build tool
1,406 lines (1,317 loc) • 153 kB
TypeScript
/// <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