mui / material-ui

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.
https://mui.com/material-ui/
MIT License
93.35k stars 32.13k forks source link

Let's ship v1! #9673

Closed oliviertassinari closed 6 years ago

oliviertassinari commented 6 years ago

Well, not yet. We need a plan for doing so. The v1 effort started 18 months ago. We have had some interesting discussion in #9388 and #9614. Here are the problems I want to solve all at once:

  1. How can we make the migration from v0.x to v1 as smooth as possible? Right now, people have to do it in a single batch. It's very hard.
  2. How can we scale the number of components we support? The community has been building a lot of components on top of Material-UI, with large quality distribution.
  3. Some of our components are pretty stable while some aren't. Should the few unstable components prevent us from releasing the stable components earlier?

I'm proposing the following plan, any feedback is welcomed. If we follow it. I'm expecting the to see the first v1 stable release of our components in a month or two and to complete it in 6 months or so.

We take advantage of @material-ui npm scope name

Effectively people imports will change:

-import { Button } from 'material-ui';
+import { Button } from '@material-ui/core';

I have opened a poll on Twitter to collect some feedback.

Pros

Cons

Overall, the Babel blog on this topic is very interesting https://babeljs.io/blog/2017/12/27/nearing-the-7.0-release.

We create a lab package

The package can be named @material-ui/lab or @material-ui/denovo as @rosskevin likes it. What's more important is that we can leverage this package.

Pros

Cons

Overall, the Blueprint approach in interesting to have a look at http://blueprintjs.com/docs/#labs.

mono-repository ❤️

No matter what. I think that we should try very hard to keep the project in a single GitHub repository.

cc @mui-org/core-contributors

mbrookes commented 6 years ago

v1 will be complete once we merge v1-beta into the master branch

Wouldn't it be simpler to rename master to v0, and v1-beta to master?

oliviertassinari commented 6 years ago

Wouldn't it be simpler to rename master to v0, and v1-beta to master?

@mbrookes It's definitely simpler. But we will lose some contributors along the way. A tradeoff. I like the idea of trying. We need to keep the history too. I can't think of a smart approach. Your solution sounds good to me.

mbrookes commented 6 years ago

Hmm, no, you're right that's important.

I've no idea how you would go about merging v1 into master, but if it's possible, @nathanmarks will know the answer! In that case, we would simply need to copy master to v0 before merging.

As for the rest of your proposal: 💯

leMaik commented 6 years ago

It's definitely simpler. But we will lose some contributors along the way.

@oliviertassinari Why are we going to loose contributors by renaming branches?

oliviertassinari commented 6 years ago

@leMaik It's like Bitcoin vs Bitcoin Cash fork, you get the past transactions but not the futures. In our case, we lose the contributors that committed on the v0.x version since we forked to start v1.

leMaik commented 6 years ago

@oliviertassinari Ah, you loose the contributors from the contributors tab?

What about forking material-ui to material-ui-legacy and keeping the legacy branch master there. That would mean that all contributors from 0.x would be kept as contributors in material-ui-legacy. (The stars would indeed reset, but are we really here for the stars? :star:)

Regarding the lab project: If we have more than one component in the lab but every component has another "hero" that started/maintains it, we get problems. What if material-ui has a breaking change and multiple lab components need to be updated? You may have to wait for every lab component to be updated. This wouldn't be an issue if every component is developed and released independently.

eyn commented 6 years ago

@oliviertassinari - I like the lab/core idea. There's a pretty strong argument in my view to release v1 asap.

Right now people are starting projects with v0.x which given the quality and stability of v1 they shouldn't be. They are just creating extra work for themselves as they will have to transition at some point. There are lots of us using v1 in production already with no problems and the odd breaking change is less hastle than upgrading from v0 to v1. And the labs/core designation might make this easier. Ie a core breaking change requires a semantic version change with a release train that departs once a month and a labs release train departs once a week. One downside of this might be dependencies between a core change and a labs component requiring that change. Is there a good pattern on how to handle that?

