Prismatik / dendritic-admin

Admin UI for Dendritic apps
1 stars 0 forks source link

Use JSX #4

Closed nwinch closed 8 years ago

nwinch commented 8 years ago

I suggest we should stick to using JSX instead of React API for any redbeard react work. Most of our react projects use JSX, is there any reason we shouldn't use it for this?

davidbanham commented 8 years ago

Because it's grooooooooooss.

Afaik, the main reason we're using JSX in other projects is the lack of documentation, code snippets, examples, etc of the raw React API. Part of the purpose of Redbeard is to provide a place to look for those patterns as an enabler for people to use the API.

nwinch commented 8 years ago

Before we get too far into this discussion - perhaps we can allow both? Pass -render jsx or -render api and you can work with what you like? There are plenty of simple tools out there which can convert to and from each of them which we could include.

nwinch commented 8 years ago

I wouldn't say the lack of awareness of the API is the reason we're using JSX. At least, it's not the reason why I don't use it. I have used both API and JSX extensively. I prefer JSX.

Actually the more I think about it, the more an option to include both seems like the right thing to do. We don't want redbeard imposing itself, and by you choosing API and me choosing JSX we're making the decision for the implementer. Let's give them an option so they can decide :)

davidbanham commented 8 years ago

I don't think this admin UI will ever be getting rendered by the CLI. This is a built artifact that you use as a service from our S3 bucket or compile and deploy to your own. Users of the Redbeard ecosystem won't be modifying the code of the admin system as a matter of course. They're free to, naturally, but the scope of those changes will hopefully be limited to hooking it up to their weirdo authentication system or something.

The components that make up the admin tool, on the other hand, will be heavily reused by frontend projects. Once they're stable, those should be split out into their own package(s) on npm, ready to be imported into frontends far and wide.

JSX vs API isn't a big deal at that point, as I understand it. If it was JSX we'd be pre-compiling it before publishing to npm anyway.

The decision we've got is, I think:

  1. Would we rather use the API or JSX when developing it ourselves?
  2. Would consumers of these components be more comfortable with API or JSX when they want to fork the components rather than just consuming them?
nwinch commented 8 years ago

To me, 1. has been answered by the amount of react projects we have using JSX.

But I'm not sure there is a productive way to discuss it TBH? Comes back to gut feel. Like when talking about CSS. Some devs hate it. There is nothing wrong with CSS, but they just don't jive with it. Your opening response "... it's groooooosss" haha I'm sure you could reel of a list of why you like the API better, but we've had this conversation a few times now and I don't see it going any differently than before.

Agreeing to disagree and including both seems like a good win for us internally and future redbeard users. After widespread (hopefully!) use of redbeard we could gather some stats and decide "hey community, no one it seems is using {X} so we've decided to drop support for it in future releases".

I'm not sure how we could definitively answer 2? Honestly, I think you'd have to go with the community at large (maybe there are polls out there for JSX vs API?) and go with JSX to satisfy the majority. We're not saying JSX is better, we're just making it easier for the masses.

davidbanham commented 8 years ago

So let's explore this "Why not both?" scenario a little more.

It is "I write the file in my preferred syntax, then a pre-commit hook transpiles it across to the other format automagically" or have I misunderstood?

nwinch commented 8 years ago

We've probably risen above the admin now I think, so I mean in terms of the end user (which is us in the short term) for the react work we do for redbeard stuff - which this might not be an issue for this admin, given your initial answer above? - if someone wants to spit out a react frontend from redbeard, or any react files in any redbeard modules that will be generated for use, then we give them the option to scaffold with JSX or the API.

In terms of what format the code is that creates the code, it seems like writing in JSX would be easier given that JSX compiles to the native syntax, and we're back to point 1 again.

kaievns commented 8 years ago

to add my 5c here. i find that API is "groooooss" :) yes it is a personal preference, but i think it comes to using the right tool for the job. front end was always split into three parts, code, layout and styles, and the way they approach it with three different languages for all of them makes sense.

we obviously can use javascript for everything, but to which end? i'm not a big fun of XML but it is a really good tool for describing nested structures and every web developer on this planet is familiar with using it to this end. same with css, many hate it, but it's declarative nature prevents you from mixing it with other contexts and separate concerns better.

to sum it up. yes, JSX feels like blasphemy from the pure coding perspective, but it is a very good tool for describing HTML structures in a HTML-ish language. and, as react, arguably, is the view library for rendering HTML i think it is most fitting to use JSX.

