New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Evaluate frontend framework options #593

Closed
nicksellen opened this Issue Aug 11, 2017 · 24 comments

Comments

Projects
None yet
5 participants
@nicksellen
Copy link
Member

nicksellen commented Aug 11, 2017

There has been various talk about the need to switch from angular 1.x at some point, and various informal conversations about it.

The idea here is to put our thoughts through a more rational evaluation pipeline. I recently went through this kind of process for choosing a PaaS platform, and found it pretty good at making sure we don't just get lured by our short term feelings for a particular technology.

We based our process loosely on how gov.uk went through a similar process. Not sure it exactly maps to this model though.

I started writing everything in here, but I think an etherpad is a better option --> https://pad.disroot.org/p/evaluating-frontend-frameworks

Tasks

Create proof-of-concepts for:

Additionally:

@tiltec

This comment has been minimized.

Copy link
Member

tiltec commented Aug 13, 2017

There's so much choice out there... well, I'm happy about following a rational process. Maybe that even means sticking with Angular.

@nicksellen

This comment has been minimized.

Copy link
Member

nicksellen commented Aug 25, 2017

I did an evaluation of Angular 4, Angular Material2, ngrx

The code is available at https://github.com/yunity/frontend-poc-angular

There were a couple of starter kits I looked at:

But they were so overwhelmingly complex that I decided to start simple using angular cli, and add bits as I needed.

I used https://github.com/ngrx/platform/tree/master/example-app to work out how to use ngrx.

I'm not checking it against our criteria docs right yet, just some immediate feelings:

Good:

  • typescript is awesome, esp with intellij, I guess I have the webstorm equivalent plugins - it's possible to define custom types and from then on the IDE knows all the fields and types, even in the html templates. also get auto imports, and refactoring stuff, that all seemed work very well
  • big improvement on angular1's global module definitions
  • a clearer component-based approach compared to angular1 (directives vs components)
  • ngrx: does all the redux centralized state stuff, and feels very powerful
  • ngrx: once you've set up all the actions and reducers, it makes the component very simple
  • ngrx: fits neatly into angular world, as angular itself uses rxjs for http stuff now

autocompletecrop
An example of some of the fancy typescript/intellij stuff - because I named the #sidenav component, I can refer to it in places that accept js, and it knows the type so can autocomplete the valid methods, nice!)

Bad:

  • typescript is a new language to learn, most like es6 js, but not entirely
  • still don't really get benefit of angular's DI over just importing es6/ts modules directly, it's a second layer where errors can happen, and the IDE does not always know about it if you forget to import an angular module
  • angular is very all consuming, you use angular http library, angular modules, angular everything
  • might be still called angular, but basically feels all new
  • angular world can get very confusing, because of all the DI the app can seem fine, but actually you forgot to register something, and nothing happens, and no errors...
  • ngrx: a lot of boilerplate - this file basically doesn't need to exist other than these functional purists who want all side effects to be seperated
  • rxjs: adds a lot of new concepts (e.g. trying to understand switchMap)
  • material2: not so many docs/examples as material1
  • material2: missing common things (mobile footer nav menu, sticky top bar), feels like it would need quite a bit of fiddling about with
  • I could not simply get hot module reloading working, the ng cli has an --hmr option, but it tells you to go and visit an outdated webpack 1 page docs page :/ - the starter kits above include webpack with hmr, but I ran out of energy to integrated it into my one

Summary:

There is a lot of stuff to like there, and the typescript development experience is a joy to beyond, the complexity of ngrx/rxjs does not put me off personally that much. The complexity of angular itself does put me off a bit more, and I am also concerned about it's impact on other developers who just want to get shit done.

This stack is not my preferred option, but if others were into it, then it would also work for me.

@nicksellen

This comment has been minimized.

Copy link
Member

nicksellen commented Aug 26, 2017

I added the built version of it to yunity.github.io repo so you can view it at https://yunity.github.io/framework-pocs/angular/

This is from running:

ng build --target=production

