Hacker News new | ask | show | jobs
Ask HN: JavaScript framework that I can use “right now”?
13 points by CircleJerk 3950 days ago
After spending a week learning and experimenting "modern" JavaScript I think it's not worth the effort to use React.js and Webpack if I'm not making a full SPA. It's like alpha software with constant changes (I'm mainly talking about the ecosystem and its components). Documentation is also lacking, specially Webpack. Even tutorials from 3~6 months ago are somewhat outdated. Funny thing I learned Flux's basics and now they are already talking about Relay (ffs!)

Right now I have a tradicional (and huge) MVC back-end and an API (I'm not using Node.js). Assets = Gulp to concat+rev+uglify.

What would be the best approach to my pages where a lot of user interaction is needed? Using jQuery and handlebars seems ugly but I think I'll be overcomplicating things if I adopt an entire new stack (React, Babel JSX/ES6, Webpack, modules, hot-reload...) on top of what I already have.

I'm the single developer on this web app, I feel extremely productive on the back-end side but the front-end is driving me NUTS. Since it started making a good amount of money I quit my job a few months ago and it's my main income now.

I'm (literally) having nightmares about a JS bug I won't be able to solve since it's so many moving parts and I'm a back-end dev who doesn't have the time or patience to replace his entire front-end stack every 6 months.

9 comments

I'd use Backbone. It's old (relative to other JS stuff) but stable. It's one thing to learn and has all the pieces (model, views, events, router). Plenty of resources online or in paper form.

If you want, try applying some of the ideas of the "modern" tools to Backbone: make a backbone view that has two models - one for data (aka React props) and one for view state (aka React state). Bind both model "change" events to your view's `render` method. It won't have the performance boost of React virtual DOM diffing - but you get some of the other design benefits.

This is very, very pragmatic advice.
jQuery.

I'm the sole developer on a "rails monolith" (254 tables, 540 models/classes, 4 years old), with enterprise-like architecture (ecommerce, event ticket sales, booking engine, access control, etc) and I'm positive the only way I'm able handle it all is because I stick to basic jquery.

My secrets:

- The rails-ujs adapter

- $(document).on('event', '.element', ..) is fantastic. Never debug events ever again

- selectize select's for "find or create" relationships

- cocoon gem for nested form relationships

- parsley for form validation (hooks into html5 validators)

- bootstrap 3

- datatables.net + following the pattern of ajax-datatables-rails (gem - separate classes for each table)

- a single javascript function that accepts a DOM element (body, a modal, section) and initializes all the elements the app knows of (selectize elements, date/time pickers, etc) inside that container

- above function is hooked into by bootstrap's 'bs.modal.shown, bs.modal.hide, tab's, cocoon's 'cocoon:after-insert', etc.

rake stats says: 33k LOC models, 8k LOC controllers, 23k Javascript (though this must be all plugins. I'd guess 3-6k lines of javascript, max)

Needless to say, I don't believe in the frontend javascript hype.

Thank you for this comment. Several things there that I will look into! If you don't mind, could you elaborate a bit on the following:

> - $(document).on('event', '.element', ..) is fantastic. Never debug events ever again

> - a single javascript function that accepts a DOM element (body, a modal, section) and initializes all the elements the app knows of (selectize elements, date/time pickers, etc) inside that container

$(document).on lets you keep your javascript source files relatively flat because the event handler listens on the document, rather than an individual element. So even if the element is not currently on the page (loaded in via AJAX for example) the $(document).on handler will still pick it up. You never need to bind or unbind event handlers manually. The rails recommended way is to respond to the JS format and do server-rendered javascript.... but I tend to prefer using a simple data-transport-only (JSON) api, then do the client stuff on the client side.

Simple example:

  $(document).on 'ajax:success', '.guest-form', ->
    notify 'success', 'Guest updated.'
    $(@).parents('.modal').modal 'hide'


  $(document).ajaxError (event, jqxhr, settings, thrownError) ->
  handle_ajax_error(event, jqxhr)


  @handle_ajax_error = (error, xhr) ->
  if xhr.status is 422
    error = JSON.parse(xhr.responseText)['errors']
    notify 'error', error
  else if xhr.status is 500
    notify 'error', 'Error communicating with the server. We have been notified.'
  if xhr.status is 401
    notify 'warning', 'Session has expired. Redirecting to login...'
    window.location = '/login'
  if xhr.status is 403
    window.location = '/access-denied'

So if you load in content via AJAX (I do this a lot for table views of data and the user wants to see a single record), rather than go to a separate page, I do an ajax call, put the result into a Twitter bootstrap modal, show the modal, and when the bs.modal.shown event fires, that "single javascript function" with the modal as the parameter is called, and it initializes all the javascript needed for that particular DOM container.

Example:

  $(document).on 'shown.bs.modal', 'a[data-toggle="tab"]', (e) ->

    $modal_body = $( $(e.target).attr('href') )
    general_init $modal_body
The general_init function will initialize all my selectize elements (among other things) as such:

  general_init = ($container) ->
    add_selectize $container.find('input.membership-plan-select'), $.extend(true, {}, Selects.MembershipPlanOptions)
So when writing forms, lets say to create a new "Event Ticket" I simply plop in a text field with a class of "guest-select" and I instantly have an AJAX powered search field to find/create a guest to assign that ticket to.
Thanks a lot for the detailed response! I'm a Rails developer myself, and have recently become increasingly interested in front end development. Have tried to embrace React et al. but am not convinced that it's what I need.
That's amazing! Believe it or not I was mocking a very similar thing (besides rails). And select2. What made me rethink was the heavy dependencie on using datatables and mobile compatibility. Am I worrying too much and datatables.net "just works"?
Thanks! That's a really good point - and it's currently one of the codebases biggest weaknesses. I use DataTables EVERYwhere. They're fantastic - I have tons of places where I need to show thousands of records, so I use server side processing for pagination, filtering, sorting, etc. However, they don't look good on mobile, and the responsive tables plugin is not the greatest. What I actually do (for now) is wrap the table in Twitter Bootstraps .table-responsive class, which basically creates a viewport for the table on mobile. You scroll left/right to see hidden columns. Works pretty well. Long term, I'm not sure what I am going to do as there are no other table plugins with as rich a featureset and I prefer not to write my own.
Having worked on a fairly large SPA using Ember.js 1.*, I can tell you that React.js (with Webpack, React Router and something like Redux) would probably be better than Ember (perhaps even Ember 2.0, which is still not fully mature).

But if you need something even more stable than React, I'm not sure there is a good option out there. I dislike Angular.js for a number of reasons (which I won't go into here). I've heard good things about Mithril, but it's MVC so as the app grows larger, you're likely to end up with the same problems you have with your current implementation.

Ironically, I'm currently considering a move to the exact stack you're considering (React, Babel JSX/ES6, Webpack...) and I find it better than everything else I've evaluated over the past year.

Thoughts?

I liked React ideas it's just that it feels incomplete not to use the entire stack you mentioned. And it's too much for my taste. I'm sure webpack works fine for most people it's just that the possible edge cases with the black box that is the compiled modules files and lack of good documentation makes me lose my sleep. Combined with the alpha state of the rest of the ecosystem is not really an easy choice for a paranoid developer like me. I also faced a lot of small inconveniences because I'm using Vagrant. IIRC there were options like watch-polling that was available as a cli arg but not on the config file. And the usual CORS problems that I had to solve.
Don't kill the messenger but I tend to stick to plain jQuery + ba-hashchange for building SPAs.

I don't think its worth the time to really learn Angular or whatever is the current fad these days - quality of both the software and the documentation of JS frameworks is an afterthought to "getting an MVP ready to ship".

I'm not a ripening chamber for bananas, especially bananas with no papers.

My english is awful, I was trying to say it's not really a SPA that I'm making. I want to keep the routing mainly on my back-end and only do ajax calls to my API where needed. But if it's not another alpha-state component I would love to have the added possibility of using one or two extra routes on the JS side. It's just that checking the most popular repos and reading things like these is awful: "We are currently working hard on some major API changes for version 1.0."

Is like "mini-SPA's" on a few places that deal with too many data sources and would be a pain to make my users change screens.

I really enjoyed doing "one way binding" and some ideas around React though.

> I want to keep the routing mainly on my back-end and only do ajax calls to my API where needed.

I'm not trying to push React (I'm still evaluating it myself), but that sounds like just the job for React components?

