-
-
Notifications
You must be signed in to change notification settings - Fork 6.2k
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
fix(css): css file emit synchronously #12558
Conversation
Run & review this pull request in StackBlitz Codeflow. |
emitTasks.add({ | ||
name: emitName, | ||
emit: async () => { | ||
chunkCSS = await finalizeCss(chunkCSS, true, config) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code will be more neat if we make finalizeCss
synchronous
@sapphi-red cc |
I found const called = false
const plugin = {
renderChunk(code, chunk, opts, meta) {
if (!called) {
called = true
for (const chunkName in meta.chunks) {
// emit css file
}
}
},
buildStart() {
called = false
}
} |
Good catch. But I think if we handle all the chunks via |
Since chunkCSS = resolveAssetUrlsInCss(chunkCSS, cssAssetName)
let emitName = cssToNameMap.get(chunkCSS)
if (!emitName) {
emitName = path.basename(cssFileName)
cssToNameMap.set(chunkCSS, emitName)
}
chunkCSS = await finalizeCss(chunkCSS, true, config)
const referenceId = this.emitFile({
name: emitName,
// ... I feel like this would be simpler and has lesser toll on keeping tasks in memory. We could also hash the |
Yeah, |
I'd probably accept that caveat for now since it's rare, but the longer I stare at this, maybe this PR can work too. I have some ideas to simplify this and might push directly here if you're fine with it. |
I'm fine. Go ahead. |
I've refactored it as a promise-based queue so that each |
There is already a test case for this issue. I thought about using a promise queue before. But I am not sure whether rollup will guarantee the async |
Ah nice!
Judging from this rollup code I hope it does, but if not, I think it should be fixed in Rollup instead.
IIUC the rule applies pre-renderStart, so for post-renderStart we'd let Rollup handle it the way it wants so in the future if it changes again, our CSS emit logic should follow too. |
Ok. Make sense to me. 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably need another review before we merge this.
const emitTasksLength = emitTasks.length | ||
|
||
// wait for this and previous tasks to finish | ||
await thisTask | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe there is a way to avoid the promise chain here, by using a single semaphore promise and a counter. We could review the aproach if we see a perf issue
Description
This pr contains 2 parts:
rollup3.20.0 broke the rule
first assets determines the name
ofgetFileName
, and 3.20.1 fix that, see Only set asset names when finalizing rollup/rollup#4919, this pr will upgrade rollup to 3.20.1rollup3.20.1 will lead Builds are non-deterministic #11911 (which was fixed in chore: upgrade rollup 3.20.0 #12497) to happen again, vite has to handle CSS file(with the same content) emission order by itself. This pr will force CSS files to emit synchronously and make the final asset name deterministic.
Additional context
Maybe lead to some perf lose after this pr.
rollup 3.20.0 -> 3.20.1 changelog
What is the purpose of this pull request?
Before submitting the PR, please make sure you do the following
fixes #123
).