Then copying the dist folder into the other repo, and setting the base to <base href="/framework-pocs/angular/"> in the index.html doc.

@nicksellen

This comment has been minimized.

Copy link
Member

nicksellen commented Aug 26, 2017

Ping @NerdyProjects and @raph-ael - I would propose using the same framework in fslight (if we continue it) as for fstool, so your input here would be welcome!

@tiltec

This comment has been minimized.

Copy link
Member

tiltec commented Aug 26, 2017

I'm working on a React+Material UI PoC right now.

You mentioned to me that trustroots is also interested in modernizing their frontend framework. Are there already public discussions about it?

@nicksellen

This comment has been minimized.

Copy link
Member

nicksellen commented Aug 26, 2017

I added Vue+Onsen https://github.com/yunity/frontend-poc-vue-onsen online at:

I created it from their vue cli template thing:

vue init OnsenUI/vue-pwa-webpack hello-world

It asks you questions (as per regular vue cli), so I ended up with a nice base app with hot module reloading working out the box, vuex setup, and a nice little standard mobile-style ui to get started with.

I then borrowed a bunch of stuff from the vuex shopping cart example https://github.com/vuejs/vuex/tree/dev/examples/shopping-cart to rejig the stores to make them a bit more modular.

Good:

  • did everything in about 1/4 of the time as it took me with the angular poc (ok, I'm more familiar with vue, but not so familiar with vuex, it really is much simpler, and the examples are much easier to follow and borrow from)
  • veux: great docs, very simple to get running
  • vuex: chrome dev tools makes actions/state changes very clear without having to setup anything in app
  • vue: also has great docs, although I didn't use them here as I already know enough
  • onsen: docs seem quite good (e.g. progress loader)
  • onsen: list of components seems sufficient
  • onsen: android and ios themes for components and auto change if you use from ios or android (unlike quasar afaik)
    onsen: came with nice default template, and it worked out the box with more useful things than I managed to get working for the angular poc

Bad:

  • vuex: relies on strings for many things (mapGetters, mapActions, etc) so could be easier to get that slightly wrong (although could extract them into a types file to import)
  • onsen: as it's not vuejs specific, can be some quirks, e.g. integrating with vue-router, worry there could be more once getting deeper into it
  • onsen: I sometimes got a bit lost in the docs, as the cater to multiple frameworks

Summary:

I very much like vuejs/vuex - simple and pragmatic. I did not go very deep into onsen ui, so still have a few outstanding uncertainties about it how things would work out beyond that.

I prefer this stack to the angular one so far, from what I see it would be usable too.

@NerdyProjects

This comment has been minimized.

Copy link
Member

NerdyProjects commented Aug 26, 2017

Thanks for dragging me in here - but I actually like to stay out of the frontend discussion/decision as I might not really participate.

As a frontend-newb, I really liked what we get with quasar/vue and would like to get your comparison also towards that stack.
From what I grasped from recent fs tool development, I would not chose a too complex approach (e.g. angular) again - but I also don't know about expandability of the other approaches (e.g. is it easy enough without too many quirks to build the fs tool frontend or even some more complexity in the chosen approach?)

I trust your decision and would help pursuing it :-)

@nicksellen

This comment has been minimized.

Copy link
Member

nicksellen commented Aug 29, 2017

@tiltec nothing much public regarding trustroots. A bit on the meanjs roadmap 1.0 topic (meanjs/mean#1666 (comment)) that trustroots tracks closely. I get the impression @simison is not so inclined towards a big rewrite into a new framework due to the amount of work it would be, for not much end user benefit.

@simison

This comment has been minimized.

Copy link

simison commented Aug 29, 2017

I get the impression @simison is not so inclined towards a big rewrite into a new framework

Right now at least. :-) It's a topic of constant re-evaluation and looking for great examples.

Our priority objective right now is to grow and maintain quality, and big rewrite won't help with that.

@tiltec

This comment has been minimized.

Copy link
Member

tiltec commented Aug 29, 2017

