I am curious to understand/figure-out if the ECMAScript-6 new-changes will work on the old browsers or not.
Why I am asking this question is:
I remember the introduction of 'use strict'; in ECMAScript-5, it was meant for the compatibility with the old versions.
That means the old browsers will keep working fine and they will just ignore it when they encounter the 'use strict'; statement while parsing the new JavaScript code.
And the new JS-engines will treat the statement 'use strict'; in some special way as detailed here Strict mode.
So, coming to the question
I seriously doubt and curious to know how would the ECMAScript-5 compliant browsers behave when they will parse the ECMAScript-6 code.
The reason for my doubt is ECMAScript-6 new features involve syntax change/updates. And the old browsers which are new-syntax-unaware-engines will start throwing errors when they encounter any of the new syntax from the following
yield[*], Map, Set, WeakMap, function* foo(){}, =>, for...of etc.
My concern is has the decision/inclusion of new features in ECMAScript-6 taken care of supporting the old-browsers without any break of code?
If Yes then how?
If Not then what should I do to keep my old-browser-users happy?
I see one solution to keep the users using old browsers happy by including some transpiler like traceur-compiler in my project. This will convert my ECMAScript-6 code to ECMAScript-5 equivalent. But do I have any other solution to keep my old-browser-users happy?
What you are trying to explain here is forward compatibility. Obviously ES 5 ( or more precisely ES 5 engine ) is not forward compatible. Any way its hard to acheive and rare to find.
Although you can see that some of the features of upcoming ES 7 are already out and hence possibly ES 6's engine may be implemented considering those enhancement. So whenever ES 7 comes, some of the features will be working in older engine.
Answer to the question, is ES 6 backward compatible will be "yes". Yes! ES 6's engine will be happy to run ES 5's code but vice versa is not true.
Many ES6 features will not work in an ES5 JS engine, particularly new syntax features such as for/of or arrow functions, generators, etc.... Some features like the Set object can be partially polyfilled for older browsers, others cannot.
Of the list of features you had in your question:
yield[*], Map, Set, WeakMap, function* foo(){}, =>, for...of
None of those are compatible with older versions of Javascript and will either cause syntax or reference errors. Some characteristics of Map and Set can be polyfilled (though not all). Yield, generators, arrow functions and for...of are just new syntax that older browsers do not process and cannot execute. It is possible to use an ES6 transpiler that will convert your code to ES5-compatible code. That isn't really ES6 backwards compatibility, but rather a code conversion that uses only ES5 syntax to accomplish the same things that are expressed in the newer ES6 syntax. Some of that is done with polyfills and some done with alternative ways of expressing an ES6 construct using only ES5 code (and usually more ES5 code).
If your code runs in something like node.js or if it's a plug-in for a specific version of a specific browser, then you have better control over the JS engine and can likely use ES6 features sooner than in a browser.
If your code runs in a browser and you're not using a transpiler to conver to ES5 code, then it will be awhile (many years) until most browsers in use on the internet are all ES6 ready.
The different purpose of "use strict"; (removing support for bad practices) is more consistent with allowing for compatibility with older versions than new language features like generators as the "use strict"; construct was specifically chosen to be something that a new browser could detect, but an older browser would just see as a normal string. New ES6 features that represent new language syntax are simply not that way as older browsers don't know how to process them and even if they could somehow ignore the newer syntax, they don't support the functionality that the new syntax implies.
You may find this article useful which discusses some of the issues in trying to use ES6 today:
ECMAScript 6 Resources For The Curious JavaScripter
If you want to use most of ES6 capabilities today in a wide range of browsers, then your best option is probably to transpile your code using something like BabelJS. This will transpile your ES6 code into ES5 compatible code that will run in any ES5 browser. You get to write in ES6, but the code will run in a wide range of browsers.
Or, if you're running in only a specific environment (such as a browser plug-in for a specific version of that browser) or a specific runtime engine such as node.js, then you can write code that uses the ES6 features that are already supported in that specific engine.
Related
Regarding compatibility between ECMAScript specification and actual implementation;
It is fairly easy to check out the data about browser support for ECMAScript2015 (ES6), but I found it pretty difficult to have an equivalently clear table for all the following ES versions (ES7+).
By the time this question is asked:
Mozilla has some info on their website: it is possible to see that ES7 and ES8 are fully supported, ES9 still has some problems and ES10 is supported on the latest versions.
I can also guess that IE11 never progressed after ES5.
I did not find anything for the other browsers, just some stolen info here and there.
How can I check what the current browser-support level is?
Browser vendors don't implement specific versions, but specific features. Almost every modern browser is still missing features from ES2017-ES2020. Hence there is not and won't be a table where you can see an ES version to browser version mapping.
But that is not a problem because you as a developer do the same. You use features, not versions of ECMAScript. Caniuse is still a great resource to check for support of individual features. If you are not happy with the data presentation on Caniuse, maybe these compatibility tables are better for you. Additionally, you can use polyfills and Babel for transpiling of newer features to older runtimes.
The simple reason is: they don't support it. Everything above ES6 is still in the works. Since ES6 is still being adopted and not all browsers support everything there's no reason for them to aim for ES7. If you want to use >ES7 features I would suggest looking into Babel, since there are ways to use ES7 and above and compile it back to ES5 so that even IE supports it.
I implemented CKEditor on a project and I was surprised to discover, either in the interface or in the source code, that it's written in ECMA 6, using all its modern features such as the short function notation (arrow functions).
Given these features are not widely supported as the ECMA 5 version is (not yet as of today, July 2018), I ask why the developers made this strategic choice: are they not interested in a wide browser compatibility? Or is CKEditor so well spread to allow them to dictate a precise direction towards modern browser versions, risking to lose a portion of users?
Browsers are not a problem
Let's be clear here:
CKEditor 5 can be run in all browsers which it supports without any transpilation. All browsers which it supports have a sufficient level of ES6 support.
Why would you need ES5?
The only reason why you might want to transpile CKEditor 5 from ES6 to ES5 are:
Legacy browsers which it doesn't support (at least at the moment).
Existing setups which use ES6-incompatible JS minifiers (UglifyJS). It may be a bit inconvenient to include CKEditor 5 in such applications but, as it was commented already, we explain how to transpile CKEditor 5 to ES5.
Development environments for frameworks like React (create-react-app) or Angular (angular-cli) which didn't catch up yet and still require that libs kept in your node_modules/ are in ES5.
The last case is indeed a bigger problem because you don't have that much control over this environments as on your own projects. As I commented on Twitter:
3 years ago we decided that CKEditor 5 will be released in ES6 because all browsers which we planned to support should have a sufficient ES6 support by our ETA.
We were right – it worked great... in the browsers.
It turned out that the problem is in the build environments (create-react-app, angular-cli) which did not catch up.
We'll need to introduce ES5 builds just to satisfy these envs ;/
To clarify – I'm not criticising authors of these tools. It's more of an observation that we've been always worried about browser support while today the tools stop us.
And, as I mentioned in the other tweet, the problem is broad (e.g. finding a supported, stable, ES6+ compatible and fast minifier – see e.g. https://github.com/webpack-contrib/uglifyjs-webpack-plugin/issues/262 …).
Fortunately, the situation is improving:
#mtrebizan:
I think CRA 2.0 will be shipping non-transpiled code,just don't know how far release is. cc #dan_abramov
#dan_abramov:
There’s alphas you can try. Other than that the ETA is when the community makes it happen 🙂 there’s active work and you can help too
I know there was work in angular-cli on improving this situation too. So, in a relatively short time, all should work smoothly too.
Time aspect
The difference (in terms of features) between ES6 and ES5 is huge. Back in 2014, when we've been starting CKEditor 5 development, we chose ES5. ES6 wasn't standardised yet.
However, the situation changed in 2015. ES6 got published and our tests proved that all features we looked to (classes, generators, iterators, weak sets, weak maps, and more) were already available in Chrome. We decided to go for it and see.
About 1.5 year later CKEditor 5 worked natively (without any transpilation) in all modern browsers (with the exception of Safari which had a nasty bug). At the same time, babel-minify became usable so we didn't have to transpile CKEditor 5 to ES5 even for production.
It's 2018 and the number of obstacles was reduced even more. There's a chance that still this year you won't have to transpile CKEditor 5 to ES5 unless your project is supposed to be ES5 because of browser support (but then, why would you include CKEditor 5? it's not going to work in those browsers anyway).
Looking at the history of CKEditor 3-4, CKEditor 5 will stay with us for the next 8+ years. So, we're talking here about 2026+. This means that for the vast majority of its lifetime ES6 will not be a problem.
CKEditor supports vanilla javascript (ES5) and ES6 as well. The issue is not the editor, it just supports it, doesn't care about compatibility because it doesn't know where your code is going to run but only how to highlight and give you tools to develop it.
The thing is that, by the time, the ECMA standard is under heavy development, improving in every version, so there's a lot going on, there are a lot of proposals being added every month, some passes and makes their way into the standard, which later gets into cool features we can use like arrow function.
All of that makes it harder for browsers to catch on the new updates. Even so, there are a lot that supports the new features now (you may track the updates in that page).
Anyway, besides from all of that, you may use a code compiler like Babel (which compiles ES6/ES7... down to code the browsers can understand such as ES5). It's widely adopted, and recommended for the thing it does: Make your life easier. Many big companies adopted it, such as Facebook which uses react (and made it) using Babel to compile not only ES6 but JSX (check this).
Side note: Why should I use ES6 if I need a compiler?
https://itnext.io/why-you-should-use-es6-56bd12f7ae09
I would like to know if it's secure to use let and const keywords while working with UI5. I don't know if returning a let, const, or even creating for instance a sap.m.Table with let would have adverse effects.
Maybe someone has some previous experience with this?
The documentation still warns about the possible incompatibility with UI5:
⚠ Restriction
We currently do not guarantee that newer ECMAScript standards, such as ES6/ES2015, work with OpenUI5.
On the other hand, I've been using ES6+ features (including const and let) with UI5 without any issues so far.
Note
In order to support building the application with ES6+ syntax in the application code with ...
UI5 Tooling: upgrade the npm dependency #ui5/cli at least to the latest 2.x.y version. See "ECMAScript Support" in UI5 Tooling for more information.
SAP Web IDE: if your project still depends on the legacy #sap/grunt-sapui5-bestpractice-build, ensure its version is at least 1.3.65 or newer e.g. 1.4.0.
Reporting the code coverage with the legacy blanket.js library version lower than 1.2.0 fails if ES6+ syntax is used for the target project. Even if no ES6+ syntax is used, the UI5 bootstrap config sap-ui-async has to be disabled in order to allow the code coverage report with blanket.js. Subscribe to OpenUI5 issue #3540 to get notified about the latest development regarding the code coverage report feature in UI5 projects.
I would assume that you are afraid of browser incompatibilities? let and const are constructs for declaring variables; they do not affect object lifetimes. let declares a block scope variable whilst const declares a read-only variable. The objects contained in these variables have a completely different life cycle.
This is not really a UI5 issue, but a general JavaScript issue. Regardless of the libraries that you are using, the compatibility of your app will be determined by two factors:
The compatibility matrix of each of the library that you are using.
The compatibility of the code that you are writing.
As you can't really control the compatibility matrix of UI5 (which should cover the compatibility matrix for ES6), it all boils down to two major questions that you have to ask yourself:
What browsers do I support?
Can I use something to transpile my code to support older browsers?
For the first question, if you only care for browsers which can support natively ES6 (not IE), then you can definitely use it. Otherwise, the second question might make more sense. If you have a decent C.I. pipeline in place for your app, then you could use something like babel to transform your shiny ES6 code into the verbose spaghetti that IE loves so much.
Later edit:
As per the comments, I would point out that ES6 is not a supported in an all-or-nothing fashion. Feature sub-sets (like support for const and let) may be available for some browsers (IE) even if ES6 in its entirety is not. Concretely, based on https://caniuse.com/#feat=let and https://caniuse.com/#feat=const, it seems that let and const are available in IE11 (but not in older versions). Other features like ES6 class definitions are not supported.
SAP WebIDE can deploy ES6 let/const syntax as long as you use a newer version of the build module.
Just use: "#sap/grunt-sapui5-bestpractice-build": "1.3.65"
I want to use ES6 features in my script, and having all browsers support it. How can I do that, and can I?
I've been thinking about using some tool that will convert my code to ES5 automatically on git pulling it on the server, and create the second file out of it. And then in the browser I could use one of those scripts, depending on the browser and its version.
Is this possible?
It would however create some problems:
Converted code would have the same performance as writing the code
in ES5 natively.
I would have to write some kind of if in the HTML, and I want to
include just one script, without anything else.
What's the best way to do this?
Until more browsers support ES2015 (aka ES6) features, using transpilers and polyfills will be the only way to go. Checkout the ES6 compatibility table to determine what features you can use today for the browsers your site supports.
Keep in mind that there are two main parts to ES6:
new language features
new native API features
Until all the browsers your site supports have support for the new ES6 language features, you won't be able to use them in your scripts without first transpiling them to an ES5 equivalent. I've used babel and it has worked great. The ES5 equivalent code that is generated has performed just fine. It also beats me trying to write equivalent ES5 code manually. The code generated by babel has been thoroughly tested by babel's test suite and has been used by thousands of developers around the world. Also, writing your code with ES6 is shorter and easier to maintain. This saves a lot of developer time. When the day comes that when all the browsers your site supports have support for all the ES6 features, then you can turn off the transpiling step in your build and you'll get the full benefit of native browser performance without having to manually convert your manually written ES5 code to ES6.
Many of the new native API features can be used today by providing a polyfill. The polyfill is only needed when you want to use an ES6 feature AND you need to support older browsers. With a polyfill, only the older browsers may have slower performance compared to the native implementation. Since most of the modern browsers already support many of the native ES6 API features, many of your users will get the full performance of the browser's native implementation. From my experience with polyfills, I have not noticed any significant performance implications.
If you are concerned about modern browsers unnecessarily downloading and running the polyfill all for naught, then there are techniques you can to do minimize the impact:
On the server-side, you can detect the browser making the request and determine whether to bother sending the polyfill script tag in the response.
You can properly version the polyfill and make sure the web server's caching is set so the browser will rarely make a request for the polyfill after the initial download.
babel used to be able to transpile the ES6 code in your html files, but that feature has been removed. You can just move your embedded code to a separate external JavaScript file. If you don't like the idea of incurring another request to get this external JavaScript file, then you can do the following:
Write your ES6 code in a separate file.
Run this file through babel
Use your server-side scripting language to include the transpiled content directly in your HTML.
#DannyHurlburt's answer was correct at the time of posting it, but now, you can use TypeScript language (with .ts file extension) to work around this. TypeScript is a strict superset of JavaScript, so any ES6 code you have is also lexically valid TypeScript. TS compiles to old versions of JavaScript as old as ES3.
I'm looking through the compatibility list for JS6 and its not promising. According to that list it will be at least 3 years before it is usable for everyday use. Is this correct?
Keep in mind that the page you linked doesn't take into consideration browser market share. For example, if there were a single browser with 100% coverage added to that page, the page as a whole would still look bad. However, if that browser accounted for 95% of all browser market share, things would actually be pretty good.
The page also doesn't consider importance of features, only if it's supported or not. While 100% compliance may be a long way off, vast amounts of useful features – like the spread operator – already have wide support.
In the meantime, as others have pointed out, there are many polyfill libraries available to help you bridge the gap until ECMAScript 6 is fully supported by all major browsers.
It is not JS6. It is ES6, or ES2015.
IE has ceased development and will always be red.
Although red, most non-syntax features can be shimmed, such as Array.from, Promise, and even WeakMap. Throw in a script and your code can use them.
In most browsers you can directly use arrow functions, new object syntax, template string, array spread, promise, for of, const/let etc.
They can simplify your code a lot.
Finally, we have Babel, which transforms your ES6 script to ES5 script. You can code ES6 now, run Babel, and get code that runs on any browsers. There are many ways to run Babel, from command line to in-browser.
Babel is the secret of the javascript chatroom people.
We are using ES6 now and using it daily.
A few language features simply cannot be done in ES5, in particular Proxy and subclassing, thus Babel do not support them. Firefox is the only browser to support Proxy, and Node.js supports an old syntax which can be shimmed into the final syntax.
As you can guess, they can do things totally impossible before, and may change how you design your program; such a radical change does take years to mature and spread, regardless of language.