Let's talk about deprecating spacebars

Let’s talk about deprecating spacebars!

Originating from the discussion about adding nested expressions to spacebars here: https://github.com/meteor/meteor/pull/4101

It seems like Spacebars just keeps getting more complex while also adding less separation of concerns.

With that said:

Let’s deprecate spacebars and move towards writing Blaze views directly like React with JSX or a elegant JS API like React's compiled output for example or instruct to use htmljs.

I mean, shouldn’t we eat our own dog food with the whole JavaScript everywhere tenant?


I just see spacebars adding more complexity and providing less separations of concerns and it already seems like javascript is going to be supported down the road in templates. Let’s just skip to the finish line and go javascript only for templates!

I mean, with great power comes great responsibility, and I think it would be easier for people to learn just javascript rather then javascript+spacebars, albeit with some how-to-write-templates guidance from MDG.

In addition, if MDG deprecates spacebars, it can be supported as a package, while any transpiler (like jade) could just macro on top of the JS API allowing for more diversity from templating packages

And I’m not saying the Blaze API isn’t enough, I just think, if we considered removing/deprecating spacebars and making Blaze first class method of writing views/components a second look should be taken on the existing API (although I think all the APIs are great). I think JSX is really important here in terms of elegance, but a fall-back API like htmljs would be nice. Maybe this is a better target for the upcoming iojs/node merger once ES6 lands.

Thoughts?

:smile:

8 Likes

Because not everyone agrees with your development preferences.

I feel strongly against going javascript only and think <flamewar>react is an abomination</flamewar>.

Seriously, I do like looking at an html snippet and instantly recognizing its structure. I also love being able to onboard a html/css savvy designer and let them work on my meteor project simultaneously without worrying about them screwing up my javascript code.

If you want to go with react or something similar in essence, by all means go for it. But please concentrate on bringing in the things you love and not taking out the things you don’t but others may do. After all, it is opt-in and you can always remove spacebars or organize your project in packages and not even add spacebars.

20 Likes

I think there are two competing thoughts here, that are both really valid:

  1. Lots of people, especially designers, can write HTML and CSS but don’t know JavaScript. It would suck to force them to learn the depths of JavaScript scoping, closures, and functions to be able to write HTML. You currently need to know a lot about these concepts to use JSX.
  2. Learning a second language to do logic inside templates, and having to constantly pipe data into and out of templates through helpers, is a huge hassle. Why learn two languages when you could use just one, and why pipe data when you could just access it directly?

I wonder if there is some compromise possible here that will achieve both goals. I think one of JSX’s problems is that it doesn’t try very hard to “feel” like HTML - for example using className instead of class, and having style be an object instead of a string. Would a more HTML-compliant version of JSX solve all of these problems? How much would it look like Spacebars?

14 Likes

One compromise that I’ve been researching into is providing refactor paths between HTML and CSS and pure-javascript based UI layers (ie. React, Famo.us, Blaze Components). I have dozens of examples within the Cookbook, and I’ve been leaning towards migrating them towards a component based system. But it’s a lot of stuff to migrate. And Serkan brings up excellent points about onboarding new developers, and the larger problems of managing teams of developers.

Specifically, I’ve been looking into html2json and jss as missing pieces to the React/Famo.us/Blaze integration problem. The html2json library provides a nice way of parsing existing HTML into a JSON object that could be consumed by React or Blaze. JSS provides similar functionality for converting CSS into JSON.


These could be added to a utility script to do a one-time batch conversion, or added to the build pipeline via Package.registerBuildPlugin. Of course, we’d then need a way for React, Blaze, and/or Blaze Components to subsequently consume those JSON objects. But my hunch is that folks who are comfortable programming with React and Famo.us and similar libraries will know exactly what to do with a JSON representation of HTML and/or CSS.

I’m thinking I’d like to see the possibility of the following file structure in all of my components:

clients/components/fooComponent/foo.js     # javascript
clients/components/fooComponent/foo.jss    # css equivalent
clients/components/fooComponent/foo.json   # html equivalent