I think one of the main reasons for us to consider switching frameworks is the dependency on angular-material, which seems to be going into maintenance mode: https://github.com/angular/material/graphs/contributors

Both angularJS and angular-material are usable right now and will probably continue being usable for the next 2 years and longer.

So another valid decision could be to stick with the current choice and do some refactoring to make the frontend more fun to work with (= make it feel less heavy, more maintainable). These are some of my issues with the current setup:

  • missing hot module replacement makes UI work rather slow
  • state management in angularJS has disappointed me so far
  • components feel big with ~5 files and boilerplate
  • angularJS gets slow when there is much DOM to render (e.g. history page)
  • angular-material issues get closed with a hint to angular-material2 and only dirty workarounds available (e.g. touch action support seems to be lacking)

So additionally to considering other frameworks, we could investigate more into the current stack:

  • Can we activate hot module replacement? -> investigation
  • I would probably like to have centralized state management (mobx? redux?)
  • Can we make components smaller? Probably means offloading stuff into services, which is good anyways for reuse
  • Is there a way to make angularjs faster? I read some bits, but didn't try them out
  • Can we use another UI framework or custom components in addition to angular-material?

Maybe some of those considerations are interesting for trustroots as well (or you solved them already?)

@tiltec

This comment has been minimized.

Copy link
Member

tiltec commented Aug 29, 2017

I created https://github.com/yunity/frontend-react-poc with react, redux and material-ui. I used create-react-app to get a basic setup.

This is my first react app and the experience was really nice. I always wanted to understand why so many people like react and how they use it to build websites. Although the initial site setup was really quick, it took me some time to understand the different concepts:

React

  • Although many tutorials use the Component class, the easiest way to render stuff is a simple function const button = ({text}) => <button>{text}</button> - fantastic!
  • JSX is not HTML! This is mean sometimes, e.g. className instead of class

Redux

  • Split up state changes into actions, reducers and a store. This adds some boilerplate like string constants in actions and reducers.
  • I used redux-thunk to handle async actions. It went quite smoothly, but some more reading was necessary
  • redux-thunk seems to return promises from action dispatch, so they are then-chainable
  • I went for redux, as it is the most widely used state management library in the React ecosystem. Another candidate would be mobx, which is maybe easier to get started with (less concepts to learn)
  • Logging middleware is a nice experience, it shows all state transitions in the console

image

Material-Ui

  • Material-UI is moving towards v1.0, but it's not stable yet. I got an old package at first, and I wondered why the examples in the documentation didn't work.
  • The standard way of applying styles in Material-UI is JSS, a CSS-in-JS solution. This means writing styles as javascript object that look slightly similar to CSS.
  • Material-UI seems to be roughly at the same completion level as angular-material
  • Somehow the drop shadows of my Card made the page scroll sideways. I was annoyed and solved it by a simple overflow-x: hidden ⚔️

screen shot 2017-08-30 at 00 57 25

Setup

  • create-react-app is awesome! Really smooth dev experience.
  • Hot module replacement was not enabled by default, I had to write a line of code
  • Dev proxy setup with create-react-app is easy, just needed to add a line in packages.json
  • For more complicated configuration, eject is necessary, meaning that you can't get updates from create-react-app anymore
  • I also read quite a bit though https://github.com/verekia/js-stack-from-scratch - it explains the redux and HMR setup nicely

Other stuff

I didn't try out forms, routing, error handling, i18n, map and other important stuff. But I'm certain that there are good solutions available in the react ecosystem.

Mildly interesting:
I discovered Storybook, which seems a nice way to write and test custom UI components.

Summary

I found this stack easier to work with compared to our existing angularJS one. The building-block nature of the React ecosystem offers something for every need, although that also means that I had to look out for the standard way. I think ecosystem also protects yourself from vendor lock-in, e.g. there are alternatives to react (preact, inferno) that are almost drop-in replacements.

My only caveat would be Material-UI. I would rely heavily on it, as it's a pain for me to build UI components. It seems hard to switch UI frameworks, so I would try to make extra sure that it will serve our needs.

