Skip to content

Commit ea8d558

Browse files
committed
feat: use native runtime to import the config
1 parent a4245b0 commit ea8d558

File tree

6 files changed

+74
-30
lines changed

6 files changed

+74
-30
lines changed

docs/config/index.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ You can also explicitly specify a config file to use with the `--config` CLI opt
2222
vite --config my-config.js
2323
```
2424

25-
::: tip BUNDLING THE CONFIG
26-
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.
25+
::: tip CONFIG LOADING
26+
By default, Vite uses `esbuild` to bundle the config into a temporary file and load it. This may 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](/guide/api-environment-runtimes.html#modulerunner) instead, which 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+
Alternatively, if you're using an environment that supports TypeScript (e.g. `node --experimental-strip-types`), or if you're only writing plain JavaScript, you can specify `--configLoader native` to use the environment's native runtime to load the config file. Note that updates to modules imported by the config file are not detected and hence would not auto-restart the Vite server.
2729
:::
2830

2931
## Config Intellisense

docs/guide/cli.md

Lines changed: 19 additions & 19 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ export interface ResolvedWorkerOptions {
546546
export interface InlineConfig extends UserConfig {
547547
configFile?: string | false
548548
/** @experimental */
549-
configLoader?: 'bundle' | 'runner'
549+
configLoader?: 'bundle' | 'runner' | 'native'
550550
envFile?: false
551551
forceOptimizeDeps?: boolean
552552
}
@@ -1696,15 +1696,19 @@ export async function loadConfigFromFile(
16961696
configRoot: string = process.cwd(),
16971697
logLevel?: LogLevel,
16981698
customLogger?: Logger,
1699-
configLoader: 'bundle' | 'runner' = 'bundle',
1699+
configLoader: 'bundle' | 'runner' | 'native' = 'bundle',
17001700
): Promise<{
17011701
path: string
17021702
config: UserConfig
17031703
dependencies: string[]
17041704
} | null> {
1705-
if (configLoader !== 'bundle' && configLoader !== 'runner') {
1705+
if (
1706+
configLoader !== 'bundle' &&
1707+
configLoader !== 'runner' &&
1708+
configLoader !== 'native'
1709+
) {
17061710
throw new Error(
1707-
`Unsupported configLoader: ${configLoader}. Accepted values are 'bundle' and 'runner'.`,
1711+
`Unsupported configLoader: ${configLoader}. Accepted values are 'bundle', 'runner', and 'native'.`,
17081712
)
17091713
}
17101714

@@ -1735,7 +1739,11 @@ export async function loadConfigFromFile(
17351739

17361740
try {
17371741
const resolver =
1738-
configLoader === 'bundle' ? bundleAndLoadConfigFile : importConfigFile
1742+
configLoader === 'bundle'
1743+
? bundleAndLoadConfigFile
1744+
: configLoader === 'runner'
1745+
? runnerImportConfigFile
1746+
: nativeImportConfigFile
17391747
const { configExport, dependencies } = await resolver(resolvedPath)
17401748
debug?.(`config file loaded in ${getTime()}`)
17411749

@@ -1762,7 +1770,17 @@ export async function loadConfigFromFile(
17621770
}
17631771
}
17641772

1765-
async function importConfigFile(resolvedPath: string) {
1773+
async function nativeImportConfigFile(resolvedPath: string) {
1774+
const module = await import(
1775+
pathToFileURL(resolvedPath).href + '?t=' + Date.now()
1776+
)
1777+
return {
1778+
configExport: module.default,
1779+
dependencies: [],
1780+
}
1781+
}
1782+
1783+
async function runnerImportConfigFile(resolvedPath: string) {
17661784
const { module, dependencies } = await runnerImport<{
17671785
default: UserConfigExport
17681786
}>(resolvedPath)

playground/config/__tests__/config.spec.ts

Lines changed: 22 additions & 1 deletion
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+
})
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default {
2+
value: 'works',
3+
}

0 commit comments

Comments
 (0)