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:
|
||||
|
||||
- `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.
|
||||
|
||||
## `ResolvedConfig`
|
||||
|
@ -19,6 +19,7 @@ interface GlobalCLIOptions {
|
||||
'--'?: string[]
|
||||
c?: boolean | string
|
||||
config?: string
|
||||
configNativeImport?: boolean
|
||||
base?: string
|
||||
l?: LogLevel
|
||||
logLevel?: LogLevel
|
||||
@ -83,6 +84,7 @@ function cleanGlobalCLIOptions<Options extends GlobalCLIOptions>(
|
||||
delete ret['--']
|
||||
delete ret.c
|
||||
delete ret.config
|
||||
delete ret.configNativeImport
|
||||
delete ret.base
|
||||
delete ret.l
|
||||
delete ret.logLevel
|
||||
@ -180,6 +182,7 @@ cli
|
||||
base: options.base,
|
||||
mode: options.mode,
|
||||
configFile: options.config,
|
||||
configFileNativeImport: options.configNativeImport,
|
||||
logLevel: options.logLevel,
|
||||
clearScreen: options.clearScreen,
|
||||
optimizeDeps: { force: options.force },
|
||||
@ -304,6 +307,7 @@ cli
|
||||
base: options.base,
|
||||
mode: options.mode,
|
||||
configFile: options.config,
|
||||
configFileNativeImport: options.configNativeImport,
|
||||
logLevel: options.logLevel,
|
||||
clearScreen: options.clearScreen,
|
||||
build: buildOptions,
|
||||
@ -340,6 +344,7 @@ cli
|
||||
root,
|
||||
base: options.base,
|
||||
configFile: options.config,
|
||||
configFileNativeImport: options.configNativeImport,
|
||||
logLevel: options.logLevel,
|
||||
mode: options.mode,
|
||||
},
|
||||
@ -382,6 +387,7 @@ cli
|
||||
root,
|
||||
base: options.base,
|
||||
configFile: options.config,
|
||||
configFileNativeImport: options.configNativeImport,
|
||||
logLevel: options.logLevel,
|
||||
mode: options.mode,
|
||||
build: {
|
||||
|
@ -519,7 +519,22 @@ export interface ResolvedWorkerOptions {
|
||||
}
|
||||
|
||||
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
|
||||
/**
|
||||
* 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
|
||||
}
|
||||
|
||||
@ -834,7 +849,10 @@ export async function resolveConfig(
|
||||
|
||||
let { configFile } = config
|
||||
if (configFile !== false) {
|
||||
const loadResult = await loadConfigFromFile(
|
||||
const loadConfigFn = config.configFileNativeImport
|
||||
? loadConfigNative
|
||||
: loadConfigFromFile
|
||||
const loadResult = await loadConfigFn(
|
||||
configEnv,
|
||||
configFile,
|
||||
config.root,
|
||||
@ -1465,6 +1483,76 @@ export function sortUserPlugins(
|
||||
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(
|
||||
configEnv: ConfigEnv,
|
||||
configFile?: string,
|
||||
@ -1476,26 +1564,10 @@ export async function loadConfigFromFile(
|
||||
config: UserConfig
|
||||
dependencies: string[]
|
||||
} | null> {
|
||||
const start = performance.now()
|
||||
const start = debug ? performance.now() : 0
|
||||
const getTime = () => `${(performance.now() - start).toFixed(2)}ms`
|
||||
|
||||
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(configRoot, filename)
|
||||
if (!fs.existsSync(filePath)) continue
|
||||
|
||||
resolvedPath = filePath
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const resolvedPath = searchConfigFile(configRoot, configFile)
|
||||
if (!resolvedPath) {
|
||||
debug?.('no config file found.')
|
||||
return null
|
||||
|
Loading…
Reference in New Issue
Block a user