Hi,
Using the bundle analyser I see that Material UI takes up nearly 400kb of space, and it appears to includes the entirety of the project.
My imports are all of this style:
import { Box, Card, CardContent, Typography, Button, Link, FormControlLabel, Checkbox, Container, Dialog } from '@material-ui/core';
The Material UI documentation suggests that nothing else is needed for modern frameworks that support tree shaking:
Tree-shaking of Material-UI works out of the box in modern frameworks. Material-UI exposes its full API on the top-level
material-ui
import. If you’re using ES6 modules and a bundler that supports tree-shaking (webpack
>= 2.x,parcel
with a flag) you can safely use named imports and still get an optimised bundle size automatically
That’s not what I’m seeing with Meteor 1.10, which I’d definitely consider to be modern. So I then decided to use the babel-plugin-transform-imports
plugin to convert my imports to separate lines as suggested here. This is my configuration:
"plugins": [
["transform-imports", {
"@material-ui/core": {
"transform": "@material-ui/core/esm/${member}",
"preventFullImport": true
}
}]
],
This configuration result in compilation errors:
Error [ERR_REQUIRE_ESM] [ERR_REQUIRE_ESM]: Must use import to load ES Module: /<snip>/node_modules/@babel/runtime/helpers/esm/extends.js
W20200527-09:08:07.152(2)? (STDERR) require() of ES modules is not supported.
require() of /<snip>/node_modules/@babel/runtime/helpers/esm/extends.js from /<snip>/node_modules/@material-ui/core/esm/CssBaseline/CssBaseline.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
W20200527-09:08:07.152(2)? (STDERR) Instead rename extends.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/Tim/Development/MyApps/coco-et-lili/node_modules/@babel/runtime/helpers/esm/package.json.
I did however manage to make this work with a slight tweak to the babel config by removing the /esm from the path (as suggested on the Material UI site for 'if your bundler does not support ES modules’:
"transform": "@material-ui/core/${member}",
This compiles, and delving into the compiled source I see that it’s done its job. However, it made absolutely no difference at all to the bundle size - the whole of Material UI is still imported into the initial bundle.
Continuing my research I fell across this site: https://www.ninjapixel.io/meteor-bundle-size.html
Here the author uses a different plugin (babel-plugin-direct-import
) successfully, however when I try I get the same ERR_REQUIRE_ESM
errors that I did above.
Has anyone here had this problem?
Did you solve it?
Why isn’t Meteor successfully tree shaking Material UI by default?
Regards,
Tim