Skip to content

Commit b3cb2f5

Browse files
committed
docs: move lazy loading docs to config troubleshooting page
Use Vite's native Promise-based plugin support via dynamic import() instead of the custom lazy field. Migrate the documentation from config/index.md to a new config/troubleshooting.md page and update the snap test to use the import().then() pattern.
1 parent 90aef5e commit b3cb2f5

File tree

6 files changed

+40
-70
lines changed

6 files changed

+40
-70
lines changed

docs/.vitepress/config.mts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ export default extendConfig(
163163
{ text: 'Build', link: '/config/build' },
164164
{ text: 'Pack', link: '/config/pack' },
165165
{ text: 'Staged', link: '/config/staged' },
166+
{ text: 'Troubleshooting', link: '/config/troubleshooting' },
166167
],
167168
},
168169
],

docs/config/index.md

Lines changed: 1 addition & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -28,67 +28,4 @@ Vite+ extends the basic Vite configuration with these additions:
2828
- [`test`](/config/test) for Vitest
2929
- [`run`](/config/run) for Vite Task
3030
- [`pack`](/config/pack) for tsdown
31-
- [`staged`](/config/staged) for staged-file checks
32-
33-
## Lazy Loading Plugins
34-
35-
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.
36-
37-
The `lazy` field solves this by letting you defer plugin loading into an async function. Plugins provided through `lazy` are only resolved when actually needed:
38-
39-
```ts
40-
import { defineConfig } from 'vite-plus';
41-
42-
export default defineConfig({
43-
lazy: async () => {
44-
const { default: myHeavyPlugins } = await import('./my-heavy-plugins');
45-
return { plugins: myHeavyPlugins };
46-
},
47-
});
48-
```
49-
50-
### Type Signature
51-
52-
```ts
53-
lazy?: () => Promise<{
54-
plugins?: Plugin[];
55-
}>;
56-
```
57-
58-
### Merging with Existing Plugins
59-
60-
Plugins returned from `lazy` are appended after any plugins already in the `plugins` array. This lets you keep lightweight plugins inline and defer only the expensive ones:
61-
62-
```ts
63-
import { defineConfig } from 'vite-plus';
64-
import lightPlugin from 'vite-plugin-light';
65-
66-
export default defineConfig({
67-
plugins: [lightPlugin()],
68-
lazy: async () => {
69-
const { default: heavyPlugin } = await import('vite-plugin-heavy');
70-
return { plugins: [heavyPlugin()] };
71-
},
72-
});
73-
```
74-
75-
The resulting plugin order is: `[lightPlugin(), heavyPlugin()]`.
76-
77-
### Function Config
78-
79-
`lazy` also works with function-style and async function-style configs:
80-
81-
```ts
82-
import { defineConfig } from 'vite-plus';
83-
84-
export default defineConfig(async () => ({
85-
lazy: async () => {
86-
const { default: heavyPlugin } = await import('vite-plugin-heavy');
87-
return { plugins: [heavyPlugin()] };
88-
},
89-
}));
90-
```
91-
92-
::: info
93-
The `lazy` field is a temporary Vite+ extension. We plan to support this in upstream Vite in the future.
94-
:::
31+
- [`staged`](/config/staged) for staged-file checks

docs/config/troubleshooting.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Configuration Troubleshooting
2+
3+
Use this page when your Vite+ configuration is not behaving the way you expect.
4+
5+
## Slow config loading caused by heavy plugins
6+
7+
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.
8+
9+
Vite supports promises in the `plugins` array, so you can use dynamic `import()` to defer heavy plugin loading:
10+
11+
```ts
12+
import { defineConfig } from 'vite-plus';
13+
14+
export default defineConfig({
15+
plugins: [
16+
import('vite-plugin-heavy').then((m) => m.default()),
17+
],
18+
});
19+
```
20+
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()`:
24+
25+
```ts
26+
import { defineConfig } from 'vite-plus';
27+
import lightPlugin from 'vite-plugin-light';
28+
29+
export default defineConfig({
30+
plugins: [
31+
lightPlugin(),
32+
import('vite-plugin-heavy').then((m) => m.default()),
33+
],
34+
});
35+
```
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
> # Test that plugins loaded via lazy field are applied during build
1+
> # Test that lazy-loaded plugins via dynamic import 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 plugins loaded via lazy field are applied during build",
3+
"# Test that lazy-loaded plugins via dynamic import are applied during build",
44
{
55
"command": "vp build",
66
"ignoreOutput": true
Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
import { defineConfig } from 'vite-plus';
22

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

0 commit comments

Comments
 (0)