-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: use module runner to import the config #18637
base: main
Are you sure you want to change the base?
Conversation
fa4e6dd
to
3965409
Compare
Probably the test are failing because we support |
This looks similar to what Astro has been doing, which starts up the Vite server and Question: Does the module runner handle CJS config files well?
I'd honestly love if we start to not support them 😅 Separately from this PR, maybe we should start warning if we see them and suggest using |
Good catch! We can inject it with a different evaluator. |
Hm, module runner only supports ESM. Injecting To support a CJS config, we need to reimplement most of vite-node's "mix cjs-esm" code. Unless we forbid CJS altogether 😄 |
e546e04
to
31a84d9
Compare
I added |
Shouldn't using the module runner be opt-in instead? IIUC there's features like For the option name, it would be nice if it's |
It is opt-in, |
Oh didn't notice that, I thought it was |
Yeah, I agree. I just couldn't come up with a good name. I like |
1eb3dcc
to
65578af
Compare
packages/vite/src/node/cli.ts
Outdated
.option( | ||
'--configLoader <loader>', | ||
`[string] use 'bundle' to bundle the config with esbuild or 'runner' to process it on the fly (default: bundle)`, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to flag this experimental? I guess it's fine not to, but just to confirm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can mark it as experimental since the environment API is experimental 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Marked it like this:
- [string] use 'bundle' to bundle the config with esbuild or 'runner' to process it on the fly (default: bundle)
+ [string] use 'bundle' to bundle the config with esbuild or 'runner' (experimental) to process it on the fly (default: bundle)
.default | ||
const environment = createRunnableDevEnvironment( | ||
'inline', | ||
// TODO: provide a dummy config? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this TODO comment still relevant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Open to discussion. The environment requires a config and we know every plugin that will be used - should we provide a dummy config instead to make it faster? (I mention the time in the description of the issue)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we set configFile: false
? It should skip trying to find a config file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^this still takes 5-6ms (bundle approach takes 0 for this step as it is not needed)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, so you're trying to reduce the resolveConfig
call cost. I'll vote for keep using resolveConfig
here than { ...thingseNeeded } as ResolvedConfig
.
Maybe we can set envFile: false, cacheDir: process.cwd()
and make this call only happen when needed?
vite/packages/vite/src/node/config.ts
Line 1246 in ae68958
const pkgDir = findNearestPackageData(resolvedRoot, packageCache)?.dir |
That should eliminate the probably costly fs calls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding these shaved off ~1ms
commit: |
} finally { | ||
await environment.close() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we close the environment here, dynamic import happening after the main module import throws Error: Vite module runner has been closed.
. Here is a repro https://stackblitz.com/edit/93byylkl?file=index.js (and I pushed an example as test case)
Do we need to give up explicit close here and rely on proper gc instead?
(Also, dynamic import doesn't appear as dependencies
. I'm not sure what is the case with bundled config though.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The environment also overrides global Error.captureStackTrace
and close
removes the override, so we would have to either disable this and patch the error if it happens or return the environment and document that it should be closed manually (or just return the close
method)
dynamic import doesn't appear as
dependencies
Dynamic import is not in dependencies because it wasn't executed. We can store ssrResult.dependencies
as module.parsedDependencies
maybe 🤷🏻
Description
This PR implements an optional
--configLoader=runner
CLI flag andconfigLoader: 'runner'
inline config property to opt-in to use the module runner instead of bundling the config file.runner
only supports ESM syntax and cannot be used with CJS syntax like__filename
/__dirname
/module
.Some advantages:
type: module
needed)Benchmarking the
vitest.config.ts
file in the root:resolveConfig
to construct a simple resolved config (environment requires a config, we can construct a small one just for this environment since we control all private plugins)init
plugin containerrunner.import
AsyncFunction
ssrTransform
esbuild
Overall the new approach takes ~28-32ms and the old one takes ~14-22ms, but resolving the config is not a hot path fortunetly. We can also shave off 5-6ms if we provide a dummy config
This PR also adds an
runnerImport
experimental helper that creates a temporary environment with a module runner to import a single file.