mirror of
https://github.com/vitejs/vite.git
synced 2024-11-21 14:48:41 +00:00
feat(config): support native import
This commit is contained in:
parent
a0336bd519
commit
8e936cd3d9
@ -76,7 +76,11 @@ parentServer.use(vite.middlewares)
|
|||||||
|
|
||||||
The `InlineConfig` interface extends `UserConfig` with additional properties:
|
The `InlineConfig` interface extends `UserConfig` with additional properties:
|
||||||
|
|
||||||
- `configFile`: specify config file to use. If not set, Vite will try to automatically resolve one from project root. Set to `false` to disable auto resolving.
|
- `configFile`: Specify config file to use. If not set, Vite will try to automatically resolve one from project root. Set to `false` to disable auto resolving.
|
||||||
|
- `configFileNativeImport`: Whether to use native `import()` to import the config file. This is useful if the default behaviour of writing a temporary file to the filesystem is undesirable. However, you'll lose other features such as:
|
||||||
|
- TypeScript support if the runtime does not support it.
|
||||||
|
- Automatic server restarts if the files imported by the config (recursively) are updated.
|
||||||
|
- Cache busting of files imported by the config (recursively). A full manual restart is required.
|
||||||
- `envFile`: Set to `false` to disable `.env` files.
|
- `envFile`: Set to `false` to disable `.env` files.
|
||||||
|
|
||||||
## `ResolvedConfig`
|
## `ResolvedConfig`
|
||||||
|
@ -19,6 +19,7 @@ interface GlobalCLIOptions {
|
|||||||
'--'?: string[]
|
'--'?: string[]
|
||||||
c?: boolean | string
|
c?: boolean | string
|
||||||
config?: string
|
config?: string
|
||||||
|
configNativeImport?: boolean
|
||||||
base?: string
|
base?: string
|
||||||
l?: LogLevel
|
l?: LogLevel
|
||||||
logLevel?: LogLevel
|
logLevel?: LogLevel
|
||||||
@ -83,6 +84,7 @@ function cleanGlobalCLIOptions<Options extends GlobalCLIOptions>(
|
|||||||
delete ret['--']
|
delete ret['--']
|
||||||
delete ret.c
|
delete ret.c
|
||||||
delete ret.config
|
delete ret.config
|
||||||
|
delete ret.configNativeImport
|
||||||
delete ret.base
|
delete ret.base
|
||||||
delete ret.l
|
delete ret.l
|
||||||
delete ret.logLevel
|
delete ret.logLevel
|
||||||
@ -180,6 +182,7 @@ cli
|
|||||||
base: options.base,
|
base: options.base,
|
||||||
mode: options.mode,
|
mode: options.mode,
|
||||||
configFile: options.config,
|
configFile: options.config,
|
||||||
|
configFileNativeImport: options.configNativeImport,
|
||||||
logLevel: options.logLevel,
|
logLevel: options.logLevel,
|
||||||
clearScreen: options.clearScreen,
|
clearScreen: options.clearScreen,
|
||||||
optimizeDeps: { force: options.force },
|
optimizeDeps: { force: options.force },
|
||||||
@ -304,6 +307,7 @@ cli
|
|||||||
base: options.base,
|
base: options.base,
|
||||||
mode: options.mode,
|
mode: options.mode,
|
||||||
configFile: options.config,
|
configFile: options.config,
|
||||||
|
configFileNativeImport: options.configNativeImport,
|
||||||
logLevel: options.logLevel,
|
logLevel: options.logLevel,
|
||||||
clearScreen: options.clearScreen,
|
clearScreen: options.clearScreen,
|
||||||
build: buildOptions,
|
build: buildOptions,
|
||||||
@ -340,6 +344,7 @@ cli
|
|||||||
root,
|
root,
|
||||||
base: options.base,
|
base: options.base,
|
||||||
configFile: options.config,
|
configFile: options.config,
|
||||||
|
configFileNativeImport: options.configNativeImport,
|
||||||
logLevel: options.logLevel,
|
logLevel: options.logLevel,
|
||||||
mode: options.mode,
|
mode: options.mode,
|
||||||
},
|
},
|
||||||
@ -382,6 +387,7 @@ cli
|
|||||||
root,
|
root,
|
||||||
base: options.base,
|
base: options.base,
|
||||||
configFile: options.config,
|
configFile: options.config,
|
||||||
|
configFileNativeImport: options.configNativeImport,
|
||||||
logLevel: options.logLevel,
|
logLevel: options.logLevel,
|
||||||
mode: options.mode,
|
mode: options.mode,
|
||||||
build: {
|
build: {
|
||||||
|
@ -519,7 +519,22 @@ export interface ResolvedWorkerOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface InlineConfig extends UserConfig {
|
export interface InlineConfig extends UserConfig {
|
||||||
|
/**
|
||||||
|
* Specify config file to use. If not set, Vite will try to automatically resolve one from project root.
|
||||||
|
* Set to false to disable auto resolving.
|
||||||
|
*/
|
||||||
configFile?: string | false
|
configFile?: string | false
|
||||||
|
/**
|
||||||
|
* Whether to use native `import()` to import the config file. This is useful if the default behaviour of
|
||||||
|
* writing a temporary file to the filesystem is undesirable. However, you'll lose other features such as:
|
||||||
|
* - TypeScript support if the runtime does not support it.
|
||||||
|
* - Automatic server restarts if the files imported by the config (recursively) are updated.
|
||||||
|
* - Cache busting of files imported by the config (recursively). A full manual restart is required.
|
||||||
|
*/
|
||||||
|
configFileNativeImport?: boolean
|
||||||
|
/**
|
||||||
|
* Set to false to disable .env files
|
||||||
|
*/
|
||||||
envFile?: false
|
envFile?: false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -834,7 +849,10 @@ export async function resolveConfig(
|
|||||||
|
|
||||||
let { configFile } = config
|
let { configFile } = config
|
||||||
if (configFile !== false) {
|
if (configFile !== false) {
|
||||||
const loadResult = await loadConfigFromFile(
|
const loadConfigFn = config.configFileNativeImport
|
||||||
|
? loadConfigNative
|
||||||
|
: loadConfigFromFile
|
||||||
|
const loadResult = await loadConfigFn(
|
||||||
configEnv,
|
configEnv,
|
||||||
configFile,
|
configFile,
|
||||||
config.root,
|
config.root,
|
||||||
@ -1465,6 +1483,76 @@ export function sortUserPlugins(
|
|||||||
return [prePlugins, normalPlugins, postPlugins]
|
return [prePlugins, normalPlugins, postPlugins]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function searchConfigFile(root: string, configFile?: string) {
|
||||||
|
let resolvedPath: string | undefined
|
||||||
|
|
||||||
|
if (configFile) {
|
||||||
|
// explicit config path is always resolved from cwd
|
||||||
|
resolvedPath = path.resolve(configFile)
|
||||||
|
} else {
|
||||||
|
// implicit config file loaded from inline root (if present)
|
||||||
|
// otherwise from cwd
|
||||||
|
for (const filename of DEFAULT_CONFIG_FILES) {
|
||||||
|
const filePath = path.resolve(root, filename)
|
||||||
|
if (!fs.existsSync(filePath)) continue
|
||||||
|
|
||||||
|
resolvedPath = filePath
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolvedPath
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadConfigNative(
|
||||||
|
configEnv: ConfigEnv,
|
||||||
|
configFile?: string,
|
||||||
|
configRoot: string = process.cwd(),
|
||||||
|
logLevel?: LogLevel,
|
||||||
|
customLogger?: Logger,
|
||||||
|
): Promise<{
|
||||||
|
path: string
|
||||||
|
config: UserConfig
|
||||||
|
dependencies: string[]
|
||||||
|
} | null> {
|
||||||
|
const start = debug ? performance.now() : 0
|
||||||
|
const getTime = () => `${(performance.now() - start).toFixed(2)}ms`
|
||||||
|
|
||||||
|
const resolvedPath = searchConfigFile(configRoot, configFile)
|
||||||
|
if (!resolvedPath) {
|
||||||
|
debug?.('no config file found.')
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await import(
|
||||||
|
pathToFileURL(resolvedPath).href + '?t=' + Date.now()
|
||||||
|
)
|
||||||
|
debug?.(`config file imported in ${getTime()}`)
|
||||||
|
|
||||||
|
const userConfig = result.default as UserConfigExport
|
||||||
|
const config = await (typeof userConfig === 'function'
|
||||||
|
? userConfig(configEnv)
|
||||||
|
: userConfig)
|
||||||
|
if (!isObject(config)) {
|
||||||
|
throw new Error(`config must export or return an object.`)
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
path: normalizePath(resolvedPath),
|
||||||
|
config,
|
||||||
|
dependencies: [],
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
createLogger(logLevel, { customLogger }).error(
|
||||||
|
colors.red(`failed to load config from ${resolvedPath}`),
|
||||||
|
{
|
||||||
|
error: e,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function loadConfigFromFile(
|
export async function loadConfigFromFile(
|
||||||
configEnv: ConfigEnv,
|
configEnv: ConfigEnv,
|
||||||
configFile?: string,
|
configFile?: string,
|
||||||
@ -1476,26 +1564,10 @@ export async function loadConfigFromFile(
|
|||||||
config: UserConfig
|
config: UserConfig
|
||||||
dependencies: string[]
|
dependencies: string[]
|
||||||
} | null> {
|
} | null> {
|
||||||
const start = performance.now()
|
const start = debug ? performance.now() : 0
|
||||||
const getTime = () => `${(performance.now() - start).toFixed(2)}ms`
|
const getTime = () => `${(performance.now() - start).toFixed(2)}ms`
|
||||||
|
|
||||||
let resolvedPath: string | undefined
|
const resolvedPath = searchConfigFile(configRoot, configFile)
|
||||||
|
|
||||||
if (configFile) {
|
|
||||||
// explicit config path is always resolved from cwd
|
|
||||||
resolvedPath = path.resolve(configFile)
|
|
||||||
} else {
|
|
||||||
// implicit config file loaded from inline root (if present)
|
|
||||||
// otherwise from cwd
|
|
||||||
for (const filename of DEFAULT_CONFIG_FILES) {
|
|
||||||
const filePath = path.resolve(configRoot, filename)
|
|
||||||
if (!fs.existsSync(filePath)) continue
|
|
||||||
|
|
||||||
resolvedPath = filePath
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!resolvedPath) {
|
if (!resolvedPath) {
|
||||||
debug?.('no config file found.')
|
debug?.('no config file found.')
|
||||||
return null
|
return null
|
||||||
|
Loading…
Reference in New Issue
Block a user