47

I am currently writing a web application using the MEAN Stack, and am attempting to write code in ECMAScript 6 JavaScript; however, I am getting errors in both Chrome and Firefox when using import and export syntax. Are there currently any browsers that fully support ECMAScript 6?

Please note: I am not asking when ECMAScript 6 will be supported by browsers. I'm asking which browsers support ECMAScript 6 import and export syntax. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla#Features_not_yet_supported_by_Firefox

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Gregory R.
  • 1,815
  • 1
  • 20
  • 32
  • 1
    http://stackoverflow.com/questions/13355486/when-will-i-be-able-to-use-es6-in-a-browser – vaultah Nov 04 '15 at 08:23
  • Astonishingly, Microsoft Edge claims to fully support it. – sailens Nov 04 '15 at 08:29
  • @vaultah: The question you posted was asked 2 years ago. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla#Features_not_yet_supported_by_Firefox The feature is not yet supported in Firefox, nor Chrome. – Gregory R. Nov 04 '15 at 08:29
  • 2
    But the answer in that question links to a [fantastic up-to-date resource](http://kangax.github.io/es5-compat-table/es6/). – deceze Nov 04 '15 at 08:30
  • Also: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export#Browser_compatibility – deceze Nov 04 '15 at 08:35
  • @deceze: I have visited that page prior to posting this question, and can't seem to locate the feature name (import and export syntax) Can you please guide me as to what the feature name may be for these syntaxes. Thanks! – Gregory R. Nov 04 '15 at 08:36
  • 5
    It seems import and export are missing from that page. However, I've linked to the MDN compatibility chart for specifically that feature above. In short: no browser *fully* supports ES6 at this point and apparently none supports import/export. – deceze Nov 04 '15 at 08:39
  • 2
    Seems as it's not supported yet on any browser. Quoting from website: "Note: This feature is not implemented in any browsers natively at this time. It is implemented in many transpilers, such as the Traceur Compiler and ES6 Module Transpiler." https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import – Gregory R. Nov 04 '15 at 08:40
  • @GregoryR. Your note directly conflicts with the title of your question. If you *are* asking specifically about import/export syntax I would update your title. – CodingIntrigue Nov 04 '15 at 08:44
  • Title updated. Thanks. – Gregory R. Nov 04 '15 at 08:47
  • 7
    The actual module loader is not part of the ES6 standard and there is currently no standard for it. If a browser cannot load modules (according to a standard) it doesn't make much sense to support the syntax for modules. So I guess we'll have to wait until a [standard](http://whatwg.github.io/loader/) is finished. – a better oliver Nov 04 '15 at 09:36
  • 1
    note that despite the module standard not being supported, 'import' and 'export' and 'default' are reserved words on Safari 9 and Chrome 50 (and possibly older versions too), so messing around in the Developer Console may give the false impression that there is support. – Michael Scott Asato Cuthbert May 12 '16 at 20:15
  • @zeroflagL Thanks for the link. I noticed the GitHub repo for the standard also contains links to the [implementation status of the milestones](https://github.com/whatwg/loader#implementation-status) on different browsers. – user4040648 Jul 05 '16 at 13:54
  • I would bundle (using rollup) modules anyway since loading them from the browser seems crazy to me, sending a request to the server per module..30+ requests? 100? – vsync Oct 25 '16 at 11:05

5 Answers5

38

It's supported in:

  • Safari 10.1 - IOS 10.3
  • Chrome 61
  • Firefox 60
  • Edge 16
Ali
  • 21,572
  • 15
  • 83
  • 95
17

Chrome and Firefox support import and export syntax (there exists tests for proper parsing).

What isn't supported is module loading - you can't load module by any means, because specification for it isn't complete. You have to use some kind of module bundler for this. I'm not front-end developer, but I have heard good opinions on Rollup from my coworkers.

Ginden
  • 5,149
  • 34
  • 68
  • 3
    Webpack, SystemJS, AMD, to name a few more bundlers :) – SethWhite Aug 29 '16 at 19:31
  • 8
    Rollup is the best (its super fast) and easiest to start with, and require zero learning. just run the command and it works. I've been using it for over a year with great success of several projects ranging in sizes. – vsync Oct 25 '16 at 11:03
  • @Ginden SystemJS is module loader , and webpack is module blunder.. is my understanding correct ? – refactor Dec 13 '16 at 14:54
  • 3
    @Ginden, What do you mean by Chrome supporting `import` and `export` syntax? I'm getting `Unexpected token export` – Pacerier Apr 08 '17 at 20:12
  • @Pacerier Because token "export" isn't allowed in context that you are trying. Actually you can't create context where export would be valid - it's hidden from end user and available only from internals. – Ginden Apr 10 '17 at 20:00
  • 3
    @Ginden So wait, it "supports" it but can't actually use it in any context? Isn't that a rather loose usage of the term "supports"? – RaisinBranCrunch Aug 10 '17 at 00:42
  • Chrome doesn't support import yet. – JavaRunner Feb 10 '18 at 11:13
  • It seems like this is now supported in modern browsers (except IE) https://caniuse.com/#feat=mdn-javascript_statements_export https://caniuse.com/#feat=mdn-javascript_statements_import – Nelson Rodriguez Nov 01 '19 at 14:29
7

As others have said, support for it is still very limited. But even if there was full support.... would it be smart to use it? How would we do that?

Think about it. A typical JS app written with Node JS modules easily contains dozens, even hundreds of (very small) packages. Do we really want that many requests?

Browserify, Webpack, Rollup etc are so popular because they allow us to bundle many small packages into one fast download. With code splitting we can let the module bundler decide at transpilation time, based on the code our pages are actually using and on some configuration settings, how many bundles to create and what to put in each of them. That way we can write many small packages and serve them as a (couple of) big bundles.

My point is that we should divide our code into packages that work well on a conceptual level, then bundle those packages into bundles that work well on a technical (network) level. If we write our code based on optimum network packet size, we end up sacrificing modularity in the process.

In the meantime, using it will probably only add to the confusion. For example, look at the example on the Edge blog:

import { sum } from './math.js';

Note how they add the extension .js to the from string? In Node JS we usually write this as:

import { sum } from './math';

So will the above code also work on Edge? And what about named packages? I fear we will see a lot of incompatibility here before we figure out how to make these paths work across the board.

I would hazard to guess that for most developers, System.import will remain mostly invisible in the browsers and that only the bundling software itself will start to use it (for efficiency purposes) when it becomes mainstream.

Stijn de Witt
  • 40,192
  • 13
  • 79
  • 80
  • 11
    Note that HTTP v2 means that making 1000s of small requests has only a small overhead compared to making 1 big one. Node js is also used for server side apps and scripts, tools, etc, which don't suffer from the requests issue (using 'import' would be mostly identical to using 'require' for these in terms of semantics). – TomW Mar 29 '17 at 10:33
  • @TomW And if you look at it in more detail, you will find out that actually, Node too [has](https://kev.inburke.com/kevin/node-require-is-dog-slow/) [issues](http://raspberrypi.stackexchange.com/questions/34496/node-js-and-its-require-function-is-too-slow) when you use too many small packages. For large systems comprised of hundreds of small package, the inital require tree can become so big that you get (many) seconds of startup delay. In fact some people recommend [bundling for the server side](http://jlongster.com/Backend-Apps-with-Webpack--Part-I) as well (also for HMR etc). – Stijn de Witt Mar 29 '17 at 21:35
  • 2
    @StijndeWitt, all those hundreds of requests **can be cached**. Or even serviceworker-ed. – Pacerier Apr 08 '17 at 20:13
  • 3
    @Pacerier No need to insult. There is a reason that in guidelines for progressive web apps they advice you to *inline* your critical styles and JS code in the head of the document. These requests will hurt your Time To Interactive in *the real world*. Yes those requests might be cached... then again they might not. Everyone taking perf seriously is doing their best to minimize number of requests, number of roundtrips and payload size per request. Because that's what kills performance if you don't limit it. – Stijn de Witt Apr 09 '17 at 14:02
  • 1
    First-layer inlining is needed to stop that 200 msec load time blank screen. **That's only for the initial load. Every other request do not get inlined in HTTP 2.0** since there's multiplexing. Even in HTTP 1.0, if they are service-workered, then they are **already** considered inlined. – Pacerier Aug 07 '17 at 01:15
  • I think in simple implementations, like a very simple website, it is a better option to use import than to include both scripts as script tags, for more complex scenarios I would stick with webpack – santiago arizti Apr 16 '18 at 22:28
5

Now there's a pollyfill that you can use to import ES6 module.

I tested it successfully on Chrome.

Here is the link: http://github.com/ModuleLoader/browser-es-module-loader


It is also implemented natively in Edge 14:

https://blogs.windows.com/msedgedev/2016/05/17/es6-modules-and-beyond

Supersharp
  • 29,002
  • 9
  • 92
  • 134
2

According to Google's Javascript Style Guide:

Do not use ES6 modules yet (i.e. the export and import keywords), as their semantics are not yet finalized. Note that this policy will be revisited once the semantics are fully-standard.

// Don't do this kind of thing yet:
//------ lib.js ------
export function square(x) {
    return x * x;
}
export function diag(x, y) {
    return sqrt(square(x) + square(y));
}

//------ main.js ------
import { square, diag } from 'lib';

However, import and export are implemented in many transpilers, such as the Traceur Compiler, Babel or Rollup.

Gregory R.
  • 1,815
  • 1
  • 20
  • 32