@tiltec

This comment has been minimized.

Copy link
Member

tiltec commented Aug 30, 2017

Today I tried to enable HMR in our existing stack using https://github.com/vitaliy-bobrov/angular-hot-loader - it didn't work.

After a lot of trial-and-error, I gave up and read through a similar approach that only works when maintaining those conventions:

You must have one file per controller and export the controller or the angular.module with the controller invoked.
You must use named functions or classes for your controller (we use the controller.name property)
You must have a precise filenaming strategy. Currently our loader looks for the folder name of the file, adds Controller, and then finds a reference to the old controller thanks to angular’s $injector. It then updates its methods one by one with the ones from the new controller in your new module.

I'm not sure I should follow this route, I fear that it could lead to unexpected problems during development. Only for making development faster 😕

@tiltec

This comment has been minimized.

Copy link
Member

tiltec commented Aug 30, 2017

Next PoC with Vue.JS, Vuex and Quasar: https://github.com/yunity/frontend-poc-vue-quasar

I used quasar-cli to bootstrap the project: quasar init pwa frontend-poc-vue-quasar. I like a lot of the defaults: HMR works, it has template generators and enforces a semicolon-free ES6 style 🌟

Getting into Vue+Quasar was almost no effort, I had a bit of previous knowledge from working with foodsharing-light though. I was amazed by the number of components and examples in the Quasar docs, although at first the demos were hidden because of my small browser viewport.

Neither Vue nor Quasar bring their own http client, so I either could have used fetch or axios. The latter seems to be more widespread and has a nicer interface (no calls to .json() necessary).

Then it came the time to add vuex for state management. I read through the docs and found the similarities to redux nice, but the subtle differences a bit confusing. It was no problem in the end to get it running, I even go a chance to use the new async/await syntax.
Vuex (like redux) adds a lot of structure to the project, which seems a bit boilerplate-y for an example project of this size. Though I feel that it makes sense for the foodsaving tool, especially since we want to grow it further.

Quasar components feel very good, I like them better than Material-UI. I didn't try both enough to make a fair comparison to angular-material though.

Summary

Very nice and smooth stack, it seems the most beginner-friendly by far and I would like to use it for the foodsaving tool.

I'm a bit afraid of lock-in though, especially with Quasar, which relies mainly on the efforts of a single developer. I think as soon as you choose one UI library, it's quite hard to migrate away from it. We have the same problem with angular-material already.

@nicksellen

This comment has been minimized.

Copy link
Member

nicksellen commented Aug 31, 2017

For me, the main reasons to switch frameworks now are:

  1. it will have to be done at some point, if not now, then when?
  2. if we accept point 1, then any new features added to the existing site will be built twice eventually
  3. as a developer I like a development stack that brings me joy, and more joy is to be had now
  4. would have some benefit to use same stack across other sites I/we work on
  5. it is not actually such a big piece of software yet then I would consider it a big rewrite
  6. I think motivation to really get behind AngularJS 1 as platform is low, so implementation quality of new work on it will suffer
@nicksellen

This comment has been minimized.

Copy link
Member

nicksellen commented Aug 31, 2017

I'm a bit afraid of lock-in though, especially with Quasar

Yes, this is a definite risk. It's for sure a gamble, but it always is. Last gamble with AngularJS + angular-material1 went in the other direction (big company, stable, established framework). Maybe these small one-person frameworks/libraries end up more stable as they are invested in them more personally. Who knows.

@tiltec tiltec added this to the Release 4 milestone Aug 31, 2017

@tiltec

This comment has been minimized.

Copy link
Member

tiltec commented Sep 3, 2017

Thanks @simison

Maybe we should do a table like this, and add criteria that are relevant to us? I think that's the slightly more rational approach (the table entries don't have to be perfect).

image

@nicksellen

This comment has been minimized.

Copy link
Member

nicksellen commented Sep 3, 2017

Maybe we should do a table like this, and add criteria that are relevant to us? I think that's the slightly more rational approach (the table entries don't have to be perfect).

