-
-
Notifications
You must be signed in to change notification settings - Fork 32.8k
Description
Current Situation
We ship 3 bundles:
mainentry points to a bundle using CommonJS modules supporting legacy browsers[1]moduleentry points to a bundle using ESModules supporting legacy browsers/escontains the source files
Proposal
Ship the following bundles that are coupled to their target environment and not to a generic preset:
- "modules"-bundle: uses ESModules and supports browsers that support ESModules aka "modern" browsers (this will include node 14)
- "nomodules"-bundle: uses ESModules (for tree-shaking) and supports legacy browsers
- "commonjs"-bundle: uses CommonJS and supports node 10 (current LTS version at the time of release)
- "modern"-bundle (TBD): See [RFC] Support only last n browser versions #15496
- "esnext"-bundle (TBD): source files that only uses features part of the latest ES spec i.e. stage-x proposals are transpiled.
As far as I know the current main entry isn't all that meaningful since it mixes module concerns with target environment concerns. We don't need to support ie11 with commonJS. If you target IE11 you have to use a bundler anyway since IE11 supports neither CommonJS nor ESModules.
Why
The "modules and nomodules" pattern is gaining some traction and by mapping this directly to our bundle it's easier for users to decide which bundle to use.
With this change it's no longer required to transpile our files to get a "modules" bundle (an alias is easier than configuring the babel-loader).
Implementation details
Plenty of unanswered questions. I'd like to put the files next to each other leveraging .(js|mjs) extensions (mjs for esmodules and .js for commonjs). It's not as important whether bundlers support this (I guess any old bundler supports this one way or another with manual work) but whether they support this by default. The "modules" build would go into a separate folder.
For v5 we might flip this default ("modules" by default, "nomodules" in /legacy). While I'm not a big fan of it popular bundle size pages are pressuring libraries to use the smallest bundle as the default.
Adding this would make more sense after we switched to next 9 and reintroduced page size tracking. This way we can compare the bundles better.
The "nomodules" and "commonjs" bundles are not as important right now. Though I didn't check how a less transpiled bundle would affect ssr. The "nomodules" bundle is basically our module entry right now. The "modules" bundle can be shipped in a minor release.9
Concerns
What are the drawbacks of publishing that much code to the registry? What services penalize that metric? CodeSandbox is definitely an issue here. We should find out if CSB users download the full package or only the parts needed.
Plan
[ ].nodeextension with webpack 2,3,4[ ].nodeextension with rollup[ ].nodeextension with parcel 1,2- participate in conversation about modern bundle entry point (talk to authors of bundle compare sites how we can communicate different bundles)
- finish [docs] Upgrade to next 9 #18441
- Upgrade babel deps to latest to reduce size diff noise
- Leverage babel 7.8 (simpler build task thanks to Add --out-file-extension option to babel-cli babel/babel#9144)
- Include
/modulesfolder in build transpiled with@babel/preset-modules
What about size tracking? A simple markdown table is less usable with this number of entries. A separate app might make sense. The data is available as json - Are npm release tags a valid alternative to bundle aliases?
No. They point to a specific version and SemVer has no ability to communicate different variants for versions
notes
[1] legacy browsers
ie 11
edge 14
firefox 52
chrome 49
safari 10
node 8
-- https://material-ui.com/getting-started/supported-platforms/#browser
Updates
- remove
.node. Node will use.jsfiles while the "modules" build uses.mjs. "nomodules" will go into/legacy