gregnb commented 6 years ago

If I can share my opinion, I really like the 'material-ui/core' setup it just seems very clean to me.

It's funny, I have two other departments that are running the 0.x version while my group is building on the beta. I sat with a lead from one of these departments as he tried to make the upgrade, but then easily gave up after it threw errors on Autocomplete missing. He didn't want to waste the time filling in what used to come with 0.x. I'm like man, just get a package for that! :confounded:

oliviertassinari commented 6 years ago

What if material-ui has a breaking change and multiple lab components need to be updated?

@leMaik I'm glad you are asking. It's where a large chunk of the mono-repository value comes (https://github.com/mui-org/material-ui/pull/9614#issuecomment-354568219). You save a lot of synchronization effort. You can migrate everything in one go. However, as the code base grows, it's taking more time. It's the same tradeoff behind monoliths vs micro-services architecture: inertia (weight) vs synchronization hell.

However, your point is valid, we need to address the following problems:

So, I believe we need a third entity:

  1. core: core stable components that 80% of the people will need: mono-repository (material-ui).
  2. lab: core components we wish will be stable enough one day to move into the core: mono-repository (material-ui). It's allowing us to do experimentations.
  3. complementary components for the long tail: independent repositories (material-ui-X). They will have their own lifecycles. The maintainers can watch the project without being flooded with noise. It's creating ownership. It's what people have been naturally doing so far. The difference now if that we have our own GitHub organization. We can host some of those complementary components under mui-org. We can make them more official, increase exposure. Those components can be published on npm under the @mui-org scope.
sakulstra commented 6 years ago

I <3 this idea! If I get it correctly the flow will then be: 1) I create e.g. a material-ui-slider package which will 2) eventually be accepted as lab component and 3) when stabilized enough moved to core.


Eventually we could also provide a material-ui-x boilerplate for docs/tests/webpack, then it would be easier to transition them to lab at some point.

Serfenia commented 6 years ago

@oliviertassinari I like the idea of the lab vs core package.

Are you shipping it then as a separate package on npm? Making it dependant on @material-ui/core to be installed (So you can use core without lab, to reduce package size; But have to use core if you want lab, so you are not duplicating code in each package due to infrastructural reasons)

oliviertassinari commented 6 years ago

@Serfenia Yes, having a separate package on npm is important. It's allowing two different lifecycles.

fzaninotto commented 6 years ago

I don't like it because:

  1. It makes me change my code again. We've already been that path, but every major breaking change like this is a huge pain for existing v1 users.
  2. It requires more typing. Way more typing. On a typical component:
- import TextField from 'material-ui/TextField';
+ import TextField from '@material-ui/core/TextField';
- import Paper from 'material-ui/Paper';
+ import Paper from '@material-ui/core/Paper';
- import { MenuItem } from 'material-ui/Menu';
+ import { MenuItem } from '@material-ui/core/Menu';
- import { withStyles } from 'material-ui/styles';
+ import { withStyles } from '@material-ui/core/styles';

You can tell me that modern IDE add import packages automatically, or that I can all import from @material-ui/core and use a babel plugin. But both these suggestions require a more sophisticated toolchain and make the entry barrier higher.

Using withStyles was already a step back from v0 in terms of developer usability, this would be another one.

Please be kind with your users, and think your API to make their lives easier, not harder.

kgregory commented 6 years ago

@fzaninotto why do you consider withStyles to be a step back? And what is it a step back from? Having to use inline styles and dedicated className props?

fzaninotto commented 6 years ago

It was a step back in terms of usability. Adding style with JSS is ultra verbose:

import { withStyles } from 'material-ui/styles';

const styles = {
  div: {
    color: 'red',
  }
};

const MyComponent = ({ classes }) => (
    <div className={classes.div}>
      Hello, World!
    </div>
);
export default withStyles(styles)(MyComponent);

