Skip to content
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

Vite Hooks Api #5709

Closed
userquin opened this issue Jul 26, 2022 · 5 comments
Closed

Vite Hooks Api #5709

userquin opened this issue Jul 26, 2022 · 5 comments

Comments

@userquin
Copy link
Contributor

userquin commented Jul 26, 2022

Describe the problem

The SvelteKit's prerender and adapter process can have a race condition with another configured Vite plugins on writeBundle and/or closeBundle hooks.

Some Vite plugins will require to run after prerender and before adapter processes: need access to collect prerendered pages and the result should be copied to the adapter output build folder (for example sitemap generation and pwa service worker).

Vite will run in parallel writeBundle and closeBundle plugins hooks and so we end up with the race condition, let me explain:

  1. kit plugin + XXX plugin with async closeBundle and enforce: 'pre': the XXX plugin will collect the prerendered/pages folder entries and generates a file in the kit output folder
  2. kit plugin + YYY plugin with async writeBundle and enforce: 'post': the YYY plugin will collect the prerendered/pages folder entries and generates a file in the kit output folder

In case 1), the XXX plugin will collect the pages properly, since it will run in the closeBundle hook, but since it will run in parallel, the adapter (that runs in the kit closeBundle) can finish before the XXX plugin finish run its closeBundle hook, and so the result is missing in the adapter output build folder.

In case 2), the YYY plugin will not collect the pages properly, since it will run in the writeBundle hook in parallel, so it can finish before the prerender process finish.

A good example is the vite-plugin-pwa: this plugin will collect all pages in the prerendered/pages to add them to the service worker's precache manifest (to allow work in offline), once collected it needs to build the service worker.
If we configure the vite-plugin-pwa build plugin with previous case 1), then the service worker is not copied to the adapter build output folder. If we configure it with previous case 2), then, the service worker is copied to the adapter build output folder, but the service worker's precache manifest will have not the pages.

Describe the proposed solution

Add build hooks to SvelteKit, it will control the internal process: allow configure Vite plugins via Rollup intercommunication plugin api and look for kit hooks to notify internal build process state.

Alternatives considered

Add a new preCloseBundle hook in Vite: vitejs/vite#9326

Importance

i cannot use SvelteKit without it

Additional Information

No response

@benmccann
Copy link
Member

I think https://github.com/vitejs/vite/discussions/9442 is a better solution to this. I'll close the issue for now assuming it can be solved in Vite

@lukastaegert
Copy link

Is there a technical reason why the kit plugin needs to write its file to disk instead of emitting them as assets in Rollup? If it were doing the latter, everything could happen nicely in the generateBundle hook which does indeed support ordering.

@userquin
Copy link
Contributor Author

Is there a technical reason why the kit plugin needs to write its file to disk instead of emitting them as assets in Rollup? If it were doing the latter, everything could happen nicely in the generateBundle hook which does indeed support ordering.

The problem is that kit will point the Vite output dir to another folder (the client folder), while the prerender process will output to prerendered folder (kit in the writeBundle hook will do a lot of things, client build, SSR build and the prerender process):

imagen

@lukastaegert
Copy link

Ah I see. So in order to solve this, the output dir would need to be kind of one level higher with all outputs using different naming patterns to place files in subfolders. Probably not so easy to pull off with a lot of caveats.

@benmccann
Copy link
Member

Is there a technical reason why the kit plugin needs to write its file to disk instead of emitting them as assets in Rollup?

It's not so clear to me which file you're talking about because there are many files that get produced in different places. This PR was driven by the desire to be able to disable SvelteKit's service worker plugin and use vite-plugin-pwa instead. Neither SvelteKit nor the PWA plugin can emit in the main build, but run their own build that gets kicked off from a hook where they emit instead. The reason for this is that they need to include the prerendered assets. Generating the prerendered assets requires the server to be started which can't happen until the assets are already on disk. So we kick off these subsequent build steps from writeBundle since that's the first place the assets are on disk.

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 a pull request may close this issue.

3 participants