Skip to content

docs: add config troubleshooting page with lazy plugin loading guide#1215

Draft
fengmk2 wants to merge 3 commits intomainfrom
how-to-use-lazy-field
Draft

docs: add config troubleshooting page with lazy plugin loading guide#1215
fengmk2 wants to merge 3 commits intomainfrom
how-to-use-lazy-field

Conversation

@fengmk2
Copy link
Copy Markdown
Member

@fengmk2 fengmk2 commented Mar 30, 2026

Summary

  • Add docs/config/troubleshooting.md with guidance on using the lazy field to defer heavy plugin imports
  • Add the troubleshooting page to the config sidebar
  • Add unit tests for async/await lazy loading patterns in defineConfig
  • Add a snap test that verifies lazy-loaded plugins are applied during vp build

Vite does not support functions or async factories in the plugins array (PluginOption only accepts Plugin | Promise<Plugin>), so there is no native way to truly lazy-load plugins. The lazy field in vite-plus fills this gap.

Test plan

  • Unit tests pass: vp test run packages/cli/src/__tests__/index.spec.ts (19 tests)
  • Snap test passes: pnpm -F vite-plus snap-test-local lazy-loading
  • Docs render correctly with troubleshooting page in config sidebar

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 30, 2026

Deploy Preview for viteplus-preview ready!

Name Link
🔨 Latest commit 8936d0c
🔍 Latest deploy log https://app.netlify.com/projects/viteplus-preview/deploys/69cb4002d5c21b0008f7a6b1
😎 Deploy Preview https://deploy-preview-1215--viteplus-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Copy Markdown
Member Author

fengmk2 commented Mar 30, 2026


How to use the Graphite Merge Queue

Add the label auto-merge to this PR to add it to the merge queue.

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@fengmk2 fengmk2 self-assigned this Mar 30, 2026
@fengmk2 fengmk2 marked this pull request as ready for review March 30, 2026 12:32
@fengmk2 fengmk2 force-pushed the how-to-use-lazy-field branch from 5adc3fd to 49d17df Compare March 30, 2026 12:34
Copy link
Copy Markdown
Contributor

@leaysgur leaysgur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no objection to recommending this method as a current workaround. 👌🏻

(However, I cannot judge whether this is the best approach, as I do not know the background behind why this lazy was introduced.)

@cpojer
Copy link
Copy Markdown
Member

cpojer commented Mar 31, 2026

I'm really not a fan of the lazy attribute and I don't think we should recommend it. It would be better to make the plugins field either an array or a function that returns Promise<Array<…>>.

@fengmk2 fengmk2 force-pushed the how-to-use-lazy-field branch from 49d17df to b3cb2f5 Compare March 31, 2026 03:08

export default defineConfig({
plugins: [
import('vite-plugin-heavy').then((m) => m.default()),
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@leaysgur @cpojer @branchseer I referenced @sapphi-red's suggestion and changed to using Vite's standard solution to resolve the slow configuration loading issue caused by plugins. The slow loading problem of other configuration items is temporarily not what this PR is meant to discuss and solve.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this still cause the plugin to be executed eagerly? I think this should be:

Suggested change
import('vite-plugin-heavy').then((m) => m.default()),
() => import('vite-plugin-heavy').then((m) => m.default()),

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right that bare import().then() is evaluated eagerly.

However, wrapping it in () => import(...) does not work because Vite treats functions in the plugins array as plugin objects, not as factories to be called. It fails with:

Cannot assign to read only property 'name' of object '[object Object]'

Same issue with async () => { ... } (fails with [object AsyncFunction]).

Vite's PluginOption type is Plugin | false | null | undefined | PluginOption[] | Promise<PluginOption>, which does not include functions. So there is no native way to truly lazy-load plugins in Vite today. The lazy field in vite-plus was created specifically to fill this gap.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, true...

Copy link
Copy Markdown
Member Author

@fengmk2 fengmk2 Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sapphi-red 😢 let me revert to lazy field for now

@fengmk2 fengmk2 changed the title docs: add lazy loading plugins documentation and tests docs: add config troubleshooting page with lazy loading guide Mar 31, 2026
@fengmk2
Copy link
Copy Markdown
Member Author

fengmk2 commented Mar 31, 2026

I'm really not a fan of the lazy attribute and I don't think we should recommend it. It would be better to make the plugins field either an array or a function that returns Promise<Array<…>>.

This needs to be resolved on the Vite side. I think Vite+ should not change the meaning of fields defined by Vite. @sapphi-red

fengmk2 added 3 commits March 31, 2026 11:30
Document the `lazy` field in config page with usage examples showing
how to defer heavy plugin imports using async/await dynamic imports.
Add unit tests for async/await lazy loading patterns and a snap test
that verifies lazy-loaded plugins are applied during vp build.
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.
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.
@fengmk2 fengmk2 force-pushed the how-to-use-lazy-field branch from b3cb2f5 to 8936d0c Compare March 31, 2026 03:31
@fengmk2 fengmk2 changed the title docs: add config troubleshooting page with lazy loading guide docs: add config troubleshooting page with lazy plugin loading guide Mar 31, 2026
@fengmk2 fengmk2 marked this pull request as draft March 31, 2026 05:18
@cpojer
Copy link
Copy Markdown
Member

cpojer commented Mar 31, 2026

Upstream issue created here: vitejs/vite#22085

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants