What’s right and wrong about ExtJS
However, the biggest problem of ExtJS is its management. Support is poor, release cycles take much too long, bugs never get fixed in time (or at all), and for a long time they refused to let go of the 5-developer pack minimum. This is just the tip of the iceberg; I could go on for quite a while but this would lead me away from the main topic of this post. Let me just end by saying that I am not the only one who thinks this way. Just take a look at the comments section of Sencha’s roadmap updates and you’ll find that the community is pissed at Sencha. As former employee Mitchell Simoens puts it, ExtJS is destined for the legacy bin. I don’t have all the facts and information, but given my experience with Sencha for the last five years, I tend to agree with him. Whenever I start a new project, ExtJS does not end up in the shortlist of potential frameworks. And that really is a pity.
From a developer’s perspective, it is unacceptable to be still using the same methods for creating a web application. Having to use proprietary dependency loaders and command-line tools may have been okay back in the days, but today we want to use modern web development techniques. For instance, including scripts and creating bundles manually is simply a pain in the ass. Not only is it inelegant, it is also error-prone. Once upon a time, you had to explain why you wanted to use webpack or React instead of using good old jQuery, now you have to explain why you don’t. I’m sorry to say it, but ExtJS is such a reason. You could consider using ExtReact or ExtAngular but that’s just wrapping a mess in even a bigger mess – which is exactly what they did.
If ExtJS could just embrace ES modules, then we could all get on with it. But no, they don’t seem to care about that. Instead, the only thing they seem to be doing are newsletters and webinars. There even isn’t support for TypeScript. There have been some community efforts, but as these things go, they are very short-lived. I would like to suggest a lightweight approach which won’t break your application and possibly won’t even change the output of transpiled files.
Ext TypeScript definitions
In ExtJS, you describe a class with
Ext.define and you instantiate Ext classes with
Ext.create. You could also use the new keyword but then you would sidestep some of its features (such as loading classes).
Using ExtJS in TypeScript will give you one or two problems. For starters, TypeScript needs to know what Ext means. You could simply bypass the Ext framework entirely and declare a Ext variable:
TypeScript will ask no further questions as you told it can be any type. If you have Ext.craete in your code, TypeScript won’t complain that it doesn’t know ‘craete’. Then why bother using TypeScript if you are just going to use the any type?
There have been a few attempts (see here, here and here for some examples) to address this issue, but as I mentioned before they are short-lived and I wouldn’t want to rely on something that hasn’t been maintained in years.
would churn out a good old Ext class definition:
The idea is great but the execution isn’t, which is not his fault. Having your own version of TypeScript is not really what you want for a lightweight workaround. Today, one could consider TypeScript transformers to add support for Ext. But to get started with this, one would need to be able to allocate some budget as this is not going to be a trivial task.
Instead, I decided to go with a less effective but much simpler approach: TypeScript type definitions. A type definition describes the shape of a type, function, or any other consumable item. Chances are you already have the @types/jquery in your package.json file’s devDependencies list. This package contains description of the types that the jQuery library exposes. It does not contain the actual implementation but it lets TypeScript know that there is a bunch of stuff you can do with
I’ve decided to do the same for ExtJS and created a bunch of .d.ts files. Such files are not required to run your app but they are necessary for compiling. This is an unobtrusive way of TypeScriptifying your solution while minimizing the risk of breaking your app. While you’re boyscouting or refactoring, you just add or modify the typing definitions.
For example, here is my ext.d.ts file:
This allows me to call Ext.create without problems and with type support in the rest of the application:
Do you see what’s going on with
Ext.define<T>(className:string, config:T)? By defining an interface or type definition, we can benefit from the type safety of TypeScript while we still adhere to the Ext class model. Configuration items such as extend, selModel, columns are all recognized by the TypeScript compiler because they have been defined in the Ext type definitions.
And the great thing about this is when I run tsc, the output will exactly be the same. How’s that for unobtrusiveness? Now I have support from the TypeScript compiler while changing absolutely nothing to the output. This is exactly what I was looking for.
Such a simple modification just improved my life massively. In VS Code, I can just press F12 when I focus on Ext.grid.Panel, and I’ll be redirected to the d.ts file. Typos and passing the wrong parameters to my functions are a thing of the past, all thanks to the TypeScript definition files.
Even though this is still bodging, it is something I can safely do as part of my day to day tasks. For example, if I replace the ‘any’ type for certain variable by ‘Ext.grid.Panel’, I might get some errors as TypeScript does not recognize a method called suspendEvent(). Because I maintain my d.ts files, I can simply add a suspendEvent method to my Ext.grid.Panel interface.
Doing this also gives me a valuable insight which methods and properties are used in the app, and where they are used. As any developer will tell, you should keep your layers as isolated as possible. ExtJS code should reside only in the top layer of your app. Any business logic on the front end should be agnostic of its implementation. If done correctly, you should be able to swap the front-end framework with another without a redesign of the business layer. Thanks to my refactoring efforts, I am slowly getting there so I can get rid of ExtJS and replace it by Angular or React, eventually.
The workaround I just showed doesn’t address any of ExtJS’ flaws but at least it gives some support to improve an application’s stability. Purists will undoubtedly condemn this approach and I agree with them. However, if there is limited time and budget, you have to work with what you have. And to the very least, it’s a first step towards a modern web application.
To end on a potentially positive note, if we are to believe them, Sencha will address some of my concerns. For instance, in their update to the roadmap, they wrote the following:
“Our engineering teams are working on a transpiler transform process that will allow you to write Ext JS classes and components with ECMA Class syntax. This process will be transparent to the developer.”Sencha, Updates to Sencha 2019/2020 Roadmap, December 11, 2019
I guess we’ll have to see where the ExtJS saga will take us. I am anxious to know what they’ll come up with. I really hope it’ll be worthwhile as companies have made serious investments, which they – understandably – would like to keep.
Until then, I wish you happy refactoring!