compare that with the previous version:

const styles = {
  div: {
    color: 'red',
  }
};

export default () => (
    <div style={styles.div}>
      Hello, World!
    </div>
);

I love CSS-in-JS, and I think it's a step forward because of all the features it offers. Having tried packages like glamorous and emotion, I can safely say that JSS is the worst of all in terms of developer usability and productivity.

sebald commented 6 years ago

@fzaninotto I don't quite follow. Changing the name for existing code is just a find&replace. I did the same thing for the icons yesterday and took my like 5 minutes 🙂 Do you find it to long?

Also, you don't have to use JSS. If you dont't like it use emotion or whatever suits you. Since all (or almost all?) CSS-in-JS basically work the same (=set className) the interop works rather well: https://material-ui.com/guides/interoperability/

dantman commented 6 years ago

It was a step back in terms of usability. Adding style with JSS is ultra verbose:

I love CSS-in-JS, and I think it's a step forward because of all the features it offers. Having tried packages like glamorous and emotion, I can safely say that JSS is that worst of all in terms of developer usability and productivity.

You might make a better argument if you gave comparisons to what things would look like using one of the other CSS-in-JS libraries and gave a comparison of the features. I've skimmed all 3 major libraries other than JSS and they all seem to have some fundamental flaw to them where some advanced feature is missing or once you go beyond basic examples it becomes even more verbose and messy to use them instead of JSS for what Material UI is doing and what I'm using withStyles for.

fzaninotto commented 6 years ago

Changing the name for existing code is just a find&replace. I did the same thing for the icons yesterday and took my like 5 minutes 🙂 Do you find it to long?

I find it ultra painful to have to update my code at least once every week for the past year with no added value because mui breaks BC all the time. I've explained it in https://gist.github.com/fzaninotto/0a59220e0460134de321b415d1418e99

Also, I don't write import ... from 'material-ui' once a day, I write it way more often. Adding the @...core is longer and makes the code less readable (think broken line 30% more often with prettier)

Also, you don't have to use JSS

Oh yes I have to, if I want to keep the bundle size reasonable, because JSS will be bundled with material-ui anyway. Using Glamorous with material-ui would mean using two CSS-in-JS solutions. Besides, how can I use the theme in Glamorous?

It's a grand total of 2 lines longer, one to import and one to add styles.

I write code for a living. Every time I spend 30 seconds to add withStyles, I lose these 30 seconds. It happens dozens of times a day. My productivity with material-ui has decreased with 1.0.

The code gets even shorter if you're willing to use decorators

I've already explained my concerns about making the entry barrier higher.

[If you] already have other things to compose

Of, that happens often, and in that case, adding withStyles is even worse. Compare:

import { connect } from 'react-redux';

const styles = {
  div: {
    color: 'red',
  }
};

const Hello = ({ name }) => (
    <div style={styles.div}>
      Hello, {name}!
    </div>
);

const mapStateToProps = state => ({
    name: state.name, 
});

export default connect(mapStateToProps)(Hello)

to

import { connect } from 'react-redux';
import { withStyles } from 'material-ui/styles';
import compose from 'recompose/compose';

const styles = {
  div: {
    color: 'red',
  }
};

const Hello = ({ classes, name }) => (
    <div className={classes.div}>
      Hello, {name}!
    </div>
);

const mapStateToProps = state => ({
    name: state.name, 
});

export default compose(
    connect(mapStateToProps),
    withStyles(styles)
)(Hello)

And don't get me started on the need for the classnames package.

the majority of additions to each line {classes}, withStyles(styles), and import are directly necessary to provide some sort of styling related functionality that your inline style example doesn't offer at all.

Well, you may have needed it, but I've written large and complex apps that never made use if these functionality (cf admin-on-rest). Design choices must balance regular users and power users, IMO JSS gets in the way of normal users just for the benefit of a few power users.

You might make a better argument...