If Blaze could support that kind of file structure, people could either just glob all that content into a single file like the React examples, or when that gets too out-of-hand, they could split it up into CSS/HTML/JS equivalents. It would provide a nice middle-ground for refactoring code from one paradigm to another.

3 Likes

I’m with the #1 camp… I happen to really like writing clean HTML and CSS, and its one of the things that got me into Meteor. It makes it really easy for non-Meteor developers to dive into front-end projects as well.

I think it would be great if you can create .JSX files in Blaze as an alternative to .HTML/.CSS/.JS files, and then have Meteor generate the appropriate HTML/CSS/JS for Blaze.

7 Likes

I find myself liking #2 when you have a very ‘componenty’ piece of markup. The React API seems to really shine in this example. Especially so when you have to keep track of state (though the new template vars help… they feel bolted on).

However writing an entire page in JSX seems overly verbose to me… especially if you have 40 form fields with verbose bootstrap divs/classes.

Has anyone tried out Flow Components? Seems to be an interesting experiment of React methodologies with Blaze:

{{> render component="input"
      text="This is great"
      backgroundColor="#736634"
      fontSize=20
}}
1 Like

As I said, transpilers like spacebars could use the component/views/blaze apis exclusively, so templating languages would still be possible.

Have a look at htmljs you still have very close-to-html code but also have the full power of the javascript language without the go between of spacebars, spacebars could still be supported.

Right, it might, but this doesn’t negate support for things like spacebars or transpilers, I’m just saying that views/components in meteor, should all be written though a component/view API first, then let the transpiler decide how to implement views. I think JSX or ES5 APIs are one possible solution, and I think on top of that spacebars is a second level solution.

Also, in addition, you have the full power of JS, I think an API could be just as elegant as spacebars without having the go-between.

Yes, I think this can achieve both goals, with an API (think component/views/htmljs-like) we can solve for one side of the problem, with that layer in place, any view transpiler could just use those APIs. That transpiler could be something like JSX or even something like jade or spacebars.

Exactly how is this a problem currently, given the modular nature of Meteor? You can do this without having to depreciate spacebars, no? Is it too much of a hassle to remove the Blaze package and add React and Jsx packages in, if you want to go that way. I kind of like the current way that one has the choice of using either Blaze or React as the view layer, or Blaze AND React components. Or Mithril. Or whatever has a package. I’m loving that there is currently such choice on the view layer of Meteor.

6 Likes

I’m very happy for those who’ve found bliss in React but please keep its paws off of Blaze. Right now it allows me to work exactly the way I like: for every part of the screen I have 1 template (html) with 1 view model (js) and maybe a css file. The only thing it’s lacking is the ability for templates to preserve their reactive vars on hot code pushes.

As for priorities, I want Meteor to continue solving the big problems. In particular I would like Meteor to solve the problem of clients having to load the entire app every time a change is made to any part.

9 Likes

Yep. I totally agree with you.
In most of our code, HTML is the biggest piece.

I really don’t want to mix HTML with logic which is on JS.

7 Likes

I think this is a good point - whether or not templates are a good idea depends on whether your app is mostly static HTML or mostly complex components. I felt the same way about HAML in Rails - using HAML made a lot of sense with complex logic, but ERB was more reasonable when there was a huge blob of HTML, since it mapped more directly to what would end up in the browser.

Maybe there is some hybrid approach possible?

I remember the good(!) old days when I exclusively did java.

The day we got JSP it became the most overused java tech. It was supposed to bridge html and business logic, but somehow its power was abused and we saw jsp-only apps that were a mess to maintain.

Then came the cool kids with very reacty solutions like wicket and then gwt (from google) stormed in.

In the meantime, java itself brought in a solution they called JSF, something very similar to spacebars in essence and it improved to become what’s known as facelets, something very similar to the direction we are trying to head towards when we talk components in blaze/spacebars.

