-
Notifications
You must be signed in to change notification settings - Fork 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
Assets: Fix the order of the chunk files (2nd try) #96100
Conversation
Jetpack Cloud live (direct link)
Automattic for Agencies live (direct link)
|
I'll come back to this when I have time. |
05fe9bb
to
21b5627
Compare
This PR modifies the release build for the following Calypso Apps: For info about this notification, see here: PCYsg-OT6-p2
To test WordPress.com changes, run |
This PR does not affect the size of JS and CSS bundles shipped to the user's browser. Generated by performance advisor bot at iscalypsofastyet.com. |
Hi @arthur791004 👋 I'd like to merge this patch again. To do that responsibly, I'd like to know some details why exactly it failed the first time, on Nov 6 2024. In this comment you say that production chunks were empty. Do you remember anything beyond that? I tried to find some Slack thread about it, but didn't find anything. I'd like to avoid discovering exactly the same problem again and reverting again, without learning anything new. The second try should be in some sense better, more informed than the first one. |
I checked the response html after the deployment and found that the chunk files were not listed. It didn't break anything, but it caused the preload not to work. |
Thanks, this is already useful info. I understand it as:
Is that right? |
Yes, exactly! |
21b5627
to
f279841
Compare
I can reproduce this on calypso.live. The preloads for the section JS chunks are missing. Locally, in dev mode on |
@@ -82,10 +82,8 @@ Object.assign( AssetsWriter.prototype, { | |||
|
|||
statsToOutput.chunks = stats.chunks.map( ( chunk ) => | |||
Object.assign( {}, chunk, { | |||
chunks: stats.namedChunkGroups[ chunk.id ]?.chunks, |
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.
This line causes the problem with missing chunks in production. The chunk.id
is a chunk ID, but stats.namedChunkGroups
uses chunk names as keys. In development they are both identical (we use chunkIds: 'named'
) but in production the chunk IDs are numbers.
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.
I fixed this by a radical refactoring of the assets.json
file format 🙂 It turns out that everything the app needs to serve the right assets is in the stats.namedChunkGroups
object and in the assets
field of this object's entries. For each chunk group, assets
is a combined array of all assets from all chunks that comprise a chunk group. We don't need to look at chunks
of the chunk group and then find all individual chunks one by one and read their assets
. It's all already prepared by webpack at one place.
In the server code that reads the assets.json
file, I also unified the two functions getFilesForEntrypoint
and getFilesForChunk
. Because entrypoint is just a special type of a chunk group. We only need one function, getFilesForChunkGroup
.
ba58ad8
to
f561b74
Compare
} | ||
|
||
return asset.info.hotModuleReplacement || asset.info.development; | ||
} |
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.
This fixes one of possible causes of the "window.AppBoot
is not a function" error. In development mode, we were writing the *.hot-update.*
assets to the assets.json
file, and the dev server was probably serving them as one of the scripts in the initial HTML page. That's wrong, hot updates are supposed to be sent only to a live page without reload. Once you reload, you'll load the updated asset.
See how html-webpack-plugin
does exactly the same filtering of assets that will be included on the HTML page: https://github.com/jantimon/html-webpack-plugin/blob/7299866767d7256c65e1d11daaed83426b6d74aa/index.js#L558-L564
I discovered this by accident when having the assets.json
file open in the editor and suddenly noticing suspicious entries there:
![Screenshot 2025-01-24 at 15 28 11](https://private-user-images.githubusercontent.com/664258/406499141-a6b22bd4-4669-435b-9316-3b5cdfc69582.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk2NzkzMjgsIm5iZiI6MTczOTY3OTAyOCwicGF0aCI6Ii82NjQyNTgvNDA2NDk5MTQxLWE2YjIyYmQ0LTQ2NjktNDM1Yi05MzE2LTNiNWNkZmM2OTU4Mi5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjE2JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxNlQwNDEwMjhaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1hZTBkYWZjOTRhZDY5ZjQxOGU3MGZmOGIzMWYwNGM4YWMxOTNhZGNkOGE2MmMzMDI5MTQ4MzkyMTlhY2I4ZmMzJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.TG91vyLlOHkUWnxao_5TG4pkNnm-95cs76Xv1lkbTz8)
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.
Nice find 👍
@tyxla @arthur791004 I believe this PR is now fixed and ready. The The asset writer code has been incrementally patched for years, since webpack 1 all the way to webpack 5, and accumulated some noise. Now it's cleaned up again. How to test:
|
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.
Tests as expected 👍
I think we should try it out.
Also left a few minor questions, nothing blocking though.
Let's make sure to test thoroughly once on production.
#!/usr/bin/env node | ||
const path = require( 'path' ); | ||
const stats = require( path.join( __dirname, '..', 'build', 'assets.json' ) ); | ||
const gzipSize = require( 'gzip-size' ); |
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.
Ah, we can actually remove the gzip-size
dependency now 👍
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.
Someone here has a well trained detector of removable code 👍 Pushed a commit that removes gzip-size
from the NPM dependencies.
@@ -1,80 +0,0 @@ | |||
#!/usr/bin/env node |
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.
Is this script completely unused? Was it ever used for anything beyond debugging during major webpack upgrades?
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.
Yes, we discussed this in the try-1 version of this PR: #95748 (comment)
The script has been completely replaced by ICFY.
return false; | ||
} | ||
|
||
return asset.info.hotModuleReplacement || asset.info.development; |
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.
Wasn't able to see a single asset where development
is true
. Is this intended to be for source maps? If we're not sure, should we keep the pre-existing *.map
check?
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.
Yes, development: true
is a flag that source maps have. It's reliable, html-webpack-plugin
also uses it, for the same job as we do here: figure out which compilation assets and how to embed into the app's HTML document.
Here is a webpack source reference where the source maps plugin adds the flag: https://github.com/webpack/webpack/blob/3919c844eca394d73ca930e4fc5506fb86e2b094/lib/SourceMapDevToolPlugin.js#L547-L550
'entry-domains-landing': assetsList.map( ( asset ) => | ||
asset.replace( 'entry-main', 'entry-domains-landing' ) | ||
), | ||
'entry-gutenboarding': assetsList.map( ( asset ) => |
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.
Oh my, this is long gone 😅 let's remove it.
} | ||
|
||
return asset.info.hotModuleReplacement || asset.info.development; | ||
} |
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.
Nice find 👍
5187f8a
to
c0de2a3
Compare
Related to #95748
Proposed Changes
Why are these changes being made?
Testing Instructions
Pre-merge Checklist