OK, let's just make it a personal preference then. As for advertising flaws in other libraries, feel free to give examples, too.

eyn commented 6 years ago

@fzaninotto there is nothing much stopping you continuing to use style={} in v1. A significant reason the library moved to a JSS solution rather than using style={} is to solve a whole bunch of performance issues with using style props with large numbers of elements in v0.x.

Personally I find v1 much more powerful, consistent and easier to use than v0.x and the performance is far better. There have been quite a lot of breaking changes but @oliviertassinari has done a great job of noting these in the release notes. I was working on a few other things for a month or two and came back to update my codebase to the latest version of material-ui and found it only took an hour or two of working through all the releases to update the code base.

I'd like to call out @oliviertassinari and @mbrookes and everyone else for doing an awesome job with the project - each of the changes (particularly things like variant being used consistently) make the library much easier to use. Thanks!!

sebald commented 6 years ago

Sorry, if I didn't make any sense regarding the name change. I was talking about upgrading an existing 1.x-beta app to a stable 1.x release.

I don't think there is any argument about migrating from 0.x to 1.x. It will not be super easy since the API changed a lot. I never personally used 0.x., but the majority of users seem very happy with the new API. Also, migrating 11k LOC in 20 hours seems very good to me. I don't think anyone could migrate an AngularJS app to Angular this fast 😅

