You ever find yourself feeling unreasonably protective of JavaScript? I do. For a long time, JS lacked a lot of sophistication. It was vulnerable to being trampled over by bigger, more powerful technologies like Java applets or Flash. There was nothing to really commend it to anyone who didn't, for whatever crazy reason, already love it. Eventually it was able to do things for itself, but there were many years where it was pretty much defenseless and it sounds dramatic only in hindsight to say it wasn't clear whether it was going to survive to maturity.
Maybe I just like underdogs, but I've rooted for JavaScript from the beginning. Probably unsurprising then that I was really pissed when I first encountered CoffeeScript. JavaScript had finally developed the power and utility people had mocked it for lacking, and now they were going to complain about its appearance? Bullshit. But lately I find that I don't care as much about CoffeeScript et al.
JavaScript isn't a little baby language anymore. It's full-grown and it's going places I never expected and it's got fat arrows and other things I probably don't even want to know about. Dropping the analogy, seriously, do you ever take a step back and consider how much it's changed? JS used to be a very personal language. You didn't share it with a compiler or a test suite and, if you were like me, you were the only person on your team who understood it and thus the only one who looked at it. It feels very public now, and I don't mean once you put it on github. I mean that there are best practices, and they aren't the secret handshake of a few embattled front-end developers stepping all the way out of the closet for the first time. Hell, sometimes they don't even come from JavaScript developers. I repeated something I hadn't fact-checked in nearly two years at work last week and some corrected me with a jsperf. For a minute, my unspoken reaction was, "It can't be wrong, I learned that at a JS conference!" And then I realized that you don't have to go to those conferences to understand things anymore, and that over the past year I've seen at least as many conference talks taking stock of state of JS as I've seen unveiling new or revelatory information.
As JS developers, we don't really move JavaScript forward anymore. Browser vendors do that. Library authors who used to be the only people making our jobs possible without risk to our sanity are now just providing consistent abstractions around techniques that are built in, backward-compatible API calls that let our code remain the same while the logic moves from something written by us or developers like us to a part of the platform we're writing for. And that's what I actually want to talk about.
At SXSW this year, someone predicted that jQuery would not exist - at least, as we know it today - in two years. It was kind of one of those things where your mouth goes, "What?! That's ridiculous!" while your brain goes, "Whoa, of course." Obviously jQuery continues to improve, but in terms of the stuff that people desperately needed it for, it seems to me it's been stable for some time. When I began my job last week I found out that there are a few parts of the site we're in the process of upgrading from jQuery 1.3.2 to 1.6.2. I asked why we weren't upgrading to the latest version. Part of the response was that the upgrade had begun when 1.6.whatever was the latest version. The other part was that the difference between the slightly-older and most-current versions didn't seem compelling enough to justify starting over.
The idea of an optional jQuery upgrade is somewhat fascinating to me. People got stuck on 1.3, that's understandable. There was a legitimate risk of things breaking, and how many sites had a full suite of regression tests at that point? But when did it become an option to not upgrade for lack of perceived value instead of threat of destruction? I don't know, but I feel like it was recently. And although I think the changes since jQuery 1.6.2 are pretty fucking slick, I have to agree that the world isn't going to end if we don't upgrade immediately, or even if we never do.
My impression is that we're in a brief window right now where jQuery still has a brilliant team of people working on it, but is stable from the perspective of most users. The most advanced might care deeply about event delegation and the features of deferreds, but someone who merely wants a reliable cross-browser click handler probably doesn't give a shit. And they no longer have to. jQuery and others solved the problem so well that we can all safely forget there was a problem. Unfortunately, I think that means once there are no more improvements to make to event handling and no more features to add to deferreds, the brilliant team will begin moving on to other projects. I think the same will happen to Backbone, and Socket.IO, and whatever goofy-ass transpiler is cool right now. The things we had to do manually moved into libraries and tools, and the things we needed libraries and tools for are moving into the browser. It's just a matter of time.
So if you agree that the sky is very slowly falling, what do you do about it? Two things. First, you begin to insulate yourself. Second, you take an active role in making sure the things you need most survive as open-source software and don't get tied to larger projects whose futures may not include the relevance they enjoy now.
I've been about insulating yourself from plugins for some time. That's cause I worked for a company that had three different dialog plugins in use and getting them standardized was a pain in the ass. When one was discovered to lack some important feature, no problem, someone would download a different one, implement it on a new page with new site-wide CSS to make it appear similar to the old one, and now there would be two ways of creating a dialog. Clearly that's fucking stupid. But many places settle for standardizing on one dialog plugin, or one UI library that contains a dialog widget, and leaving it at that. I think you should go a step further. Don't rely on developers (present and future) to know that you use jQuery UI for everything except this one super-special dialog. Instead create a library namespaced with your site or company's name and put everything under there. I don't give a shit if CoolCo.dialog
has a signature that matches the plugin's exactly and contains only one line where you pass the plugin its arguments. Wrap everything up, put it in the same namespace.
Once all your shit is insulated from the tools you're using, begin looking at the methods you rely on. Are you using jQuery selectors but only targeting cutting-edge browsers? Maybe that's something you could replace with querySelectorAll
. Is that necessary? Will it everything super fast? Is there a big risk that jQuery selectors suddenly become monstrously inefficient? Probably not. But, on the other hand, it protects you from Bizarro John Resig. Bizarro John Resig is a theoretical maintainer of the jQuery project who will emerge in the post-apocalyptic future of web programming and decide to rewrite the library to optimize it for WebGL, and remove everything else. When that happens, you will be glad you're using CoolCo.qsa
instead of the dollar sign.
To put it another way, there's excellent broadly applicable code in jQuery now that - for the things the library's known for - gets the job done remarkably well. Once jQuery reaches a point where you're very excited about the features a segment of the code provides, freeze that method yourself by copying it into your code. When a change to that feature that you need comes along, swap the code out. If you've insulated yourself well, hopefully the way your library uses the functionality doesn't have to change.
I can see that you think I'm totally crazy and living in the nineties and a bunch of other perjoratives. That's fine. Copying and pasting code is bad, isn't it? Well yes. But as we move toward a point where all the JavaScript developers are getting bored and antsy and making things like freaking CoffeeScript, it's smart to begin thinking about where you plan to get off the bus. Cause mark my words, this bus is headed to Crazy Town. The obvious practical problems are solved. Solutions to the difficult and subjective architectural problems are cropping up all over the place and converging on a few different philosophies. Eventually the geniuses of JavaScript are going to have nothing more amusing to do than make shrinkrays and giant homicidal robots, and you're still just going to want your selectors to work in Chrome 1643 the way they did in Chrome 18. You see what I'm saying?
So in addition to building a fortress to protect you from the giant robots, there was a second point, and this is about avoiding copying and pasting wherever possible. Let's go back to dialogs. You know what's awesome about jQuery UI? It's modular. If you just want dialogs, you can just get dialogs. We need everyone to do that. We need the pieces. Instead of downloading a package of everything including the kitchen sink we need modules. I think about this a lot when working on node stuff. Node lacks many things that are very monolithic. A lot of people are annoyed by this. The more I think about it, the more I like it. Your application should be written to run your application. There's a new version of node? Of course there is, it's Tuesday. Does it give you anything you need? No? Fuck it. Wait until you have a reason to move. More importantly, if a project progresses in such a way that it's introducing dependencies that aren't relevant for your app, consider whether it's appropriate for you to maintain a fork without the dependencies that provides a subset of the functionality.
I feel kind of awful saying these things, but I believe them. It sounds like I'm saying write JavaScript that'll live on a mainframe in a basement. That's because that's what I'm saying. Your application will either die or it will live on a mainframe in the basement. That field ain't gonna stay green forever. Eventually your JavaScript is going to get old. Somebody should start planning for its future.