How we mocked improving JavaScript

Photo credits

Creating software is an art. Every good programmer knows it. But at the same time, every good programmer forgets that to be good in art you must be a good artist (pretty obvious, right?). And to be a good artist you must obey THE RULES. Let’s dive into the shallow pool of THE RULES of the art of JavaScript!

Actually, our dive would be very, very short and lead to a discovery of only ONE RULE: TDD. I know that you know everything about TDD (tests FTW!), but I’m not talking about that TDD. We’re talking about JavaScript, have you already forgotten? In this weird and deformed world of JS, nothing is normal, not even TDD…

TDD in JS world means Tool Driven Development, which is present everywhere. I can bet my kidney that your super simple “Hello world!” package uses at least one tool. I can also tell you its name: Babel (woohoo, magic!). Wrong guess? So let me try again: webpack (woohoo, more magic!). Yep, we’re still talking about one line of code that displays “Hello world!”.

In the old pre-ES6 era we would simply write:

and we’re done! But come on, it’s already 2017, it’s not professional anymore. Now we must:

  • create a class that will produce ‘Hello world’ (or some pure function — FP FTW!)
  • create a class that will display a string
  • if we’re using TypeScript instead of normal JavaScript, then we must also implement a Renderer interface
  • write an actual application that will instantiate both of the classes and use them together
  • and did I mention tests?

Of course, everything must be written in super crazy ES 2022 syntax that isn’t supported anywhere so we must transpile it. Don’t forget that we’re using these super ES modules that don’t have support anywhere either, so we must use webpack to bundle all files.

“Hello world” JS app from 2008:

  • lines of code: 1 (actually it’s more like ¼)
  • dependencies: 0

“Hello world” JS app from 2017:

  • lines of code: a lot more than needed
  • dependencies: you can’t even name the exact number

So what went so terribly wrong and made us land in such a place? Maybe the legendary fatigue is true? Maybe, but to me, the issue is more trivial. JavaScript for years was treated like a bastard in the family of respected programming languages (I’m looking at you, Java…). Then, suddenly, something changed: people understood that JS actually might be a piece of crap, but at the same time it’s the language of the web — the language that is the key to reaching the largest possible client base. So it became a thing, but it was still crap. Total crap. And what do people do with total crap? They improve it (or at least they try). What did web devs do? They mocked improving JavaScript.

Don’t understand me wrong: ES6+ is really great and I’m astonished every single day when looking at all the new features being added to browsers, Node.js and other JS-based (and dependent) environments. But at the same time, I see a community hyped up by features that aren’t even a part of ES standard (yet or at all). In a typical programming language, if a new feature is added, programmers wait until the stable version is released before using the new and shiny toy in a production environment. The wisest guys wait even longer to learn from the mistakes of early adopters. What do JavaScript programmers do? “Oh, a proposal to add Object.jumpFromTower to the ES standard — let’s try it out in our app that is used by 20 mln people every day!” → grab Babel and transpile it down to ES3. I’m really interested if there was any connection between web developers using Babel’s async/await support instead of Promises literally everywhere and the super quick implementation of this feature in all major browsers. I’m also interested if decorators would have made it into ES standard if there hadn’t been such a nice implementation of them in TypeScript. Tools are no longer just tools. They’re becoming a playground for all JS geeks. We’re experimenting with them, creating new syntaxes. We develop ES standard by playing with our toys. Ouch.

But probably the greatest example of JavaScript Tool Driven Development is the case of modules. That poor ES standard became an abomination, abused by hundreds of different package managers, bundlers and loaders (SystemJS, Rollup, webpack, Browserify, Google Closure Compiler etc.). The standard, meant to be interoperable, became a running joke, nothing more. Every bundler has its own format, every loader has its own way to load modules — and the worst of it all is the fact that native support is at last coming. I’m quite sure that the special place in hell awaits for every single one of us that has done anything to worsen this stinking pit full of damned souls (hint: we’re all doomed).

You know what’s even funnier? The maturity of the tools we’re using. You know what’s the version of the first webpack 2 release? No, it’s not 2.0.0, it’s 2.2.0. At the same time, Babili is at 0.0.10 (I’m afraid to check if they’ve added support for passing options…). Rollup isn’t better, being at 0.41.x version. Stability? Perhaps you should consider Java.

In the good, old days when you were going to write an application, you simply wrote an application. Today you must write it in the newest syntax, use transpiler to make it understandable by JavaScript engines, then pass it through bundlers to create one, nice file (flaky ES modules support…), then through minifier, then through source-map generator, then you can use it with the newest module loader.

We were probably already doomed when someone thought “Hey, I wonder if there is a way to use ES6 syntax to write code for environments that don’t understand it!”. That thought brought us to where we’re today: Tool Driven Development in JS. What we probably should do now is create a tool to manage our tools…

Or maybe what we ought to do is just go back to writing code. Normal code.

PS: And don’t even get me started about JSX!

Show your support

Clapping shows how much you appreciated Tomasz Jakut’s story.