Old ASP.NET applications and the end of TypeScript ES5 output
Posted: (EET/GMT+2)
If you maintain older ASP.NET Framework applications (such as those using .NET 4.8) that still compiles TypeScript to ECMAScript 5, there is an upcoming modernization issue worth keeping in the radar.
Shortly put, TypeScript will stop supporting ECMAScript 5 (ES5) output as a target. TypeScript version 6 is the last major version supporting this, and so, the following configuration is tsconfig.json is deprecated:
{
"compilerOptions": {
"target": "es5"
}
}
Starting with TypeScript 7, the above es5 target is no longer a supported compilation target. The lowest supported target is then ES2015 (as target, es2015).
For many applications, this is perfectly reasonable. Modern browsers have supported ES2015 features for years. But older ASP.NET Framework applications may have another dependency on ES5 that is easier to miss: their bundling and minification pipeline.
Consider this contemporary TypeScript:
const add = (first: number, second: number) => first + second;
When targeting ES5, TypeScript can turn newer JavaScript constructs into older syntax:
var add = function (first, second) {
return first + second;
};
With ES2015 or later as a target, newer syntax such as arrow functions and const can remain in the generated JavaScript:
const add = (first, second) => first + second;
The important thing to notice is that the web browser usually accepts this perfectly well. But, an old ASP.NET MVC application might still process that JavaScript with the classic
System.Web.Optimization bundling system:
bundles.Add(new ScriptBundle("~/bundles/app")
.Include("~/Scripts/app.js"));
The older ScriptBundle functionality does more than just concatenate files. It also applies JavaScript
minification when optimizations are enabled.
The classic ASP.NET optimization framework uses WebGrease for its minification pipeline. That tooling comes from the ASP.NET 4.x era and can have problems with newer JavaScript syntax.
This can produce a confusing situation:
- TypeScript successfully produces valid ES2015+ JavaScript
- Chrome, Edge, and Firefox all understand the modern JavaScript
- the ASP.NET application still fails while creating the bundle, leading to
NullReferenceExceptionfailures, among others.
It can be even more confusing because the problem may only appear in Release builds. In a normal ASP.NET MVC application, bundling and minification are often disabled while
debug="true".
You can force them on while testing:
BundleTable.EnableOptimizations = true;
This is a useful compatibility test before changing the TypeScript target. If an old application currently uses:
"target": "es5"
try compiling with:
"target": "es2015"
Then test the application with bundling and minification enabled. Look especially for generated syntax such as:
letandconst- arrow functions
- classes
- template literals
- other ES2015 or newer constructs.
If the old bundler cannot process the resulting JavaScript, the long-term answer is probably not to keep the whole application on ES5 forever. Instead, consider moving JavaScript compilation and minification into a modern frontend build step.
For example, TypeScript can produce modern JavaScript, and tools such as esbuild, Webpack, or another current bundler can handle the final browser assets.
The ASP.NET application can then simply reference the already-built JavaScript:
<script src="/Scripts/dist/app.min.js"></script>
If you genuinely still need ES5 output for an old runtime, TypeScript recommends using an external compiler or post-processing tool once you move beyond TypeScript 6.
To summarize, do not assume that changing from ES5 to ES2015 is only a browser compatibility change. In older ASP.NET applications, check every tool that parses or transforms the generated JavaScript. That includes the server-side bundler.
Good migration steps:
- check the current TypeScript
target - compile once with
es2015 - test ASP.NET bundling with optimizations enabled
- check Release builds, not only Debug builds
- move old JavaScript minification to a modern build tool if necessary
- only keep ES5 output if you actually still have an ES5 runtime requirement.
This is one of those modernization issues where the C# application itself may keep working perfectly well on .NET Framework 4.8. The part that finally forces attention can instead be a JavaScript toolchain that has quietly remained unchanged for a decade.
Hope this helps!