Oh and what happened to the very cool google kid gwh? Got dumped for angular where you can develop your markup and sprinkle in the logic from your javascript code through standard tools provided by html.

Until after a very fundamental change comes to what browsers render, html is what it is and we need to learn how to use it and not abuse it. It is the current language of web, so why insist on speaking another language and then translating it? Oh and if there are other tech that we can seamlessly and preferably transparently let the “web designer/developer” consume, bring it on. Let’s use that, too if we like. But I’m completely against shoving in every new tech trend just because it is the next savior. Maybe we don’t need saviors. Maybe we have most of what we need and some room for improving upon it.

After all, I sincerely believe the #1 takeaway from a Meteor tutorial is “hey look, you already know html, css and some jquery. You know what? You are already halfway to become a full stack dev!”

5 Likes

@sashko Nailed it! Both styles have their strengths:

Mustache templates are great for large pieces of Text/HTML simple substitutions, or template inclusions.

React Components are great for creating complex, dynamic components.


However, I’d say that I now sit on the React side of the fence. I’ve found the separation of templates and helpers is more about “Separation of Technologies” , e.g. HTML and JS rather than “Separation of Concerns”.

I’ve been carefully watching the https://github.com/meteor/meteor/tree/experimental-spacebars-over-react branch

The ability to seamlessly include React components, just like other HTML elements in Spacebars, would bring the best of both worlds. Additionally, as @awatson1978 points out, it has the added benefit of a sensible refactor path. You could simply refactor complex components from Spacebars to React, without affecting the remainder of your application.

The main downside would be, that “There should be one-- and preferably only one --obvious way to do it.”. Sure, Meteor isn’t Python - and may not subscribe to their ideologies - but having too many choices can slow people from getting started, and that’s not great for the framework.

So, if we had votes, I would choose React as the primary templating engine, for the following reasons:

  1. Spacebars is much too limited (compared to templating languages like Jinja2)
  2. The separation of Helpers and Templates is a farce, and unnecessarily complicates some components. Most changes to a template require new/changed helpers anyway.
  3. Designers are going to learn JSX anyway, or be risk being ineffective. (In response to “but designers can write spacebars”)
  4. IMHO, React is better
  5. React has a better eco-system, and mind share. (For the moment).
  6. If the experimental Spacebars/React branch survives - there’s a reasonable chance of refactoring/migrating existing code to React.
3 Likes

Beyond separation of concerns, and separation of technologies, let’s just say separation of work.

Designers (dedicated ones, not coders-who-design-too) in practice should not be writing production code. They don’t have the discipline or the bandwidth to think like a production coder. They have very valuable and technical thoughts too, but designing, factoring and maintaining production code is not among them and should not be.

This is also not to say that designers should be PSD-only and not write HTML. They can go ahead and write HTML and arguably they should write HTML as that will bake-in the constraints of the medium. The idea that designer-written HTML can just be ornamented with application hooks that can survive constant roundtripping in Dreamweaver works for Adobe’s Dreamweaver demo and promptly drops dead in any significant production scenario. Both the designers and the coders are then tied to a ball & chain of shared code neither has full ownership of and neither particularly admires.

This code sharing saves less than 5% of person hours on a typical project (hey the team only typed each div tag once!) at the cost of at least an order of magnitude more than that over the project lifetime for an equal quality result. It’s penny wise & pound foolish.

If we instead accept that any design roundtrips will have to be examined, harmonized, tested, and often refactored if not entirely rewritten by the production coders anyway, requiring refamiliarization in turn going back to the designers for the next iteration, we start to see the solution. Let the designers have their own independent work product, whether it’s HTML or PSD or Balsamiq, which they can write & maintain anyway they want and compare & update to the production implementation. The coders then study the design proposals and come up with their own implementations using the tools and architecture that makes the most sense for them. And the twain never meets, nor should it.

That allows any design to be shattered into components without having to educate designers in the latest architecture du jour. The designers are free to express themselves in their preferred medium as well. The jack-of-all-trades working both sides can use any approach they like.

