RFC: Sequential support for writeBundle
closeBundle
plugin hooks
#13175
Replies: 0 comments 73 replies
-
Thanks for putting together this RFC @antfu! IMO this is a good idea in general, and it sounds like a better direction than having two separate hooks with the only difference of one being parallel and the other sequential. Looping @lukastaegert, I think we should go in this direction if there is a chance to push this upstream to Rollup at one point in the future to avoid forking the two plugin ecosystems. The API looks good to me. For the execution loop, I think we shouldn't run all parallel hooks firsts, and then all sequential. We should leave the order to be defined normally by plugin position in the array, and each time a sequential execution hook is hit, then it is awaited. So they act as limits on what gets done in parallel
Will do Ordering should be respected as the sync part of each hook could expect that. let parallelHooks = []
for (const hook of hooks) {
const h = normalizeHook(hook)
if (h.excecution === 'sequential')) {
await Promise.all(parallelHooks)
parallelHooks = []
await h.handle(...)
}
else {
parallelHooks.push(h.handle(...))
}
}
await Promise.all(parallelHooks) Normally you should only place sequential executed hooks where need it. For SvelteKit case, these hooks should be at the end, so normally the pipeline will look like |
Beta Was this translation helpful? Give feedback.
-
If the proposal is about implementing it in Vite (any of the approachs), we need to delete or wrap the |
Beta Was this translation helpful? Give feedback.
-
I'm not the rollup team, but I'm not sure how this can be ported to Rollup. |
Beta Was this translation helpful? Give feedback.
-
I think we can go there, I am just wondering what a good use case is to actually include this. My argument here is that I want to prevent feature creep for things where I am not really convinced they actually add value, but I may stand corrected. Question 1: Why can't they do it on the bundle object? Question 2: Assume we have established that you can do the things you want to do only in Now what I am looking for is actual good real world examples that answer the questions. Otherwise, I would rather direct users to use different patterns that go along with the existing APIs and in the process, keep the number of available patterns smaller with better established best-practices. |
Beta Was this translation helpful? Give feedback.
-
I think the generic idea of sequential support is sound, but the motivation doesn't sit right with me. The main push for this feature is to run multiple Vite builds with a single Scope
In which case, I think we should be building meta-frameworks instead since it's clear where Rollup/Vite has drawn the line. They shouldn't be or allow plugins to "upgrade" them as a meta-framework. InteropabilityExtending Rollup/Vite API so that integrations are still plugins doesn't always guarantee interopability. #9326 and vite-pwa/vite-plugin-pwa#327 are an example that Maybe there is a future that all this could just work, but we need an extended contract that plugins can follow, and I don't think it's something Vite should declare, but a meta-framework does first. SummaryTo kinda summarize, I don't think the usecase justifies this feature yet. We're sort-of giving way to a hack that we don't support. Though I'm also from the Svelte team, I'm trying to think from Vite's perspective even if it sounds like we're conflicting ideas. |
Beta Was this translation helpful? Give feedback.
-
Ah, so the general use case is "I want to run some command line tools that I cannot apply to the in-memory bundle, and they need to have an order". Maybe I can get behind that.
That is the thing that bugs me most about enforce: I think it is applied at the wrong level. Plugins are sorted where it is actually hooks that need to be sorted. And while it is not much of a difference for simple one-trick-pony plugins, it is a huge difference for complex plugins like What I like about the current proposal is the introduction of a "hook object form that changes run characteristics of a hook", and that is something I could actually see Rollup introduce. That might be branching off into a different RFC but I think it is still fundamental to this proposal as well: If we introduce a general hook object form, what is the shape? There is some prior art with your So maybe we can move this into a more general direction:
I would be willing to support this if we can align on the details.
It is a little understood fact by plugin authors that a plugin can easily use the
The reason Rollup does not support this is because I am not sure how to do error handling right. Currently, Rollup tells you either the plugin name or the plugin position so that a user can infer which plugin caused issues. For nested plugins, my thought would have gone rather to support a |
Beta Was this translation helpful? Give feedback.
-
If this RFC were implemented, doesn't vite-plugin-pwa still need to communicate with svelte-kit? AFAIK svelte-kit runs If svelte-kit removes plugins that shouldn't run twice, svelte-kit needs to somehow know which plugin needs to be removed. I think it is possible to run once by having a |
Beta Was this translation helpful? Give feedback.
-
In general, I am against the goal of #5936. I think running multiple builds in What I am for is to improve the limitation of the current plugin API, where a plugin can't know what others are doing. Which ends up forcing plugins to use |
Beta Was this translation helpful? Give feedback.
-
I think we need to address the target of this RFC, we're talking about a lot of concepts:
This is my point of view, I don't want it to be misunderstood, I think we've reached the point where Vite can't do everything, application frameworks also have to provide support for certain capabilities (SSG):
There are plugins that will require an extra step to do its work, such plugins will work without any problem if the Vite build is a normal build, for example running the client build for an SPA. Plugins such as pwa, sitemap and the integrity (mentioned by Anthony) will just work. On the other hand, we have app frameworks with SSR and SSG that runs its own cli, that's, it will run multiple builds using Finally, we have app frameworks with SSR and SSG that will be a plugin, for example SvelteKit. The nature of kit plugin will have a race condition in both hooks with the plugins; such race conditions will be there only and only if the corresponding plugins hooks are async: for example, sitemap can be converted to be sync and we can register it via writeBundle and enforce post or closeBundle with enforce pre. For SvelteKit I suggest to add such custom integrations via the kit config file or kit plugin options, just like the adapter entry, and so, from the kit plugin call the corresponding integrations hooks. I guess Rollup should add a new About the |
Beta Was this translation helpful? Give feedback.
-
Also going off on a tangent here, I think Vite should definitely think about how to do SSG in a "good" way, but this would be a larger thing while the proposal at present could be a stop-gap measure until there is a better approach in place (e.g. there could also be Vite adding a virtual "buildOutput" structure that is above Rollup bundles containing all generated files with its own sequential |
Beta Was this translation helpful? Give feedback.
-
I'll try to summarize a bit here:
|
Beta Was this translation helpful? Give feedback.
-
The Rollup RFC/PR to support object form hooks: rollup/rollup#4600 Comments welcome! |
Beta Was this translation helpful? Give feedback.
-
Implementing PRs:
Summary
Introduce capability for plugins to run
writeBundle
and
closeBundle
hooks sequentially. RFC targeting to Vite plugins, with the hope to be backported by Rollup.Basic example
writeBundle
andcloseBundle
can be provided as functions, resulting in parallel execution to keep backward compatibility. With this RFC, it can optionally be an object to provide additional metadata, in this case, allowingexecution
to control the behavior of the hooks.Motivation
With the growth of Vite and its ecosystem, we have developed many more plugin usages which might go beyond Rollup/Vite's initial design scope (targeting Web, SSR, SSG, etc.). Inherit from Rollup, both
writeBundle
and
closeBundle
are executed in parallel. This creates a racing condition where some plugins are not able to read the bundle processed by other plugins.Related Issues:
$ vite build && vite build --ssr
with$ vite build
+ enable plugins to add build step #5936Detailed design
While this pattern may be able to develop into a common convention applying to other hooks in the future. This RFC will focus on supporting
writeBundle
andcloseBundle
hooks.TypeScript Definitation
writeBundle
as an example:Ordering
For simplicity, we might use the plugin level
enforce
option to control the order of execution. The question here is if Rollup team is willing to backport theenforce
concept to Rollup.Execution
Leave the order to be defined normally by plugin position in the array, and each time a sequential execution hook is hit, then it is awaited. So they act as limits on what gets done in parallel
Will do
p1 p2 p3
in parallel, await that, then dosA
, thenp4 p5
in parallel, thensB
Ordering should be respected as the sync part of each hook could expect that.
Drawbacks
Until Rollup backport it, this RFC will make:
Additional Context
In Vite, we do support a similar convention in
transformIndexHtml
which accepts an object as the hook to specify theenfore
. If this RFC gets accepted, we might take the chance to unify the convention fortransformIndexHtml
in another RFC.Alternatives
Introduce new seperate hooks like
writeBundleSequential
andcloseBundleSequential
.Adoption strategy
This RFC should be additive and does not require migrations from plugin authors.
Unresolved questions
enforce
conceptBeta Was this translation helpful? Give feedback.
All reactions