importing modules and the <script> tag

415 views
Skip to first unread message

Gil Tayar

unread,
Dec 21, 2014, 12:36:37 AM12/21/14
to traceur-comp...@googlegroups.com
All,

I have a question which is not specifically a traceur one, but more of an es6 modules one. If there is a more appropriate forum to post this, feel free to point me at it, and I will post it there.

There has been an explosion of articles about es6 modules the last month, and after all the readings and readings of links, I have found a limitation which may be problematic to our project (which uses traceur). 

The limitation is for the <script> tag. It says, a bit obliquely in most articles, that the <script> tag in browsers, once they implement es6 modules, will not support the import statement, and that the only way to import an es6 module would be inside a <module> (or <script type="module">) tag.


These references are a year old, and much has changed in module-land since then, so I would like to understand whether this is still true. If it is, the following question arises:

  1. Traceur does support this. I believe I even added the patch that allows it (https://github.com/google/traceur-compiler/issues/822). Is this an oversight?
  2. If script-s can't import, how would one write a script, used in a <script> tag that uses es6 modules?
  3. The main reason given for this limitation is the fact that <script> tag execution is synchronous. I do not understand this. True, the execution is synchronous, but the module loading could be done asynchronously. A <script> tag with an "import" statement is no different than a <script> tag using code from a <script src> preceding it. While the execution semantics are synchronous, the loading of the module could be asynchronous.
Thanks,
Gil

John J Barton

unread,
Dec 21, 2014, 11:26:11 AM12/21/14
to traceur-comp...@googlegroups.com
On Sat, Dec 20, 2014 at 9:36 PM, Gil Tayar <gi...@wix.com> wrote:
All,

I have a question which is not specifically a traceur one, but more of an es6 modules one. If there is a more appropriate forum to post this, feel free to point me at it, and I will post it there.

There has been an explosion of articles about es6 modules the last month, and after all the readings and readings of links, I have found a limitation which may be problematic to our project (which uses traceur). 

The limitation is for the <script> tag. It says, a bit obliquely in most articles, that the <script> tag in browsers, once they implement es6 modules, will not support the import statement, and that the only way to import an es6 module would be inside a <module> (or <script type="module">) tag.


The <script> tag is not specified by EcmaScript so es-discuss and the TC39 committee does not directly determine its fate.  However there is broad consensus not to support  'import' in <script> tags.  The primary motivation as I understand them are 1) a way to split the language into old pre-ES6 rules and newer post-ES6 rule and 2) a way to split script loading into old synchronous-by-default loading and new asynchronous-by-default loading.
 

These references are a year old, and much has changed in module-land since then, so I would like to understand whether this is still true. If it is, the following question arises:

  1. Traceur does support this. I believe I even added the patch that allows it (https://github.com/google/traceur-compiler/issues/822). Is this an oversight?
Traceur supports applying transpiling to the content of <script type="text/traceur">. This works and will continue to work. It's not related to anything involving es6 modules. The <script> tag allows non-JS script to be loaded and with "text/traceur" we load non-JS code and transpile it to JS. This mode of operation won't be widely used because it requires loading a compiler before executing code.
  1. If script-s can't import, how would one write a script, used in a <script> tag that uses es6 modules?
One small correction. Sadly TC39 has decided that pre-ES6 code will be called "Script" (I wished they called it "Sloppy" the term they use in correspondence). So the statement "write a script...that uses es6 modules" is not valid.  You can't use es6 modules in the thing that ES6 calls "script". In fact, that is why <script> does not support import.  Only "modules" support import.
 
There are two ways to load ES6 code with <script> tags:

  1. Dynamic import: System.import('es6-module-name.js').then(function(){ ...});

   That is, use pre-es6 "sloppy" or "script" code to call a system function that loads post-es6 or "module" code.

    This is similar to using a hypothetical <module src='es6-module-name.js'> but superior because you can take actions after the load in the then() function and because you can take actions in the script tag synchronously with the HTML. I think frameworks will use this approach.

  2. Precompile to ES3 or ES5 and include via script tag.
   I think a lot of professional sites that already compile will use this option for a long time to come.
  1. The main reason given for this limitation is the fact that <script> tag execution is synchronous. I do not understand this. True, the execution is synchronous, but the module loading could be done asynchronously. A <script> tag with an "import" statement is no different than a <script> tag using code from a <script src> preceding it. While the execution semantics are synchronous, the loading of the module could be asynchronous.
The <script> tag is synchronous with the HTML: rendering of the HTML stops when the <script> tag is encountered and does not continue until the <script> contents are loaded and executed.  And the import statement is synchronous with the compilation: execution and even semantic analysis of the code is blocked until the import completes.

I'm unsure what concerns you here. We don't need a <module> tag, but we'll probably get one. It's not a big deal.

jjb

Gil Tayar

unread,
Dec 29, 2014, 12:04:32 AM12/29/14
to traceur-comp...@googlegroups.com
John, thanks for the detailed reply.

You asked what my concern is. My concern is this - we are building a product that enables users to write HTML pages where the <script> tags (and <script src>) tags can be es6 code (this is not the main gist of the product, but only a part of it). We transparently compile the scripts into es5.

Obviously :-), we have been using traceur to compile the <script>-s. We're compiling offline, and so not using traceur's ability to compile the scripts on the fly in the browser. And it was decided to compile all <scripts>-s from es6. Just as if all script tags have a type=text/traceur added to them. It was also decided to enable import statements in those script tags. This was not difficult, as traceur includes specific support for this (it includes them inline, browserify style).

If what I read is true, then we will not be future compatible, as import statements won't be supported in script tags, but only in <module> tags.

Would you know where these decisions are (or will be) made? Is there a public mailing list, group, or forum where this is discussed?



--
You received this message because you are subscribed to the Google Groups "traceur-compiler-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to traceur-compiler-d...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Yours,
Gil Tayar
Software Architect @ Wix

John J Barton

unread,
Dec 29, 2014, 12:43:23 PM12/29/14
to traceur-comp...@googlegroups.com
You cannot be future compatible: there is no draft spec for a <module> tag or a <script> tag variant supporting import. 

The majority of the discussions about <module> and <script> have occurred on the es-discuss list. However the corresponding standards committee, TC39, has explicitly discontinued work on these subjects as outside of their charter. It seems likely that WhatWG will do this work, see https://github.com/whatwg/loader.  

I'll re-iterate that the big players in this space have low motivation to solve this issue. They use off-line compilation for web pages and that will continue no matter what standard emerges because they want compressed JS to be sent to browsers. If I were working on a product to support ES6 in browsers I would focus on producing compressed output as the only viable strategy. Then the <module> tag issues don't matter.

In terms of developer experience, the closest you can get today would be <script> tags that must appear at the end of the HTML, after any renderable tags.   That avoids blocking rendering and having pages that depend upon blocking rendering for their behavior.  These could be re-written as <module> if that ever happens.

jjb

Guy Bedford

unread,
Dec 29, 2014, 12:50:56 PM12/29/14
to traceur-comp...@googlegroups.com
I think you can be future compatible - surely the way to do this would be to have <script> tags use script mode and <script type=module> tags handle module imports, as we do?

<script type=module> is pretty well accepted at this point, as far as I'm aware, and will be the initial implementations of ES6 modules in browsers. Yes it may change naming, just as nothing is set until implementation, but it is looking very likely.
Reply all
Reply to author
Forward
0 new messages