Instead of recommending to use named exports, how about recommending importing all modules?
Before:
import { Button, Table, ... } from "@material-ui/core"
After:
import * as Mui from "@material-ui/core"
Pros:
material-ui
doesn't import named exports from react
, why should imports from material-ui
be different?Mui
Mui
Mui.Button
is a pure Mui
button, whereas Button
is part of your project's modifications that fell outside of what you can do with theme's customizationsmaterial-ui
and useful for beginners, as developers are reminded on what they use as they use values from Mui.
Cons:
Mui.
For your convenience I created a simple example that showcases:
material-ui
works when importing allBasically I put @oliviertassinari example function into a new CRA project. Please follow commits as it's easier to understand what has been changed in a pure CRA project.
And here is a screenshot of the webpack-bundle-analyzer. We can clearly see that only the button and what's necessary for it is imported (to see it for yourself, run yarn build
):
material-ui doesn't import named exports from React, why should imports from material-ui be different?
We ship a bundle with actual ES modules but React doesn't. Import style is personal preference. We won't enforce a particular style.
The reason why it will improve consistency is because a similar decision was made here.
@o-alexandrov Note that we might revisit how we import React if Facebook adds support for tree-shaking in the future. Until they do, a single import is simple and avoids back and forth with the top of the file, ask Python's developers.
@oliviertassinari you contradict yourself:
Until they do, a single import is simpler, ask Python's developers.
then why don't you:
import * as Mui from "@material-ui/core"
instead of recommending named imports (based on your own statement it is more complicated), if both lead to the exact same bundle size?
@eps1lon you also contradict your own statement in this comment and also Olivier comment
@o-alexandrov Your proposal would break tree-shaking (as far as I know). Assuming no tree-shaking, I don't think that it's an option for the demos of the documentation. Developers with less experience will blame Material-UI for being bloated once they look at the bundle size in production. It also doesn't account for all the new components coming (doesn't scale).
@oliviertassinari what makes you think it will break tree-shaking?
I am using import * as
in every webpack environment and nowhere tree-shaking was ever broken.
But you don't need to trust me, please review the following as tree-shaking for import * as
has been supported by webpack for a long time:
also updated Motivation part of the Issue description, so benefits are clearly highlighted
I am using import * as in every webpack environment and nowhere tree-shaking was ever broken.
@o-alexandrov Interesting, I didn't know! I wonder about the esthetic.
It also doesn't account for all the new components coming (doesn't scale).
I don't know about what's coming, but if you are talking about modules with side effects:
named imports
as all exported modules are parsed@o-alexandrov Interesting. I wonder about the esthetic.
Other arguments to consider and will copy them to Motivation above:
Mui
Mui
, as IDEs sometimes fail to auto import from libraries already present in the module@eps1lon you also contradict your own statement in this comment and also Olivier comment
React's exports and Material-UI's exports are not the same. React does not ship ES modules. Material-UI does. Opinions I hold about importing React do not automatically apply to Material-UI.
@eps1lon please be informed the links to your comments above lead to your phrase:
So we do want to influence them. If we want to follow then we do what we're told. If we want to lead we're doing what we think they want.
What you're describing is incoherent.
That鈥檚 what I referred to in the links above and that鈥檚 what I described as contradiction when here you say:
We won't enforce a particular style.
But the statement itself is incorrect as by making choices you enforce a particular style anyway.
This issue asks to change your opinion on what you enforce.
@eps1lon regarding:
React's exports and Material-UI's exports are not the same. React does not ship ES modules.
I don鈥檛 know why you bring it up, especially twice.
What does it change in terms of the importing style?
@o-alexandrov So if we take this demo: https://material-ui.com/components/buttons/#contained-buttons, it would become:
import React from 'react';
import * as mui from '@material-ui/core';
const useStyles = mui.makeStyles((theme) => ({
root: {
'& > *': {
margin: theme.spacing(1),
},
},
}));
export default function ContainedButtons() {
const classes = useStyles();
return (
<div className={classes.root}>
<mui.Button variant="contained">Default</mui.Button>
<mui.Button variant="contained" color="primary">
Primary
</mui.Button>
<mui.Button variant="contained" color="secondary">
Secondary
</mui.Button>
<mui.Button variant="contained" disabled>
Disabled
</mui.Button>
<mui.Button variant="contained" color="primary" href="#contained-buttons">
Link
</mui.Button>
</div>
);
}
and we would still have tree-shaking working. Maybe it's worth asking on Twitter how the community feels about using the approach by default for the demos. 馃
@oliviertassinari I apologize, I don't know whether you were asking or making a statement, so for your convenience I created a simple example that showcases:
material-ui
works when importing allBasically I put your example above into a new CRA project. Please follow commits as it's easier to understand what has been changed in a pure CRA project.
And here is a screenshot of the webpack-bundle-analyzer. We can clearly see that only the button and what's necessary for it is imported (meaning tree-shaking is working):
Could you kindly open the issue, as it seems you support further discussion on this topic?
I also added another note to the Pros
in the Description of the issue above:
it's better marketing for
material-ui
and useful for beginners, as developers are reminded on what they use as they use values fromMui.
Let's see if it resonates with developers: https://twitter.com/olivtassinari/status/1304385408525045760, we can re-close the issue if not.
Another pros I didn't thought about before. The mui.* pattern makes it easier to identify what's used in the codebase. Say you have multiple custom buttons, searching for mui.Button
will give you more accurate results.
We never destruture the theme object in the codebase for this very reason. We always do theme.palette.divider
, not const { divider } = theme.palette
.
It's important for refactoring.
It doesn't seem to resonate a lot with the community. It seems that they are mostly used to the following approach:
import {聽Button, makeStyles } from '@material-ui/core';
On Vue land, they seem to basically make all the components global:
import * as mui from '@material-ui/core';
Object.keys(mui).forEach(key => {
window[key] = mui[key];
});
https://vuetifyjs.com/en/getting-started/quick-start/#vue-cli-install
And then, some have a smart loader to have tree-shaking.
I am not surprised pretty much none of the responders there read this GitHub issue 馃槄
I read all of the responses there:
Personally, I don't think v5 should be held by old inconvenient patterns and fear. You can set a new trend with mui.*
I believe whatever you choose will be the most common pattern, so it's your call, as simple as that.
Stats based on your tweet:
@sandeep0695
, @TandonKrishna12
, @AndaristRake
, @erikras
, @thegoldenshun
(mentioned only with icons, so I'd say more positive than negative), @arunkumar413
, @MelamedYoav
@ee0pdt
(likes it, but held with a legacy project), @garbage_value
, @alchemist_ubi
, @Lani78
, @ModularCoder
, @kandelborg
@pflevy
,@MelloGarrett
, @dfmartin
Then, here is @eps1lon (I really hope you'd read the description completely), who seems to not like it due to:
Explicit imports make it easier to spot what is used
And seems like @oliviertassinari also likes the pattern.
@o-alexandrov I will personally snooze the matter for the next 2+ months. I don't think that we need to rush any changes. We have until v5 land to make bold changes (if we see them appropriate). Regarding the esthetic, Ant Design and react-bootstrap: does that too, e.g.
I totally understand decisions like this in a popular project are hard to make.
I am already happy you were open to reconsider.
From here, please do as you see best for the community, you know what's best much better than I do.
Most helpful comment
Another pros I didn't thought about before. The mui.* pattern makes it easier to identify what's used in the codebase. Say you have multiple custom buttons, searching for
mui.Button
will give you more accurate results.We never destruture the theme object in the codebase for this very reason. We always do
theme.palette.divider
, notconst { divider } = theme.palette
.It's important for refactoring.