持续更新系列: Vite源码解析一
前言
上一节结尾已经clone好了源码,这一节正式开始看源码,在第一部分我们通过一个vite的项目找到vite源码的重点。
准备
在vite的src下有两个结构,从上一节的createServer
,我们也能猜到这部分的实现肯定是在node端的。所以我们从node文件夹里的index.ts
开始。
src
|
-- client
-- node
|
-- optimizer/
-- plugins/
-- server/
-- ssr/
-- index.ts
index.ts
用来做统一导出,我们在第二行就看到从server
导出的createServer
:
export * from './config'
export { createServer } from './server'
...
因此去server文件夹下的index.ts
找createServer
:
export async function createServer(
inlineConfig: InlineConfig = {}
): Promise<ViteDevServer> {
const config = await resolveConfig(inlineConfig, 'serve', 'development')
const { root, server: serverConfig } = config
const httpsOptions = await resolveHttpsConfig(
config.server.https,
config.cacheDir
)
const ws = createWebSocketServer(httpServer, config, httpsOptions)
...
return server
}
配置相关的源码
共享配置
首先,会看到几个resolveConfig
和resolveHttpsConfig
函数,函数意思就是去解析配置。到resolveConfig
函数所在的文件config.ts
:
export async function resolveConfig(
inlineConfig: InlineConfig,
command: 'build' | 'serve',
defaultMode = 'development'
): Promise<ResolvedConfig> {
let config = inlineConfig
let configFileDependencies: string[] = []
let mode = inlineConfig.mode || defaultMode
...
}
config.ts
文件都是与配置相关的接口和函数。
resolveConfig
的入参是InlineConfig
接口定义的,而InlineConfig
本身是extends另一个config:
export interface InlineConfig extends UserConfig {
configFile?: string | false
envFile?: false
}
最终我们就会发现UserConfig
就是我们在vite官网上所配置的共享配置,上面的配置都可以在UserConfig
接口的定义里找到,如果官网没有及时更新,大家也可以根据这份定义知道Vite增加了哪些新特性。
源码里UserConfig
每一个config的选项还有注释:
export interface UserConfig {
/**
* Project root directory. Can be an absolute path, or a path relative from
* the location of the config file itself.
* @default process.cwd()
*/
root?: string
/**
* Base public path when served in development or production.
* @default '/'
*/
base?: string
/**
* Directory to serve as plain static assets. Files in this directory are
* served and copied to build dist dir as-is without transform. The value
* can be either an absolute file system path or a path relative to <root>.
*
* Set to `false` or an empty string to disable copied static assets to build dist dir.
* @default 'public'
*/
publicDir?: string | false
/**
* Directory to save cache files. Files in this directory are pre-bundled
* deps or some other cache files that generated by vite, which can improve
* the performance. You can use `--force` flag or manually delete the directory
* to regenerate the cache files. The value can be either an absolute file
* system path or a path relative to <root>.
* Default to `.vite` when no `package.json` is detected.
* @default 'node_modules/.vite'
*/
cacheDir?: string
/**
* Explicitly set a mode to run in. This will override the default mode for
* each command, and can be overridden by the command line --mode option.
*/
mode?: string
/**
* Define global variable replacements.
* Entries will be defined on `window` during dev and replaced during build.
*/
define?: Record<string, any>
/**
* Array of vite plugins to use.
*/
plugins?: PluginOption[]
/**
* Configure resolver
*/
resolve?: ResolveOptions & { alias?: AliasOptions }
/**
* CSS related options (preprocessors and CSS modules)
*/
css?: CSSOptions
/**
* JSON loading options
*/
json?: JsonOptions
/**
* Transform options to pass to esbuild.
* Or set to `false` to disable esbuild.
*/
esbuild?: ESBuildOptions | false
/**
* Specify additional picomatch patterns to be treated as static assets.
*/
assetsInclude?: string | RegExp | (string | RegExp)[]
/**
* Server specific options, e.g. host, port, https...
*/
server?: ServerOptions
/**
* Build specific options
*/
build?: BuildOptions
/**
* Preview specific options, e.g. host, port, https...
*/
preview?: PreviewOptions
/**
* Force dep pre-optimization regardless of whether deps have changed.
* @experimental
*/
force?: boolean
/**
* Dep optimization options
*/
optimizeDeps?: DepOptimizationOptions
/**
* SSR specific options
*/
ssr?: SSROptions
/**
* Experimental features
*
* Features under this field are addressed to be changed that might NOT follow semver.
* Please be careful and always pin Vite's version when using them.
* @experimental
*/
experimental?: ExperimentalOptions
/**
* Log level.
* Default: 'info'
*/
logLevel?: LogLevel
/**
* Custom logger.
*/
customLogger?: Logger
/**
* Default: true
*/
clearScreen?: boolean
/**
* Environment files directory. Can be an absolute path, or a path relative from
* the location of the config file itself.
* @default root
*/
envDir?: string
/**
* Env variables starts with `envPrefix` will be exposed to your client source code via import.meta.env.
* @default 'VITE_'
*/
envPrefix?: string | string[]
/**
* Worker bundle options
*/
worker?: {
/**
* Output format for worker bundle
* @default 'iife'
*/
format?: 'es' | 'iife'
/**
* Vite plugins that apply to worker bundle
*/
plugins?: PluginOption[]
/**
* Rollup options to build worker bundle
*/
rollupOptions?: Omit<
RollupOptions,
'plugins' | 'input' | 'onwarn' | 'preserveEntrySignatures'
>
}
/**
* Whether your application is a Single Page Application (SPA). Set to `false`
* for other kinds of apps like MPAs.
* @default true
*/
spa?: boolean
}
服务端配置
顺着这个思路也可以通过resolveHttpsConfig
函数找到CommonServerOptions
,也就是开发服务器配置。
export 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
/**
* Enable TLS + HTTP/2.
* Note: this downgrades to TLS only when the proxy option is also used.
*/
https?: boolean | 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',
* // 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.
* Set to `true` to allow all methods from any origin, or configure separately
* using an object.
*/
cors?: CorsOptions | boolean
/**
* Specify server response headers.
*/
headers?: HttpServerHeaders
}
还有build相关的配置接口参数,我不一一贴上来了,大家可以自己去找找看,看能不能找到。
总结
这一节主要看config.ts
文件中的源码,这也是官网配置Vite这部分的选项来源。搞清楚来源之后就可以去关注具体的实现了。