Skip to content

Commit e487dab

Browse files
committed
feat: use native runtime to import the config
1 parent e06731d commit e487dab

File tree

6 files changed

+72
-28
lines changed

6 files changed

+72
-28
lines changed

docs/config/index.md

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ vite --config my-config.js
2424

2525
::: tip BUNDLING THE CONFIG
2626
By default, Vite uses `esbuild` to bundle the config into a temporary file. This can cause issues when importing TypeScript files in a monorepo. If you encounter any issues with this approach, you can specify `--configLoader=runner` to use the module runner instead - it will not create a temporary config and will transform any files on the fly. Note that module runner doesn't support CJS in config files, but external CJS packages should work as usual.
27+
28+
You can also specify `--configLoader=native` if you prefer to use the environment's native runtime to load the config file.
2729
:::
2830

2931
## Config Intellisense

docs/guide/cli.md

+19-19
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,25 @@ vite [root]
1414

1515
#### Options
1616

17-
| Options | |
18-
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
19-
| `--host [host]` | Specify hostname (`string`) |
20-
| `--port <port>` | Specify port (`number`) |
21-
| `--open [path]` | Open browser on startup (`boolean \| string`) |
22-
| `--cors` | Enable CORS (`boolean`) |
23-
| `--strictPort` | Exit if specified port is already in use (`boolean`) |
24-
| `--force` | Force the optimizer to ignore the cache and re-bundle (`boolean`) |
25-
| `-c, --config <file>` | Use specified config file (`string`) |
26-
| `--base <path>` | Public base path (default: `/`) (`string`) |
27-
| `-l, --logLevel <level>` | info \| warn \| error \| silent (`string`) |
28-
| `--clearScreen` | Allow/disable clear screen when logging (`boolean`) |
29-
| `--configLoader <loader>` | Use `bundle` to bundle the config with esbuild or `runner` (experimental) to process it on the fly (default: `bundle`) |
30-
| `--profile` | Start built-in Node.js inspector (check [Performance bottlenecks](/guide/troubleshooting#performance-bottlenecks)) |
31-
| `-d, --debug [feat]` | Show debug logs (`string \| boolean`) |
32-
| `-f, --filter <filter>` | Filter debug logs (`string`) |
33-
| `-m, --mode <mode>` | Set env mode (`string`) |
34-
| `-h, --help` | Display available CLI options |
35-
| `-v, --version` | Display version number |
17+
| Options | |
18+
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
19+
| `--host [host]` | Specify hostname (`string`) |
20+
| `--port <port>` | Specify port (`number`) |
21+
| `--open [path]` | Open browser on startup (`boolean \| string`) |
22+
| `--cors` | Enable CORS (`boolean`) |
23+
| `--strictPort` | Exit if specified port is already in use (`boolean`) |
24+
| `--force` | Force the optimizer to ignore the cache and re-bundle (`boolean`) |
25+
| `-c, --config <file>` | Use specified config file (`string`) |
26+
| `--base <path>` | Public base path (default: `/`) (`string`) |
27+
| `-l, --logLevel <level>` | info \| warn \| error \| silent (`string`) |
28+
| `--clearScreen` | Allow/disable clear screen when logging (`boolean`) |
29+
| `--configLoader <loader>` | Use `bundle` to bundle the config with esbuild, or `runner` (experimental) to process it on the fly, or `native` (experimental) to load using the native runtime (default: `bundle`) |
30+
| `--profile` | Start built-in Node.js inspector (check [Performance bottlenecks](/guide/troubleshooting#performance-bottlenecks)) |
31+
| `-d, --debug [feat]` | Show debug logs (`string \| boolean`) |
32+
| `-f, --filter <filter>` | Filter debug logs (`string`) |
33+
| `-m, --mode <mode>` | Set env mode (`string`) |
34+
| `-h, --help` | Display available CLI options |
35+
| `-v, --version` | Display version number |
3636

3737
## Build
3838

packages/vite/src/node/cli.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ interface GlobalCLIOptions {
2323
l?: LogLevel
2424
logLevel?: LogLevel
2525
clearScreen?: boolean
26-
configLoader?: 'bundle' | 'runner'
26+
configLoader?: 'bundle' | 'runner' | 'native'
2727
d?: boolean | string
2828
debug?: boolean | string
2929
f?: string
@@ -155,7 +155,7 @@ cli
155155
.option('--clearScreen', `[boolean] allow/disable clear screen when logging`)
156156
.option(
157157
'--configLoader <loader>',
158-
`[string] use 'bundle' to bundle the config with esbuild or 'runner' (experimental) to process it on the fly (default: bundle)`,
158+
`[string] use 'bundle' to bundle the config with esbuild, or 'runner' (experimental) to process it on the fly, or 'native' (experimental) to load using the native runtime (default: bundle)`,
159159
)
160160
.option('-d, --debug [feat]', `[string | boolean] show debug logs`)
161161
.option('-f, --filter <filter>', `[string] filter debug logs`)

packages/vite/src/node/config.ts

+24-6
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@ export interface ResolvedWorkerOptions {
531531
export interface InlineConfig extends UserConfig {
532532
configFile?: string | false
533533
/** @experimental */
534-
configLoader?: 'bundle' | 'runner'
534+
configLoader?: 'bundle' | 'runner' | 'native'
535535
envFile?: false
536536
}
537537

@@ -1646,15 +1646,19 @@ export async function loadConfigFromFile(
16461646
configRoot: string = process.cwd(),
16471647
logLevel?: LogLevel,
16481648
customLogger?: Logger,
1649-
configLoader: 'bundle' | 'runner' = 'bundle',
1649+
configLoader: 'bundle' | 'runner' | 'native' = 'bundle',
16501650
): Promise<{
16511651
path: string
16521652
config: UserConfig
16531653
dependencies: string[]
16541654
} | null> {
1655-
if (configLoader !== 'bundle' && configLoader !== 'runner') {
1655+
if (
1656+
configLoader !== 'bundle' &&
1657+
configLoader !== 'runner' &&
1658+
configLoader !== 'native'
1659+
) {
16561660
throw new Error(
1657-
`Unsupported configLoader: ${configLoader}. Accepted values are 'bundle' and 'runner'.`,
1661+
`Unsupported configLoader: ${configLoader}. Accepted values are 'bundle', 'runner', and 'native'.`,
16581662
)
16591663
}
16601664

@@ -1685,7 +1689,11 @@ export async function loadConfigFromFile(
16851689

16861690
try {
16871691
const resolver =
1688-
configLoader === 'bundle' ? bundleAndLoadConfigFile : importConfigFile
1692+
configLoader === 'bundle'
1693+
? bundleAndLoadConfigFile
1694+
: configLoader === 'runner'
1695+
? runnerImportConfigFile
1696+
: nativeImportConfigFile
16891697
const { configExport, dependencies } = await resolver(resolvedPath)
16901698
debug?.(`config file loaded in ${getTime()}`)
16911699

@@ -1712,7 +1720,17 @@ export async function loadConfigFromFile(
17121720
}
17131721
}
17141722

1715-
async function importConfigFile(resolvedPath: string) {
1723+
async function nativeImportConfigFile(resolvedPath: string) {
1724+
const module = await import(
1725+
pathToFileURL(resolvedPath).href + '?t=' + Date.now()
1726+
)
1727+
return {
1728+
configExport: module.default,
1729+
dependencies: [],
1730+
}
1731+
}
1732+
1733+
async function runnerImportConfigFile(resolvedPath: string) {
17161734
const { module, dependencies } = await runnerImport<{
17171735
default: UserConfigExport
17181736
}>(resolvedPath)

playground/config/__tests__/config.spec.ts

+22-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { resolve } from 'node:path'
22
import { loadConfigFromFile } from 'vite'
3-
import { expect, it } from 'vitest'
3+
import { describe, expect, it } from 'vitest'
44

55
const [nvMajor, nvMinor] = process.versions.node.split('.').map(Number)
66
const isImportAttributesSupported =
@@ -48,3 +48,24 @@ it.runIf(isImportAttributesSupported)(
4848
`)
4949
},
5050
)
51+
52+
describe('loadConfigFromFile with configLoader: native', () => {
53+
const fixtureRoot = resolve(import.meta.dirname, '../packages/native-import')
54+
55+
it('imports a basic js config', async () => {
56+
const result = await loadConfigFromFile(
57+
{} as any,
58+
resolve(fixtureRoot, 'basic.js'),
59+
fixtureRoot,
60+
undefined,
61+
undefined,
62+
'native',
63+
)
64+
expect(result.config).toMatchInlineSnapshot(`
65+
{
66+
"value": "works",
67+
}
68+
`)
69+
expect(result.dependencies.length).toBe(0)
70+
})
71+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default {
2+
value: 'works',
3+
}

0 commit comments

Comments
 (0)