I guess you already read it, but @oliviertassinari already wrote about (why the previous approach wasn't working anymore](https://github.com/mui-org/material-ui/blob/v1-beta/ROADMAP.md#summarizing-what-are-our-main-problems-with-css). When he started the rewrite for version 1. There wasn't really anything better than JSS. Depending on the properties you're looking for, JSS might be still be the best solution today.

Regarding the composition of HOCs, I really don't like mixing visual components and component that have application logic. The folks from Atlassian have a good approach to solve this: they create a separate file/folder called styled and put all components that are "styled" in there (see their Button component).

One final note, I see that you're very disappointed in the path Material UI has taken. What I do not understand is why you chose this project if it doesn't match your requirements. There are plenty of other very good component libraries for React.

After all this is an OS project and a lot of people have worked hard on it for more than a year. You're an OS contributor yourself, you now the drill 🙂 For what is worth, my company looked at react-admin but did decide against it, because we didn't liked some of the approaches you took (Your approach is not wrong, it's just that our requirements are easier solved with some other libs, e.g. redux-observables instead of sagas).

EDIT: Whoops sorry, wrong button...

fzaninotto commented 6 years ago

migrating 11k LOC in 20 hours seems very good to me

Given that 1.0 offered less features than 0.9 at the time, I strongly disagree. That was pain without gain. I've explained that in my notes.

Let's close the discussion on JSS - the decision was already made and there is no way to undo it. My personal opinion is that it's not the best choice today, even if it was probably the best choice when you made it. But there's no point in discussing it further, and I didn't want to start a flamewar in this thread.

About the path material-ui has taken, I use to test tools before claiming that they fit my needs or not. Upgrading admin-on-rest to material-ui was a great way to test material-ui 1.0, and yes, we've chosen alternatives for our other projects after that. But I'm still stuck with material-ui for admin-on-rest. So I suffer every time you guys give me more work by breaking BC or making me type longer lines. Hence my message here, where I ask you to reconsider the renaming of the core package (and not all the changes you've already made!).

I'm not very disappointed by material-ui in general - you guys deliver great code in the end, and apart JSS, I find it's a beautiful piece of work. The performance is definitely better. But your release process is broken, and that caused me too many headaches.

Keep up the good work, but please remember the pain that your actions can cause.

dantman commented 6 years ago

I find it ultra painful to have to update my code at least once every week for the past year with no added value because mui breaks BC all the time.

Why are you updating every week? It's beta and there will be breaking so lock your dependencies to a specific version. And if a new release doesn't offer any features you want to use, don't bother updating to it yet. Save the update for later when you can jump a few releases and do all the BC updates all at once.

It's a grand total of 2 lines longer, one to import and one to add styles.

I write code for a living. Every time I spend 30 seconds to add withStyles, I lose these 30 seconds. It happens dozens of times a day. My productivity with material-ui has decreased with 1.0.

I write code for a living too. Spending a few second typing out a few more characters is nothing, thinking about what to write and how to write it best takes longer. We're not typists.

For that matter if there is something you write over and over, typing less characters will speed things up considerably for you, and you're the type to care about that. The solution to this is not making upstream libraries sacrifice key features in order to make things slightly more convenient for you. The traditional solution to this, are snippets! Every major editor has them Sublime, Atom, vscode, and others. If importing Material UI is a lot of typing and you do it regularly, then it should take no more keystrokes to get the boilerplate than mui<tab/enter>. Same for withStyles.

OK, let's just make it a personal preference then. As for advertising flaws in other libraries, feel free to give examples, too.

Skimming Glamorous it appears to be based entirely around a model where you define styles and tags together like glamorous.div({styles}). Which immediately freaks me out because of component, and how Material UI is mostly made up components that are not just single elements but have a pile of children. I can't imagine a glamorous based MUI implementation with the same functionality looking any less than a huge verbose, hard to read, and hard to maintain mess.

emotion has no connection to the component at all, as a result all the css classes are things like css-1dybgp4 which will make it difficult to debug dom/styles during development.

glamorous and emotion appear to be designed around a merge the styles at the element/component method of handling overriding/composing user styles with library styles model. While JSS is based around a model of defining user and library styles separately (using css specificity for user overrides) and just passing classes to elements/components. The problem I see with the former in the MUI-like case is MUI doesn't define single elements so it doesn't fit in with those libraries' pattern of extending the component MUI defines. Instead the style composition has to happen inside the MUI component itself, from how I can understand these libraries being used this would result in either having to pass components instead of style objects to modify styles or MUI composing the styles internally but this resulting in hundreds of redundant css classes because each instance ends up needing its own classes and being unable to share them.

emotion and styled appear to be based on the "write a block of css in a JS template string" model. Which is a non-starter. I've seen proponents of this model tout a few "advantages" of this model that quickly fall flat upon scrutiny. One or both of them may also support objects, but it's such an afterthought that it's only mentioned in a single page of the documentation. Every other example uses the css literal syntax.

These are just the issues I can think of from skimming them. I have a feeling that trying to actually use them to implement MUI would bring up more fundamental incompatibilities with how these libraries work and what MUI needs / what functionality we lose if MUI were to use them instead of JSS.

fzaninotto commented 6 years ago

Sorry, I don't understand your comments like

glamorous and emotion appear to be designed around a merge the styles at the element/component method of handling overriding/composing user styles with library styles model.

As for your experience with glamorous and emotion, I suggest you give them a try for real, and you'll see that most of your remarks are preconceptions that don't stand after real use. For instance:

as a result all the css classes are things like css-1dybgp4 which will make it difficult to debug dom/styles during development

You can specify the css label in the style attributes, see https://emotion.sh/docs/labels

emotion and styled appear to be based on the "write a block of css in a JS template string" model

Not necessarily, see https://emotion.sh/docs/object-styles

Again, this is not my intention, and this is not the place, to discuss CSS-in-JS specificities.

Now for the important part:

Why are you updating every week?

Because the beta releases mix bugfixes and new features. I can't have one without the other. That's why I'm saying the release system is broken.

We're not typists.

I don't pretend to tell what you are. I'm sharing my experience. I'm saying that my productivity decreased, and you're replying that I'm doing the wrong job? This doesn't make sense.

The traditional solution to this, are snippets

Again, more tooling. It's like the Java community, who can't code without a full-fledge IDE due to the complexity of the language / library design. That means that you're increasing the learning curve. That means that you're offloading the job of the library (being usable as is) on a third party (a code snippet) or the user directly. That's exactly what I am criticizing in this post.

I'm sorry if I have offended anyone, it was not my intention to do so. I have voiced my opinion because this issue said "feedback welcome"; I didn't expect to get comments where people try to systematically prove that I am wrong :( I don't pretend to be right or wrong, I'm sharing my feedback based on my experience.

It seems that we disagree, let's leave the conversation there as there is no progress.

oliviertassinari commented 6 years ago

the beta releases mix bugfixes and new features. I can't have one without the other. That's why I'm saying the release system is broken.

@fzaninotto We try to trade breaking changes with improvements every time. This way, we incentive people to keep up to date. What you are describing is the output we are expecting. You can't have both. Hopefully, people will keep up to date and the community will move as a single block. We want to reduce partitioning.

Also, I don't write import ... from 'material-ui' once a day, I write it way more often. Adding the @...core is longer and makes the code less readable (think broken line 30% more often with prettier)

I think that readability (80%) should be much more a concern than the time it takes to write code (20%). I agree with you. I have been wondering for a long time if keeping material-ui for the core modules wouldn't be better. I don't have a definitive answer. I do prefer importing material-ui than @material-ui/core (6 more characters). However, I think that flattening the imports will definitely help and reduce the need to come back to the documentation.

Oh yes I have to

"feedback welcome"

Yes, they are :)

oliviertassinari commented 6 years ago

redux-observables instead of sagas

@sebald I'm all 💯 with you on this point. We decided to use redux-observables on our main app. But It doesn't mean we can't use sagas with react-admin.

oliviertassinari commented 6 years ago

The codemod to automatically migrate from the current import path (nested) to the flatten one is ready: #11249.

olee commented 6 years ago

Two questions:

  1. When will material-ui be available as @material-ui/core?
  2. What about #9532?
oliviertassinari commented 6 years ago

@olee I have closed the issue as the @material-ui/core renaming is almost done. We will publish v1.0.0-rc.0 once all the breaking changes are done, shouldn't take more than 4 days.

caub commented 6 years ago

Excuse me if I miss something, but I don't understand the need for /core in the import paths? is it for distinguishing with /icons? I've seen it's been moved to a monorepo style but icons or the eslint-config are less important than core, I don't even use SVG icons, but just font ones for example, so I just need the Icon component (+sometimes IconButton). So imo, '@material-ui/core/Input' -> '@material-ui/Input' would be ideal

ps: for the discussion about styles, JSS is very good, it just still lack typings, but they should be added soon

oliviertassinari commented 6 years ago

@caub #7839

pelotom commented 6 years ago

@caub

ps: for the discussion about styles, JSS is very good, it just still lack typings, but they should be added soon

I’m confused, what about @types/jss?

dmtrKovalenko commented 6 years ago

@oliviertassinari good idea of moving material-ui to npm orgs! 👍

I have an a related proposal - move material-ui-pickers to the org under @material-ui/pickers for example. What do you think about that? It can be useful for some people to find this project and use at as a part of material-ui ecosystem.

oliviertassinari commented 6 years ago

@dmtrKovalenko Can we chat about it on Gitter?

caub commented 6 years ago

ah, I didn't realize import Input from '@material-ui/Input' would be impossible with npm scopes, except making a package for each component, which would be a bit annoying (but maybe..)

I've read #7839, and I trust the team choice for making a good choice there, I still think @material-ui/core/Something is still a bit verbose, above all when it's frequent, like 4-10 imports like that per View file

a webpack alias 'material-ui': '@material-ui/core' could fix that, I'll try

mbrookes commented 6 years ago

@dmtrKovalenko in the meantime, could we ask that you not use the Material-UI logo on your docs site? Thanks.

dmtrKovalenko commented 6 years ago

@mbrookes. Ok, but I will be able to redeploy docs only after 27th of May because I’m on holidays now. I will change the logo asap