styled-components / comparison

Comparing different ways to style components
MIT License
183 stars 23 forks source link

JSS Readme #31

Closed mxstbr closed 7 years ago

mxstbr commented 7 years ago

Please review @kof, and anybody else that'd like to

kof commented 7 years ago

Ok so the biggest issue here is a mix up of jss and react-jss.

JSS - is the actual rendering library. react-jss - higher level library, react integration, one among others, for example https://github.com/nathanmarks/jss-theme-reactor looks very promising, (theming, no hocs). It will be officially released soon I hope cc @nathanmarks and will become the main react-integration. aphrodisiac - higher level library, also offers easy theming and no hocs

mxstbr commented 7 years ago

Why is there an issue? I'm well aware of the two packages, and I'll happily switch this implementation over to the new JSS-react thingy when it's officially released and the blessed.

"Easy to override" is a kinda because there is no dedicated mechanism to switch styles based on props. (like radium does) It's still inline styles and JavaScript though, so it's alright.

I don't count JSS as small and lightweight because it requires at least 3 packages in my dependencies to be usable. Also requires setup, which all the others don't. That makes it less lightweight.

Pre-build means being able to compile things to CSS at build time, so there is no injection-at-render going on, which will always be the most performant option.

Does that clear up things?

kof commented 7 years ago

Why is there an issue? I'm well aware of the two packages, and I'll happily switch this implementation over to the new JSS-react thingy when it's officially released and the blessed.

Well, the point is we are describing jss here, react-jss is not jss. When saying it requires a HOC this is only true for react-jss. One could perfectly use jss directly without the convenience wrapper.

Maybe it is worth removing react-jss for the sake of simplicity?

const {classes} = jss.createStyleSheet({
  button: {color: 'red'}
}).attach()

const MyButton = () => (
  <button className={classes.button}>My Button</button>
)

"Easy to override" is a kinda because there is no dedicated mechanism to switch styles based on props. (like radium does) It's still inline styles and JavaScript though, so it's alright.

So the question is how to override current sheet over props in the current element at any time, right?

const styles = {
  button: {color: 'red'}
}

class MyButton extends Component {
   constructor() {
      this.sheet = jss.createStyleSheet(styles).attach()
   }
   componentWillReceiveProps(nextProps) {
     if (!shallowEqual(nextProps.styles, this.props.styles) ) {
       this.sheet.addRules(nextProps.styles)
     }
   }
}

I don't count JSS as small and lightweight because it requires at least 3 packages in my dependencies to be usable.

If you take a look at those dependencies, is-browser is basically a 1 liner dependency, warning is a 20 LOC function which is also stripped out in production and also there is the murmurhash which is about 50LOC function, lots of other projects just copy/paste that function.

A better metric is a minified and gzipped size of a library. You can get it real quick by using unpkg.com, for e.g. latest jss is 5.2KB.

I think amount of dependencies is a wrong metric and people might get the wrong impression.

Also requires setup, which all the others don't. That makes it less lightweight.

I am not sure if "lightweightness" includes the amount of setup. JSS having a setup is actually a feature because it makes it more flexible, but will look like a "negative" aspect for someone reading it real quick in your current presentation.

Pre-build means being able to compile things to CSS at build time, so there is no injection-at-render going on, which will always be the most performant option.

Oh you are talking about SSR? I have got this covered as well

mxstbr commented 7 years ago

One could perfectly use jss directly without the convenience wrapper.

You can, but the whole point of this exercise is showing real world usages of different libraries. Almost everybody using react will use react-jss. (even the name makes it seem like you have to use it)

What we're really describing here is "If I were to build a production react app and wanted to style it, which methods do I have?".

Of course you can use just JSS, but react-jss is the blessed solution for react so we'll showcase that for under the JSS banner. Once there is a new/better blessed solution, let's showcase that!

So the question is how to override current sheet over props in the current element at any time, right?

No, just things like <Button primary /> that sets the background color from blue to red or something.

I think amount of dependencies is a wrong metric and people might get the wrong impression.

I'm not talking about the number of packages JSS depends on. This category is a collection of:

  1. "How many more things do I have to add to my apps package.json to get this to work in a production ready way?" (at least 3: jss, react-jss and some preset. This is more than any other method)
  2. Is this method obnoxiously big in terms of download size? (No)

SS having a setup is actually a feature because it makes it more flexible, but will look like a "negative" aspect for someone reading it real quick in your current presentation.

It can be, which is why it's mentioned in the Notes.

Deducting this in the lightweightness might be the wrong category, but I don't think we have a better one at the moment. (doesn't change the three-lines-in-package-json thing though, I still wouldn't count JSS as lightweight)