I’d make Meteor agnostic to this if possible. The idea of pulling Blaze out of core and allowing React as a substitute is great. Also mix-and-match. I don’t like to have too many options either but when you have partisan inertia it’s worth it. React will have a component ecosystem Blaze won’t touch, and React Native is not something Meteor can match with an equivalent without sacrificing work on its own must-haves.

Off topic but: use a reactive-dict, they migrate across hot code pushes. Set up a global reactive-dict or something on onCreated/onRendered. Cheers

I know the feeling, generally, I’d convert everything to HAML but sometimes, ERB was just more sensible. Kinda like SASS vs SCSS. Sometimes I just want to paste something. :wink:

I think so, I mean, look at the generated template output:

Template.__checkName("about");
Template["about"] = new Template("Template.about", (function() {
  var view = this;
  return HTML.DIV(
    {
      vertical: "",
      layout: "",
      center: ""
    }, 
    HTML.DIV(
      {
        "class": "content"
      }, 
      HTML.Raw("<h2>Title</h2>"),
      Spacebars.include(view.lookupTemplate("content")),
      HTML.getTag("some-other-element")({
          "class": [ "other" ],
          someproperty: function() {
            return Spacebars.mustache(view.lookup("currentEmail"));
          }
        }
      )
    )
  );
}));

Yes, it’s verbose, no this doesn’t have to be the layer we interface with.

It does however feels a bit weird that this API is interfacing with Spacebars, I mean, shouldn’t that be under Blaze? This already looks pretty close to something pure-javascript based. I think we could benefit from a layer that makes this great for components, it just needs some syntactic sugar and polish.

This is just my two cents, I like most other people would still want both, but I’m writing less and less static html these days, I write applications, not blogs :wink: I don’t want to write static apps, or slightly dynamic html apps, otherwise I’d grab Rails (Which isn’t to say meteor isn’t a good choice for static content or the odd blob of content)

:smiley:

My 2 cents: Meteor’s #1 priority is simplicity/ease of use. React/AngularJS/Ember are almost the exact opposite of that as they are designed to be used by experienced Javascript developers that identify with problems like “scalability”, “performance”, “component-oriented architecture”, “complexity”, etc. It’s easy to mistake designing a system like templating for a large audience of users with designing it for your own needs.

Further, is it a good idea to phrase the situation as Spacebars/Blaze vs React? React is a flavor of the month framework; sure, there are good ideas in it, but there were good ideas in AngularJS too. Would this thread have been “deprecate Blaze in favour of AngularJS” 2 years ago? What about 2 years from now?

What’s the higher level discussion here?

For instance, how can Meteor take advantage of a longer term trend like Web Components (not Polymer/Material Design, but the actual W3C spec)?

12 Likes

Precisely my point. Right now you have to have some kind of mechanism to identify each template after a hot code push. That and the need for global variables to store data which is very much local. We should be able to do something like templateInstance.var(‘name’).get/set instead.

I’d say there isn’t strictly a single #1 priority but rather important tenants to try to stay close too. And I’ve already mentioned transpilers should exist (like spacebars/jade/etc). I have concerns about spacebars becoming more complex and looking less and less like regular html, specifically this topic spawn from nested expressions being added to spacebars, in that discussion, it came to attention that eventually javascript in templates would be possible (which could good thing, however I think that’s double edge, we pull closer to spaghetti code and nested expressions while really useful pulls again towards that). I think it shows that again, as much as we try things are coming full circle and we’re rounding ourselves back to a fully featured language so why not just shift priority and place javascript above spacebars as the target and have transpiler target those APIs.

I really don’t want phrase the situation as X vs Y, I want us to think about the best way to build user interfaces, I think react/JSX is an example, it has given us ideas, but it may not be the cure.

I think, there’s a couple smaller discussions happening from this topic. But, I think the most important notion is: how can we build the best user interfaces? The topic then proliferates into a number of questions/wants/needs like: designers want simple html, developers want javascript, are components the best approach, should we target web components (are they necessary).