when we extract logic into redux, react becomes pretty much a templates rendering engine. and writing HTML templates in a HTML-ish language only makes sense.

also, i will be hard pressed to remember any react based project that was born in the last year or two that uses API instead of JSX.

and finally, if that wasn't a compelling enough. lets count heads of those who will work on this code base in the future and see how many will prefer API over JSX

nwinch commented 8 years ago

We also have a discussion on this topic happening in Flowdock.

nwinch commented 8 years ago

It's also easier to deal with testing in JSX, than it is without it. Take for example:

/header.js

<header className='red lighten-1'>
  <div className='row'>
    <div className='col s12'>
      <div className='container'>
        <Nav
          items={[
            { path: '/collections/sheep', name: 'Sheep' },
            { path: '/collections/wolf', name: 'Wolf' }
          ]}
        />
      </div>
    </div>
  </div>
</header>

This is a simple dumb header component that has a few nested divs for styling and also a Nav component that contains some links. Not much too it.

Testing this with JSX is trivial when using JSX assertions:

it('must render correctly', function() {
  const el = <Header collections={['sheep', 'wolf']} />;
  const rendered = <header className='red lighten-1'>
    <div className='row'>
      <div className='col s12'>
        <div className='container'>
          <Nav
            items={[
              { path: '/collections/sheep', name: 'Sheep' },
              { path: '/collections/wolf', name: 'Wolf' }
            ]}
          />
        </div>
      </div>
    </div>
  </header>;

  shallowComponent(el).must.be.jsx(rendered);
});

The pros here are:

Let's look at an example not testing with JSX, and testing the same output:

it('must render correctly', function() {
  const el = <Header collections={['sheep', 'wolf']} />;
  const component = shallowComponent(el);

  component.props.className.must.eql('red lighten-1');
  component.props.children.props.className.must.eql('row');
  component.props.children.props.children.props.className.must.eql('col s12');

  const container = component.props.children.props.children.props.children;
  container.props.className.must.eql('container');

  const nav = container.props.children;
  isElementOfType(nav, Nav).must.be.true();
  nav.props.items.must.eql([
    { path: '/collections/sheep', name: 'Sheep' },
    { path: '/collections/wolf', name: 'Wolf' }
  ]);
});

There's a lot to see here! The problems are:

nwinch commented 8 years ago

@davidbanham I think we're getting to the point where JSX is the overwhelming choice by the majority of the team (judging by Github and Flowdock discussions), and I'd like to suggest that we can still continue this discussion if it's worthwhile, but, we should move forward with JSX as the default for redbeard and other projects. If there is considerable opinion to move away from JSX in the future, then absolutely we should revisit.

I'd very much like to tidy up this project using JSX asap before it gets any heavier use from the team.

Would you agree with the above as a way forward?

davidbanham commented 8 years ago

That's a good point well made about the ease of testability. I'm still uneasy about the ability to apply to JSX that I was talking about in Flowdock.

There is, however, always the option to drop back to the API when required. Let's go ahead with JSX. I'll lie down.

davidbanham commented 8 years ago

So, we should still move to JSX. However, the new strategy is to build out the UI library, then use it to build the next iteration of the admin UI.

In that world, it probably doesn't make sense to invest time in porting the existing components from API to JSX where they sit. If we decide to take any of these components across to the UI lib (which I hope we do!) we can do the conversion work at that point, once it's certain they're being taken forward.

On that note, I propose closing this issue. We've still got the project/company-wide directive of "use JSX" in place, but we're removing the "Port this code to JSX right now" directive.

Sane?

nwinch commented 8 years ago

I reckon it'll be easier going for me just to change API -> JSX when I come across it. I think at this point it'd slow me down a bit having to continue with API. So I could just convert the stuff I'm dealing with for whatever the upcoming tasks are, that would make me happy :)

So yeah as you say, eventually the admin will be made up of our UI lib components - which will be in JSX - but I think for my sanity in the interim, I just change stuff where it makes sense, but if it's like a huge component or something and it's gonna take a while, I won't bother and we can just keep rolling. Given the modularity of things, it won't be a deal breaker to have some components API, and some JSX I reckon, as we know the eventual outcome is JSX.

Overall I'll use common sense - if it's gonna take time I don't have, I won't worry about it :)

For sure, it can be closed.

davidbanham commented 8 years ago

Cool, I'm happy with that. Leave it up to the implementer whether to quickly refactor or press on.