This whole list is all about tradeoffs, I don't think any lib will ever have a Yes in all categories. (might even be impossible due to the categories) Choosing a lib to style your components is based on your team, your business, your experience, so many different things that there cannot be THE ONE LIBRARY TO RULE THEM ALL. It's all about tradeoffs.

Oh you are talking about SSR? I have got this covered as well

No, not at all. If you read the entire list, SSR is it's own category.

I mean extracting CSS (actual CSS code) at build time. That will always be more performant than injecting, but it might also make dynamically applying styles harder in some cases. (e.g. CSS modules)


All of that being said, (and thanks for discussing this so in-depth) the categorization (or naming) might not be perfect, but we can easily adapt that down the line. See the /spec repo for more information, which I'll update based on this discussion to make things clearer too!

kof commented 7 years ago

No, just things like

Why should this be a problem in jss? Need an example

Deducting this in the lightweightness might be the wrong category, but I don't think we have a better one at the moment. (doesn't change the three-lines-in-package-json thing though, I still wouldn't count JSS as lightweight)

Maybe we should start a poll about lightweighness, because I don't believe this is the general perception of this term. I think it is about the size. The other term you are describing is "Setup complexity"

I mean extracting CSS (actual CSS code) at build time. That will always be more performant than injecting, but it might also make dynamically applying styles harder in some cases. (e.g. CSS modules)

I don't really understand what's the difference between SSR and extracting, extracting is the first step torwards SSR, you can't do SSR without extracting styles to pure CSS code. In any case extracting from jss is easy.

kof commented 7 years ago

I was just thinking about what you said regarding setup complexity for react. React-jss always ment to be an integration for react and a higher level library. I never realized that 3 dependencies + setup line may create a strong mental overhead, because I know how those things work. However probably you have a better feel what an average user might think.

What if "react-jss" has jss and presets in its dependencies. One can still pass a jss instance with a custom setup if needed, but by default it will work out of the box.

cc @nathanmarks what do you think?

mxstbr commented 7 years ago

What if "react-jss" has jss and presets in its dependencies. One can still pass a jss instance with a custom setup if needed, but by default it will work out of the box.

That would be really cool, actually, I'd like that.

I think it is about the size. The other term you are describing is "Setup complexity"

Hmm, yeah, you're right. We need to adjust the categories a bit, I think. Let's leave this as-is, and discuss about that in the spec repo, I'll mention you in an issue there!

In any case extracting from jss is easy.

Do you have an example of that?

kof commented 7 years ago

In any case extracting from jss is easy.

Do you have an example of that?

https://github.com/cssinjs/examples/blob/gh-pages/react-ssr/src/server.js

jss.sheets.toString() gives you all currently rendered sheets as a css string

sheet.toString() gives you a css string from a specific sheet.

kof commented 7 years ago

That would be really cool, actually, I'd like that.

Will release a new version over weekend.

kof commented 7 years ago

Ok jss-react 4 released, see changelog, there are API changes as well.

mxstbr commented 7 years ago

jss.sheets.toString() gives you all currently rendered sheets as a css string

Right, which is useful for SSR, but doesn't pre-build all the things into a CSS string, right? So I'll still need to run JSS and inject stuff at run time?

kof commented 7 years ago

Right, which is useful for SSR, but doesn't pre-build all the things into a CSS string, right? So I'll still need to run JSS and inject stuff at run time?

Ahh, now I understand what you mean by prebuild. You want to extract CSS WITHOUT running components. But why would you want that? This way you don't know what is used on what page, so you would prebuild the entire css, not just critical path.

mxstbr commented 7 years ago

This way you don't know what is used on what page, so you would prebuild the entire css, not just critical path.

shrugs that's how I understood it, might have to ask @JedWatson what he really meant with that category.

kof commented 7 years ago

Preparing a pr with update react-jss.

kof commented 7 years ago

shrugs that's how I understood it, might have to ask @JedWatson what he really meant with that category.

Yeah ... in any case this is possible as well, however you will need to write a script which will find all styles and call createStyleSheet with each of them, then use jss.sheets.toString(). This can be done in pure node. Each styles object will need to be in a separate file otherwise one will need to extract them from components.

mxstbr commented 7 years ago

however you will need to write a script

Yeah so it's not possible 😉

I've updated this to correspond with the react-jss v4 update, see 68451dc

kof commented 7 years ago

Yeah so it's not possible

Lets figure out who needs this and I will make it possible))))

mxstbr commented 7 years ago

I'll merge this for now, please submit followup PRs with updates you want and we can discuss further!