-
Notifications
You must be signed in to change notification settings - Fork 65
chore: rework CSS extraction #277
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
chore: rework CSS extraction #277
Conversation
fc37b33 to
a39eac7
Compare
📊 Bundle size report🤖 This report was generated against e242ccaaa99b08bbb0cfdfdb9fcd2db802c33fc2 |
4e9ed2a to
35cb4c8
Compare
35cb4c8 to
86554e5
Compare
| "root": "e2e/nextjs", | ||
| "sourceRoot": "e2e/nextjs/src", | ||
| "projectType": "library", | ||
| "implicitDependencies": ["@griffel/webpack-loader"], |
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.
As we don't import/require @griffel/webpack-loader anywhere - Nx fails to detect it as a dependency.
| "targets": { | ||
| "test": { | ||
| "executor": "@nrwl/workspace:run-commands", | ||
| "dependsOn": [{ "target": "build", "projects": "dependencies" }], |
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.
Have been in a wrong spot 🤦
| throw new Error('Failed to find and entry points in "compilation.entrypoints"'); | ||
| } | ||
|
|
||
| const mainEntryPoint = entryPoints[0]; |
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 the main entrypoint guaranteed to be the first entrypoint in compilation.entrypoints ?
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.
actually, what if webpack is configured with multiple entrypoints?
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.
It's a good question. In all scenarios that I currently tested attaching to main entrypoint was enough. So, I don't have answer if it's good or bad. Currently works.
packages/webpack-extraction-plugin/src/GriffelCSSExtractionPlugin.ts
Outdated
Show resolved
Hide resolved
packages/webpack-extraction-plugin/src/GriffelCSSExtractionPlugin.ts
Outdated
Show resolved
Hide resolved
packages/webpack-extraction-plugin/src/GriffelCSSExtractionPlugin.ts
Outdated
Show resolved
Hide resolved
…gin.ts Co-authored-by: ling1726 <[email protected]>
…gin.ts Co-authored-by: ling1726 <[email protected]>
…gin.ts Co-authored-by: ling1726 <[email protected]>
This PR refactors Webpack plugin for CSS extraction.
Before
We use the same approach as CompiledCSS: we create a new
cacheGroupinoptimization.splitChunksand force all generated CSS files by us to go there.As a result we will get a single asset (CSS file) that we can process and sort rules. This works, but this approach requires
optimization.splitChunksto be enabled. One of our key partners has this setting disabled in dev environment: all try outs to enable it were not successful.This approach also prevents all attempts to implement chunks splitting support and avoid a single CSS file.
After
TL;DR Does the same, works differently ¯_(ツ)_/¯
The key difference is that we don't use
optimization.splitChunksand moving CSS files to a target chunk.Initial attempt
Inspired by atlassian-labs/compiled#724. All processing was done during
.processAssetsstage and it worked: we got a CSS file per a chunk (if it containedmakeStylescalls) and I was able to extract rules from it to a dedicated chunk.But:
compilation.deleteAsset()) asmini-css-extract-pluginwill register async chunks in JS runtime and these assets will fail to load..runtimeRequirementInTree(undocumented Webpack hook) otherwise chunks that have empty CSS could be registered in JS runtime 💣Implementation in this PR
After multiple attempts to do something with assets I realized that
.processAssetsis too late to transfer CSS between chunks. The problem that at any stage before.runtimeRequirementInTreewe don't have assets - we operate with modules (not really well documented). Simple explanation: an asset is a concatenated set of modules.On
.afterChunks(again undocumented, happens after a chunk graph gets generated and modules were collected):mini-css-extract-pluginto that chunk (if they contain CSS produced by Griffel)On
.processAssetswe are in the same condition actually as currently: all CSS modules produced by Griffel were moved to a dedicated chunk -> this chunk has a single CSS file -> we sort rules in it ✅