Preparing for Ext 4.1 (Part 3)

As of this writing, Ext 4.1 Release Candidate 1 was just published a couple of days ago, so I thought it would be a good time to wrap up this series. In part 1 I outlined resources for learning about Ext 4.1, and in part 2 I dove into some of the common issues I dealt with myself while upgrading Extensible to support 4.1. In this final post I’m going to illustrate a couple of examples where I’ve had to implement API patches while still supporting multiple versions of Ext simultaneously (this will be especially useful for anyone writing components used by other developers).

Ext.getVersion() is Your Friend

Earlier in the development cycle of Ext 4.1, I realized that all of my XTemplate subclasses stopped rendering output correctly. In Extensible I override the applyTemplate method in my custom template classes to customize the incoming data object before it gets applied and generated to markup. At the time of the issue, XTemplate had already been switched to support the new rendering pipeline which now requires an output buffer to be passed along so that new markup is captured for deferred rendering, rather than rendered immediately. Since then apply and applyTemplate have both been aliased so that they will still work as expected in 4.1 (and so this problem has been resolved), but at the time they simply broke and I needed to work around them.

The problem wasn’t fixing the code — that part was easy. My big issue as a component developer was fixing the code so that it still worked under all versions of Ext going back to 4.0.1 (4.0.0 is hopelessly broken for Extensible and is not supported). If I simply switched the method to return the output buffer (which would have fixed it for 4.1) I would have broken it for all versions of Ext prior to 4.1. So how to solve it generically across Ext versions?

Ext 4.0 introduced a very handy new class Ext.Version, which tells you everything you never realized you’d need to know about the currently-loaded version of Ext. Try typing  Ext.getVersion() into the console with Ext loaded:

The class also contains some useful comparison methods, which allowed me to effectively solve me problem by changing the last line of my XTemplate subclasses to look like this:

Like I mentioned, this specific XTemplate issue has been resolved, but the key point is the strategy that you can use in any scenario where you have to branch your logic or syntax based on the version of Ext currently loaded.

Version-specific Overrides

Another example is with overrides that I ship with Extensible, which is an even more common scenario for component developers. Ext 4.1 is introducing a brand new syntax for defining overrides (teased near the end of this blog post), but unfortunately since my code still has to work back to 4.0.1, I can’t take advantage of that yet. However I commonly have to provide version-specific overrides, including removing overrides for things that have been fixed in 4.1, while continuing to override them for 4.0.x!

Applying overrides conditionally by version is simple using Ext.getVersion. Here’s a quick example from Extensible (the issue being patched was fixed in 4.1):

In general it’s a wise approach to keep your overrides as limited as possible, including to the specific version(s) of Ext required to be overridden. This will limit your exposure to unexpected regressions due to changes in the code in future versions of Ext as well.

Extending Ext.dd.StatusProxy

Hopefully you haven’t had to do this yourself (I can’t imagine that it’s too common), but if you have then you may be in for a big surprise with 4.1. I have a StatusProxy subclass that uses custom markup internally to display extra information during drag operations. As of 4.0.7, this was quite a pain as all of the markup definition was private to the StatusProxy constructor (an unfortunate piece of legacy design that did not get updated during the migration from 3.x). Even worse, the class was not an Ext.Component — it simply extended the native Object — so there was no managed rendering process to hook your way into either. The only way to customize the markup under 4.0.x was to override the entire constructor and re-implement it.

In 4.1 the StatusProxy class has finally received its due attention and gotten a nice makeover. It extends Ext.Component, and now uses the standard renderTpl config to define its markup, making customization a breeze. So what’s the problem? Since I was overriding the constructor (and never calling a superclass constructor since it was not a Component previously) I was now inadvertently breaking the Component lifecycle (which caused runtime errors).

To fix this I essentially had to branch the entire constructor, keeping my existing legacy code for 4.0.x, but then also using renderTpl and deferring to the parent constructor under 4.1.  That new structure now looks like this (I’m leaving the entire legacy constructor in place just to demonstrate how nasty it was before to override):

I guess I should also point out that this branching technically could be done inside of Ext.dd.StatusProxy itself (hint hint, Sencha guys). Even though it’s probably an uncommon scenario, and even though it’s not technically an API change to refactor the guts of the constructor, the poor design of the 4.0.x version essentially means that anyone who might have needed custom StatusProxy markup will be broken under 4.1 by default.

I guess there’s an interesting discussion to be had about Ext / JavaScript compatibility in general and where to draw those lines. Examples like this also highlight the need for better “compile-time” tooling in the JavaScript world so that the end developer could strip such compatibility code for deployment if it wasn’t needed (Sencha’s SDK tools are headed in that direction). Backwards compatibility has always been one of my personal hot buttons, but I’ll save that rant for a future post 🙂

Wrapping Up

Hopefully this provided a little insight into the extra care it takes to support components used by others across different versions of Ext, especially with the changes in 4.1. I hope you found this series helpful — I know that I spent a lot of time figuring these things out during my upgrade from 4.0 to 4.1, so if I save anyone even a little time dealing with similar issues I’ll be very happy!

By the way, even though I’ve been focused in these posts on the difficulties I had in upgrading, I want to close by pointing out that 4.1 is an incredible release, especially for the performance improvements in legacy browsers. I’d like to publicly congratulate Don, Nige and everyone else on the team for all their hard work over the past year or so. Those guys are really tireless when it comes to putting out the best Ext releases possible!

See also: Part 1 | Part 2

This entry was posted in Ext JS, Extensible and tagged . Bookmark the permalink.

3 Responses to Preparing for Ext 4.1 (Part 3)

  1. Don Griffin says:

    Another great article – thanks for the kind words and awesome content!

  2. The One says:

    Great stuff, Brian!

    Out of curiosity, why do you call 4.0.0 “helplessly broken”?

  3. Brian says:

    4.0.0 threw random errors on the calendar from deep inside Ext core (stuff like event objects being undefined). Before I spent any time trying to debug it 4.0.1 came out and those issues went away (and fixed a lot of basic stuff that was broken in general in 4.0.0). At one point I actually did go back and try to “fix” the calendar to run under 4.0.0 but decided it wasn’t worth the effort since there were so many general issues with 4.0.0 that most people should have upgraded from it anyway.