TypeScript Type Hints for Configuration Items in Vite
The default configuration file for vite
is vite.config.ts
, and the most basic configuration file format is as follows:
export default {
// configuration options
};
We can also specify a configuration file using the --config
command line option, by entering: vite --config configFile.js
.
When adding vite
configuration using the vscode
editor, there are no hints from the compiler, which is not user-friendly! (The hint in the image below is not a vite
configuration hint, but rather a general JS syntax hint from the plugin)
WebStorm
has excellent syntax completion functionality, while vscode
does not. Therefore, to enable intelligent hints from the compiler, we can use the following two special approaches.
defineConfig
Using the official defineConfig
, you can see configuration item hints.
Looking at the source code:
export type UserConfigFn = (
env: ConfigEnv
) => UserConfig | Promise<UserConfig>;
export type UserConfigExport =
| UserConfig
| Promise<UserConfig>
| UserConfigFn;
/**
* Type helper to make it easier to use vite.config.ts
* accepts a direct {@link UserConfig} object, or a function that returns it.
* The function receives a {@link ConfigEnv} object that exposes two properties:
* `command` (either `'build'` or `'serve'`), and `mode`.
*/
export function defineConfig(config: UserConfigExport): UserConfigExport {
return config;
}
We can see that it essentially uses TypeScript
for type hints.
JSDoc Comment Method
JSDoc
is an API
documentation generator for JavaScript
, official website.
Using comments to provide type hints for referenced objects:
/** @type import("vite").UserConfig */
Environment Mode Configuration
In the webpack
era, developers typically set up different configuration files based on different environments, such as: webpack.dev.config
, webpack.prod.config
, webpack.base.config
...
In vite
, to set different configurations based on different environments, you just need to export a function like this:
export default defineConfig(({ command, mode, ssrBuild }) => {
if (command === 'serve') {
return {
// dev-specific configuration
};
} else {
// command === 'build'
return {
// build-specific configuration
};
}
});
Optimized writing style:
import { defineConfig } from 'vite';
import viteBaseConfig from './vite.base.config';
import viteDevConfig from './vite.dev.config';
import viteProdConfig from './vite.prod.config';
const envResolver = {
// build: () => ({...viteBaseConfig,viteProdConfig}) this way also works
// The {} in Object.assign is to prevent viteBaseConfig from being modified.
build: () => ({ ...viteBaseConfig, ...viteProdConfig }),
serve: () => ({ ...viteBaseConfig, ...viteDevConfig })
};
export default defineConfig(({ command, mode, ssrBuild }) => {
return envResolver[command]();
});
Additionally, defineConfig
also supports asynchronous configuration. If the configuration needs to call an asynchronous function, you can export an asynchronous function instead:
export default defineConfig(async ({ command, mode }) => {
const data = await asyncFunction();
return {
// vite configuration
};
});