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
Related
How to check the ECMAScript standard version that the currently installed JS on the system is using, is there any special command to know or we need to check the JS version and then Google it to know on which ES standard version it is based up on.
Environments do not run "a particular version of the standard." Rather, environments implement features from different years of the specification piecemeal. For example, it may be that in June 2022, a particular browser has implemented, say, 7 of 9 specification additions or tweaks from the prior year - and a different browser will implement those things on a different schedule.
Even if something is in the standard, there's no absolute guarantee that environments will support it, unfortunately. Usually they will, and often in a reasonably timely manner, but not always. For example, proper tail calls, from ES6, still have not been implemented in V8 or SpiderMonkey.
So, to figure out what is supported in a given environment, you'll have to test all the properties/features you're looking for individually. (eg window.hasOwnProperty('Promise'))
Often, rather than script-writers trying to detect what a browser currently supports, and working around that, script-writers will simply use a polyfill service (example) that adds all necessary missing features - that way you can get on with the main logic of your application and simply not worry about it.
Vanilla JS does not have any version as of Jquery,Angular, Reactjs, etc which are build using vanilla JS. It depends whether the current browser update supports upto which version of ECMA Script. You can use any version syntax as long as you can compile your code to ES5 syntax if your browser does not understand higher version of JS.
I am writing a Polymer 2 application. The default is to transpile ES6 to ES5 so that you can use ES6 syntax and be sure it will just work.
The problem with this is that everybody (even supporting browsers) get to receive transpiled code.
Two questions:
Is it just too crazy to say "no" to legacy browsers, and just stop transpiling?
Is there an easy-ish way to redirect specific browsers to a non-transpiled version of the app?
It really depends on the audience of the app you want to create. As for my own projects, I can see in my Google Analytics that there are still some people who are accessing it via Safari 8, 9 and even IE 11. I cannot just tell them to use a different browser because of several reasons... mostly financial reason (either personal or corporate)
Because of that, it is still a default for me to just transpile back to ES5 (given that I am using Webpack for now while waiting for the script type="module" to stabilize).
As for easiest way, they say if you use Polymer-CLI's serve function, it autotranspiles your code depending on the browser's capabilities.
Or you can have a simple javascript code that tries to check an ES6 method, then if it works, it loads the ES6 version of the bundled code... if not, it loads the ES5 version of the bundled code + the custom-elements-es5-adapter. But this one takes some performance hit because of the wait to parse the initial JS script to check before loading the necessary files instead of loading them right away (I haven't tested this though)
Or you can check in the server what type of browser is calling and then heuristically guess what type of version code you want to send.
As for performance for the overhead of the transpiled code, it's a bit miniscule, given that if you are just using Polymer.Element, you can get at least 12KB of code... then you'll have like 30+KB left to show content, which is more than enough to have a PRPL+50
The simple answer isL use prpl-server-node which does exactly what I was talking about, and more.
Specifically:
Differential Serving
Modern browsers offer great features that improve performance, but most applications need to support older browsers too. prpl-server can serve different versions of your application to different browsers by detecting browser capabilities using the user-agent header.
Builds
prpl-server understands the notion of a build, a variant of your application optimized for a particular set of browser capabilities.
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.
In Coders at work, Douglas Crockford discusses how bugs in browsers cause Javascript to be a complex, clunky language and fixing it is a catch-22. In Beginning JavaScript with DOM scripting and Ajax Christian Heilmann says something similar "[The] large variety of user agents, of different technical finesse [...] is a great danger to JavaScript."
Why doesn't JS have a breaking new version? Is there something inherent n the language design where backwards compatibility becomes a must?
Update
Why can't javascript run with multiple engines in parallel? Similar to how .NET runs versions 2, 3 and 4 on the same machine.
Lazy copypasta at OP's request:
JavaScript is just a programming language: syntax and semantics. It has no built-in support for browsers (read: the browser DOM). You could create a JS program that runs outside of a browser. You (should) know what an API is - the DOM is just a JavaScript API for manipulating an HTML page. There are other DOM APIs in other languages (C#, Java, etc.), though they are used more for things like XML. Does that make sense?
Perhaps this MDC article can clarify further.
Well a breaking change would break a lot of existing websites, which would make a lot of people very angry :)
Backwards compatibility is important because of the large number of browsers deployed and the wide variety of versions of those browsers.
If you serve a new, incompatible kind of Javascript to old browsers, they all break.
If you invent a new language that is not considered to be Javascript by existing browsers, then it doesn't work with the majority of browsers. Very few users will be willing to download a new browser just to work with your new language. So web developers have to keep writing compatible Javascript to support the majority of the users, no matter how great the new language is.
A lot of people would like to see something better than current Javascript be supported by browsers, but it just isn't going to happen any time soon. All the makers of browsers and development tools would have to support the new thing, and continue to support the old Javascript stuff too. Many interested parties just wouldn't consider the benefit to be worth the cost. Slow evolution of Javascript seems to be the only viable solution.
As a matter of fact, ECMAScript 5 is not fully backwards-compatible for the very reasons you mentioned.
Inertia.
Making a breaking change would break too many sites, no browser vendor would want to deal with all the bug reports.
And PHBs would be against targeting a new version, why should they have their developers write javascript for the broken and the fixed languages? Their developers will have to write it for the broken version anyway so why bother with 2 implementations (which from a developer perspective sucks too since now they have to update, support and debug 2 separate trees).
Ecmascript 5 has a "strict" mode. I think this strict mode is intended to combat the problem you mention. Eventually you'd mark scripts "strict" that you want to use the new engine, all others get run in an old crufty VM, or with un-optimized codepaths or whatever.
This is kind like IE and Mozilla browsers having multiple "modes" of rendering websites (IE even swaps out rendering engines).
See this question about it
Javascript has subtle differences across different browsers. This is because each browser manufacturer has different sets of responsibilities to their users to support backwards compatibility (if any). If I had to pick, I'd say the biggest barrier to the advancement of javascript is older versions of Internet Explorer. Due to service agreements with their users, Microsoft is contractually obliged to support older browsers. Even if other browsers cutoff backwards-compatibility, Microsoft will not. To be fair, Microsoft does realize how terrible their browsers are and will hopefully push IE 9.0 very hard. Despite the inconsistencies of javascript across different browsers, they are subtle enough to make cross-browser programming more than feasible. Abruptly cutting off backwards-compatibility would be a practice that would make web development a nightmare. Incrementally cutting of backwards-compatibility for specific aspects of javascript is feasible.
There is much more else wrong with JavaScript. You can't be fully backwards-compatible with things that were never fully compatible when they were fresh... Say, the length of the array [1,] is reported as 2 by at least older versions of internet explorer.
The biggest fault of JavaScript is that is comes with a tiny, incomplete and pretty much unusable standard library. That is why everyone retreats to using jQuery, Dojo, Mochikit etc. - these offer mostly functionality that should be part of some standard library included with the browsers instead of floating around in thousands of copies and versions. It's actually what makes .NET and Java so popular: the language comes with a reasonable standard library. With C and C++, you have to dig out the nice libraries (Boost e.g.) yourself.
But other than that, the ECMAScript standard occasionally is updated.
Google is also trying to do this bold step forwards and redo JavaScript in a slightly more sane way. The efforts are known as Dart: http://www.dartlang.org/
For all I can tell, Dart largely uses the syntax of JavaScript minus a couple of its quirks. Apart from that, it also is nicer for the virtual machine and will thus likely run faster (unless of course you compile Dart to Javascript and use a JavaScript VM; which is offered as a compatibility option). But of course any hardcore JavaScript nazi^W enthusiast will not like anything that claims to be better than JavaScript. Whereas for me, they don't go far enough. In particular, they still don't provide enough "classpath".
What browsers / engines already support ES5 [strict]?
All the major browser vendors more or less have had ES5 fully implemented for a few years now (though IE 9 doesn't support strict mode). kangax created this compatibility table representing the existence of ECMAScript 5 features in major browsers and other JS implementations. It will even list the availability of those features in the browser you visit the page with. It doesn't test conformance, however.
Kris Kowal created es5-shim.js, which provides as much of the functionality of ES5 as possible to ES3 compliant implementations. Of course, not everything is possible but the goal of the shim is to allow code to gracefully degrade.
AFAIK, the only implementation of ECMAScript 5 is BESEN. It's a bit disappointing, really. BESEN was created from scratch, by a single developer, in just a couple of weeks. Google, Microsoft, Apple, Mozilla and Opera on the other hand, with all their developers, all their money, haven't been able to provide an implementation after almost 11 months. And that is despite the fact that they have dozens of developers, have an already working implementation as a base to start from, were a part of the standardization process from day one (and thus had access to the specs long before the author of BESEN did), and most of the features in the ES5 specification were taken from already existing implementations in the browsers.
AFAIK, the only two features that in ECMAScript 5 that were not already part of JavaScript were the Properties API and Strict Mode.
This page of the ecmascript wiki has links to the bugs remaining in the major implementations in progress.