Skip to content

Commit 8936d0c

Browse files
committed
docs: revert to lazy field approach for deferred plugin loading
Vite does not support functions or async factories in the plugins array, so there is no native way to truly lazy-load plugins. Revert the troubleshooting docs and snap test to use the vite-plus lazy field.
1 parent 8d0889e commit 8936d0c

File tree

4 files changed

+23
-14
lines changed

4 files changed

+23
-14
lines changed

docs/config/troubleshooting.md

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,36 @@ Use this page when your Vite+ configuration is not behaving the way you expect.
66

77
When `vite.config.ts` imports heavy plugins at the top level, every `import` is evaluated eagerly, even for commands like `vp lint` or `vp fmt` that don't need those plugins. This can make config loading noticeably slow.
88

9-
Vite supports promises in the `plugins` array, so you can use dynamic `import()` to defer heavy plugin loading:
9+
Use the `lazy` field in `defineConfig` to defer heavy plugin loading. Plugins provided through `lazy` are only resolved when Vite actually needs them:
1010

1111
```ts
1212
import { defineConfig } from 'vite-plus';
1313

1414
export default defineConfig({
15-
plugins: [
16-
import('vite-plugin-heavy').then((m) => m.default()),
17-
],
15+
lazy: async () => {
16+
const { default: heavyPlugin } = await import('vite-plugin-heavy');
17+
return { plugins: [heavyPlugin()] };
18+
},
1819
});
1920
```
2021

21-
This way the plugin module is only loaded when Vite actually resolves plugins, keeping config loading fast for commands that don't need them.
22-
23-
You can mix regular plugins with deferred ones. Lightweight plugins stay inline while expensive ones use dynamic `import()`:
22+
You can keep lightweight plugins inline and defer only the expensive ones. Plugins from `lazy` are appended after existing plugins:
2423

2524
```ts
2625
import { defineConfig } from 'vite-plus';
2726
import lightPlugin from 'vite-plugin-light';
2827

2928
export default defineConfig({
30-
plugins: [
31-
lightPlugin(),
32-
import('vite-plugin-heavy').then((m) => m.default()),
33-
],
29+
plugins: [lightPlugin()],
30+
lazy: async () => {
31+
const { default: heavyPlugin } = await import('vite-plugin-heavy');
32+
return { plugins: [heavyPlugin()] };
33+
},
3434
});
3535
```
36+
37+
The resulting plugin order is: `[lightPlugin(), heavyPlugin()]`.
38+
39+
::: info
40+
The `lazy` field is a Vite+ extension. We plan to support this in upstream Vite in the future.
41+
:::
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
> # Test that lazy-loaded plugins via dynamic import are applied during build
1+
> # Test that plugins loaded via lazy field are applied during build
22
> vp build
33
> cat dist/index.html | grep 'lazy-plugin-injected'
44
<!-- lazy-plugin-injected --></body>

packages/cli/snap-tests/lazy-loading-plugins/steps.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"commands": [
3-
"# Test that lazy-loaded plugins via dynamic import are applied during build",
3+
"# Test that plugins loaded via lazy field are applied during build",
44
{
55
"command": "vp build",
66
"ignoreOutput": true
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { defineConfig } from 'vite-plus';
22

33
export default defineConfig({
4-
plugins: [import('./my-plugin').then((m) => m.default())],
4+
lazy: async () => {
5+
const { default: myLazyPlugin } = await import('./my-plugin');
6+
return { plugins: [myLazyPlugin()] };
7+
},
58
});

0 commit comments

Comments
 (0)