We have the (rather long) lists of criteria, just have not evaluated against it yet.

@tiltec

This comment has been minimized.

Copy link
Member

tiltec commented Sep 11, 2017

I'm going to take entries from this list of criteria and move them into a spreadsheet. Then evaluate our existing frontend and Quasar with them.

@tiltec

This comment has been minimized.

Copy link
Member

tiltec commented Sep 11, 2017

I'm finished with the evaluation of AngularJS+Material and VueJS+Quasar. @nicksellen do you feel like adding angular4 to the sheet, too?
https://docs.google.com/spreadsheets/d/1L0qi4zjtw1O4qkMeijGeSvS9zICC59LU9-2vaGTIFjo/edit#gid=0

I could add React+Redux as well, but I feel there wouldn't be much benefit over the Quasar solution.

@frankgerhardt

This comment has been minimized.

Copy link

frankgerhardt commented Sep 19, 2017

Here comes some feedback from an old guy. This is all wrong, sorry. Even if Vue is easier than the other there is quite some learning curve with it.

  1. the learning curve turns any potential contributor off. You should not use any of these complicated frameworks.
  2. if you choose one framework, you are blocking the path for integrating your UI with another code base, or being integrated in another UI. Keep is light.
  3. be realistic, you just don't have the manpower. Look at Docker and how complicated everything gets quickly. Then don't let the UI be another driver of brain overload.

I asked my team what they want to use and they said, please no framework. Let's just use jQuery and Bootstrap. Everybody get's up to speed quickly and we can understand each other's code without reading documentation for hours.

@frankgerhardt

This comment has been minimized.

Copy link

frankgerhardt commented Sep 19, 2017

One more thing. There is a trap.

"As a good rule of thumb, too clever is dumb."

The cleverness trap is that we nerds often think we just have to choose the super duper framework and it will multiply our brain power and productivity. It does not. The framework quickly becomes a burden and has a cost of carrying it along. It becomes a barrier of entry for people interested in contributing but are appalled by the heaviness of the project. If you add similar duper duper frameworks for your CI infrastructure, build, containers, that burden slows you down extremely. What about testing? Any resources left? Probably not. Travel light, and fast. That is clever.

@nicksellen

This comment has been minimized.

Copy link
Member

nicksellen commented Sep 19, 2017

@frankgerhardt thanks for your input, I actually agree with a lot of your sentiment, somehow the world of this modern hip web development got insanely complicated recently, it's exhausting if you try and keep it with it all. Frontend development is now a serious programming activity (just look at my angular 4 evaluation!).

I like this saying though: There are no solutions. There are only trade-offs.

This thread was to discuss with our current contributors which approach they would prefer (and nobody suggested jQuery). That doesn't mean jQuery is not right for your team though.

I have been involved with a few large-ish jQuery projects (two of them being https://foodsharing.de/ and https://github.com/Freegle/iznik) and so I avoid it now from experience, not ignorance. They have enormous difficulty getting new contributors, although jQuery itself is not so much the problem, but how it's used.

jQuery is dealing with only a very small part of the frontend architecture, so you are left to build the rest yourself (or use a compatible framework). In the projects I have seen, they end up with not very clear seperation of concerns, and poor/no test coverage. I am sure this is not inevitable though, have you got any examples of nice jQuery open source projects?

So, on a more practical note, over the last few days we have been busy building the new frontend, and we've got quite far :)

Storybook setup:

Where you can see the UI components we use: https://karrot-storybook-dev.foodsaving.world/ which is auto deployed from the master branch (via https://circleci.com/gh/yunity/karrot-frontend)

Desktop view:

karrot-progress

Mobile view:

karrot-mobile-small

Anyway, it would be better to chat in a dedicated place for such things if you are interested in the topic more. We try and keep these issues more focused than general discussion.

@nicksellen

This comment has been minimized.

Copy link
Member

nicksellen commented Oct 28, 2017

I think we are done with this now :)

@nicksellen nicksellen closed this Oct 28, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment