https://pxhere.com/en/photo/921518

Compounding our concerns

Carlos Vega
Unhandled Exception
5 min readAug 16, 2018

--

Recently, I read a tweet from someone trying to wrap their head around React (yup, there’s still a whole bunch of people using other stuff, and that’s perfectly fine). His first argument was about how weird it felt to go back to putting HTML and JS inside the same file. I’ve been there, and I think most of us were so, naturally, I approached him with our preferred counter argument: we need to change our mindset to think about components as the basic unit of any app. And, by doing so, we should be able justify why it makes complete sense to have everything that’s related to this component as close as possible.

I also threw the classic: JSX is not actually HTML, it’s Just JavaScript™

While the “component as a basic unit” is a perfectly valid argument, I remember I wasn’t convinced at first, it took me some time to embrace it. And he wasn’t convinced either so I found myself trying to come up with other arguments that didn’t require him to use the thing for months in order to acknowledge that there could be some benefit there. What I wanted to demonstrate was that, while CSS/HTML/JS-based separation of concerns was something useful for web pages, we’ve gone way past that and we need something that enables a higher level of abstraction.

It all boils down to the way we build stuff

We still build web pages, that’s a fact. But every day we build more and more applications. These “web apps” do a bunch of cool and complex stuff and, as a consequence of this, good ol’ pages couldn’t keep up. Users wanted snappier and desktop-like experiences. And we (sorta) delivered (we’re trying, OK!?).

A lot of us don’t write plain old JS anymore. We write TypeScript, SASS, LESS, “modern” JavaScript (the one we cannot ship cause not all the browsers support it) and so on. Heck, it is even possible to write a web application in a completely different language now (Elm, ReasonML and ReasonReact, Dart and AngularDart). JS/CSS/HTML have effectively become compile targets.

I mean, you can still write plain JS, throw a script tag inside your index.html and fire that server up. It works. There’s nothing wrong with it. It’s just not a comfortable development experience for big projects. Think about it like this: you can still write asm, it works and it’s amazing. With that being said, would you build a multi-platform desktop music player with it instead of, let’s say, Java?
While we’re not quite there yet, I’m confident that, eventually, JS will become a compile target -alongside with WebAssembly- and we’ll write apps using other languages.

The classic JS/CSS/HTML-based separation of concerns does not apply for these new tools, and I’m not even talking about React vs Vue vs Angular, I’m talking about something deeper: front-end development is converging into a series of common concepts and practices that are implemented in different ways but, conceptually, share a lot.

Some months ago I had the chance to create the initial version of Storybook for Angular (if you haven’t heard about Storybook, it is basically a tool that lets you render your UI components as individual pieces and work on them without having to open your app, or even without an app and server, it’s truly amazing) and found out that, while implemented using a completely different set of tools and principles, the basic concepts held true and I was able to pull it off. There are now versions of Storybook for React, Angular, Vue and more are in the works or in early alpha releases. Before this, I was convinced that the concepts were similar but now I’m completely confident that we’re converging to common ground. This is amazing!

So, if the JS/CSS/HTML-based separation of concerns doesn’t work for all of our use cases, what does?

A (ridiculously) brief (inaccurate and subjective) history of components

Back in the day, I used to do some Visual Basic 6 development (that’s badass, I know, I know), then jumped into C++, C#, Java and so on. All of them had some sort of UI component kit/toolbox that you could use to build applications. All of them allowed you to compose interfaces using these small blocks. Call them widgets, components or something else, I don’t really care. The whole point is that we’ve had this nice way of abstracting stuff for decades.

We’ve always had components in our own platform: inputs, buttons, even the infamous <marquee>. These are all examples of UI pieces that abstract away the complexity of their behavior and expose a declarative interface that we can use to manipulate them. And they worked for web pages. But as soon as we started building web apps, they fell short.

The web platform wasn’t mature enough to support fully fledged applications so we hacked, molded and bended JS to make it work. We made mistakes. We made a mess. We needed to clean our mess up so we started talking about “separating” our concerns. This period is what I like to call the dark ages.

Along the way we figured out we were doing it wrong. We tried to fix it. Frameworks and Libraries came and we embraced them as our saviors. We fought for them (some still do). After the Crusades a lot of wounded developers were returning home to build apps with their preferred frameworks. But in the process of fighting other developers, they learnt from them. They found out not everything about their enemies was bad. There were things that could be used to improve their framework/library of preference.

The Renaissance

That clash of cultures and frameworks brought something good. We started sharing. We started to trade ideas from one framework to another. We even tried to standardize a way to create our own components inside our beloved platform (hang in there, standards are hard!). While imperfect, our frameworks and libraries thrived and our communities succeeded. We started building bridges instead of tearing them down.

We’re getting close to the industrial age, the revolution, but we’re not quite there yet. For the time being I believe that separating our concerns taking a component-based approach is the way to go. It is a form of abstraction that still holds up even with the new tools we have (Reason and Dart, just to mention a couple). Not to mention that most frameworks and libraries out there use some sort of component-based abstraction mechanism and there are ongoing efforts to standardize web components as part of the platform.

So, the next time you look at that hideous single-file component, maybe give it a chance, it might not be as bad as it seems.

Disclaimer: I’m not a native English speaker, so feel free to point out grammatical and/or syntactical errors. Every respectful comment is deeply appreciated.

--

--

Carlos Vega
Unhandled Exception

Software engineer in love with web development. Avid reader and occasional blogger. He will blog about anything that crosses his mind. Costa Rica.