Check my other reply. React is great but I think you need to buy the entire stack since one thing leads to the other. "I'm already using JSX so why not add just this one more babel line and get free ES6. It's the last thing I'll add, I swear"
I thought React was designed specifically so you won't have to buy into the entire stack (unlike Ember and friends). I've used React components without ES6, using plain old jQuery and AJAX calls during component mount (and nothing else). I didn't feel any particular temptation to add more things. Okay I'm lying :) . It's tempting, but it's possible to do without.
You weren't using JSX?
- KnockoutJS (to keep HTML generation logic in the HTML)

- jQuery (for small stuff)

- RequireJS (so that you don't have to load all at once)

- MomentJS (Date / Time management done right)

- AmplifyJS (Pub / Sub and localstorage)

I really like KnockoutJS. Easy to learn and it grows with you so that you don't have to complicate your app if not necessary.

I have the same feelings about "modern" JS development.

Knockout.js is worth checking out. It can be picked up in a day or so, and can be integrated into existing sites easily.

I actually started down the road of learning Backbone/Marionette to work on an existing codebase, and I'm liking what I see overall. It offers models that can sync up to your backend easily, and adds much needed structure to handlebar templates and jQuery.

If you feel like using React, it looks like it would be quite easy to use Backbone models in the same way Flux implementations are used (basically a data store w/ events). I might try this down the road as I like React but want to avoid CommonJS/ES6 and whatever the Flux lib du jour is.

> I'm (literally) having nightmares about a JS bug I won't be able to solve > since it's so many moving parts

I am similar, writing the back end was easier ... front end not so much. I hated having JS bugs due to stupid typos and less than 100% code coverage in tests.

Switched to Typescript for the front end and things became much better. Doesn't have to be 'all or nothing' either, I still have some JS glue for interacting with some libraries and more dynamic bits, but generally everything is Typescript and feels much more solid.

FWIW the stack also heavily includes KnockoutJS, DataTables, Backbone's router & a smattering of JQuery plugins for this and that.

For a complete list, look through the source code of the TodoMVC projects (http://todomvc.com/).
this looks really complete, thanks
Use whatever you want. I go with ractive,page.js for routing , delorean for flux,jquery and various small libs here and there so you can change them.