Which version of EcmaScript should I use in the TypeScript configuration
TypeScript allows converting most of the ES next features to ES3, ES5, ES6, ES2016, ES2017. Of course, you can also target ES Next. But which version should you target?
#Why you should use the highest possible version?
Using the highest version allows you to write shorter code, and use more readable features, such as async/await, for..of, spread, etc. It's not only shorter, but also easier to debug. For instance, async/await is rewritten by TypeScript to a state machine. So, the call stack is harder to understand, stepping into the next statement is not easy because you have to step into the step machine functions. The source map can sometimes help, but it doesn't solve all issues. You can also blackbox some scripts. For instance, you can blackbox tslib
if you import TypeScript helpers.
So, if you can target ES Next, do it! Unfortunately, this is not always possible. Let's see how to choose the right version!
#Select your target JS runtime
First, you must know which runtime you want to support. Do you need to run your application in a web browser and which one, in NodeJS or Electron. Depending on this choice, you know the JS flavor you can use. For instance, if you choose Electron, you know it uses Chromium version XXX so you know which functionalities are available. If you use NodeJS, it also uses V8, the JS engine of Chromium. So, it easy to know which features are supported. For a web browser, it's a little more complicated. You may want to support multiple browsers, and multiple versions of each browser.
You can check which features are supported by the web browsers and js runtime here: https://kangax.github.io/compat-table/es6. Tip: you can change the ES version on the top.
For instance, if you want to target IE11, you'll have to target ES5. If you want to support NodeJS, MS Edge, or Chromium, ES6 is ok.
Once you know which version you want to use, update the tsconfig.json
file to reflect your decision:
{
"compilerOptions": {
"target": "ES2016" // "ES3" (default), "ES5", "ES6"/"ES2015", "ES2016", "ES2017" or "ESNext".
}
}
#Which libraries to target?
Changing the target version also changes the available libraries. For instance, if you target ES5, you cannot use Promise. But Promise is not a feature that must be implemented by the engine. You can use another library to replace them, such as bluebird. This means you can target ES5 and use Promise as long as you add them using an external library. It's the same for Array.include
, and lots of functions.
TypeScript allows specifying which libraries are available. You can select them in the configuration file tsconfig.json
:
{
"compilerOptions": {
"lib": [
"ES5",
"ES2015.Promise",
"ES2016.Array.Include"
],
}
}
You can find the list of available libraries in the TypeScript documentation.
BTW, you can read my previous post to dynamically import polyfills
#Development vs Release configurations?
As I said in the introduction, using a higher version of EcmaScript may help to debug your application. So, it may not be a bad idea to have 2 configurations, one for the development and another one for the release. For instance, the first one can target ES next because you are debugging on a recent browser, while the second one can target ES5 because your customers may use an older browser.
TypeScript supports the configuration inheritance. So, you can create a common tsconfig.json
that contains all the settings, and a tsconfig.dev.json
that inherits from tsconfig.json
. You can build using tsc tsconfig.dev.json
. You can read the documentation about configuration inheritance for more information.
#Babel
If you are using webpack, gulp or any build tool, you may consider the Babel option. The idea is to configure TypeScript to target ES Next, and transpile to another version using Babel. Based on the previous link, Babel allows transpiling more things to a lower ES version than TypeScript. Using webpack, you can also automatically include polyfills with a plugin such as webpack-polyfill-injector
.
#Conclusion
Choose the configuration that makes you the most productive and which will run on your target browsers/runtimes.
Do you have a question or a suggestion about this post? Contact me!