import script --> .esm

# John Barton (11 years ago)

A couple of months ago I tried out the suggestion by Yehuda Katz to use import syntax with special module specifiers to mean parse-as-script, do evaluate but do not produce a module. The implementation worked well and now I want to put a version of this idea into Traceur.

As soon as I started I ran it issues with the name. Obviously "legacy:" is ambiguous. "script:" looks like a URL, which I suppose was intended, but then we get into URLs in URLs. Furthermore, the URL scheme is very cumbersome with a filesystem, you have to have some side-table or algorithm to match URLs to directories or filenames.

I implemented postfix ",script", but that sure looks like an extension. Which is exactly what the semantics are: a file with a different datatype needing different processing. So it seems to me that the most honest naming would be some thing like ".ess".

I would just implement that solution but I proposed a similar idea a while back to Traceur team I got a lot of pushback along the lines of "JS is one language". Since then several Traceur users have asked for support to a non ".js" extension for loading modules, to be able to separate existing JS code in .js files from new module code in files marked with a different extension. Within Traceur's (mostly es6) code we have resorted to implicit marking-by-directory ("All code in src/node is script, not module") or with the wonderful extension of ".module.js" to mean "all the other files are script, but this one is module". So it's JS-is-one-language with two incompatible, unmentionable dialects ;-).

Finally, naming modules as .js and ES6 Scripts as .ess has the weird result that ES5 scripts (in .js files) would be processed as ES6 modules. That seems dumb. So naming the new things, modules, with a new extension makes more sense. ".esm" seems like a obvious choice.

I know this may not seem to be the most exalted of topics for standardization but the current choice of post-pending '.js' has real consequences for developers. Please consider this issue.

jjb

# Matthew Robb (11 years ago)

Personally I have felt this way for a long time as well. I think .esm is somewhat confusing since most js developers don't really think about it as EcmaScript. I would think you could just as easily do .jsm but this also suggests that files of this alternate should be served with a different mime type such as text/javascript-module or something along those lines.

  • Matthew Robb
# Brendan Eich (11 years ago)

Matthew Robb wrote:

Personally I have felt this way for a long time as well. I think .esm is somewhat confusing since most js developers don't really think about it as EcmaScript.

(sounds like a skin disease...)

I would think you could just as easily do .jsm but this also suggests that files of this alternate should be served with a different mime type such as text/javascript-module or something along those lines.

RFC4329 rightly favors application/ -- but this is all beyond the scope of ECMA-262. Do Not Want TC39 deciding suffixes. Let developers develop conventions. (Just so long as they do not sound like skin diseases.)

# Anne van Kesteren (11 years ago)

On Wed, Sep 10, 2014 at 6:14 PM, Brendan Eich <brendan at mozilla.org> wrote:

RFC4329 rightly favors application/ -- but this is all beyond the scope of ECMA-262. Do Not Want TC39 deciding suffixes. Let developers develop conventions. (Just so long as they do not sound like skin diseases.)

Well the default browser loader which is still secret(?) purportedly standardizes on a "js" suffix. That is probably why this came up.

(I think text/javascript is just fine btw. text/* works great for HTML and CSS too. In any event, for the purposes of the browser JavaScript does not really have a MIME type. We parse anything we get...)

# Allen Wirfs-Brock (11 years ago)

On Sep 10, 2014, at 8:44 AM, Matthew Robb wrote:

Personally I have felt this way for a long time as well. I think .esm is somewhat confusing since most js developers don't really think about it as EcmaScript. I would think you could just as easily do .jsm but this also suggests that files of this alternate should be served with a different mime type such as text/javascript-module or something along those lines.

I also agree (and have argued) that an external discrimination of modules and scripts is going to be a practical necessity and that file extension is the most natural way to do so. Consider a couple basic situations:

  1. linters need to know whether whether to apply script or module (including implicit strict) to the source files they process.

  2. a command line js engine needs to know which source files listed on the command line are intended to be processed as scripts which need to be loaded as modules.

command line switches or other affordances could be used to make this discrimination. But file extensions are the more traditional approach.

But, such conventions seem to be outside the scope of ECMA-262. .js isn't something that has appeared in any standard, as far as I know.

# Matthew Robb (11 years ago)

On Wed, Sep 10, 2014 at 12:20 PM, Anne van Kesteren <annevk at annevk.nl>

wrote:

(I think text/javascript is just fine btw. text/* works great for HTML and CSS too. In any event, for the purposes of the browser JavaScript does not really have a MIME type. We parse anything we get...)

​The problem is that there are now two distinctly different types of

javascript file, some should be parsed as script and some should be parsed as module. Assuming everything is script that is not explicitly module would work but I don't see how you can accurately guess without some sort of hint that you need to parse as module.​

# Anne van Kesteren (11 years ago)

On Wed, Sep 10, 2014 at 6:23 PM, Matthew Robb <matthewwrobb at gmail.com> wrote:

The problem is that there are now two distinctly different types of javascript file, some should be parsed as script and some should be parsed as module. Assuming everything is script that is not explicitly module would work but I don't see how you can accurately guess without some sort of hint that you need to parse as module.

I suspect the mode switching will happen on the client. E.g. <script type=module> is one such proposed way. <module> (with various

unresolved XSS issues) is another.

Within the browser environment workers are another type of JavaScript environment, although we do not parse them differently at the moment. (There's a suggestion that service workers become strict by default though so we can upgrade them to be modules more easily.)

# Kevin Smith (11 years ago)

Well the default browser loader which is still secret(?) purportedly standardizes on a "js" suffix. That is probably why this came up.

My understanding is that we have backed off from automagically appending ".js" to relative paths, but that info could be old.

# Matthew Robb (11 years ago)

As soon as the language decided it would have a differentiation for modules vs scripts then it seems only natural that it should also specify at least some generic means of entry into one mode or another. Then it's up to browsers or who ever to determine what external signifiers would trigger module instead of script. Or the language parsing logic could say that in the presence of module syntax it will always be treated as module. I don't know if that's feasible or not shrug

  • Matthew Robb
# Allen Wirfs-Brock (11 years ago)

On Sep 10, 2014, at 9:28 AM, Matthew Robb wrote:

As soon as the language decided it would have a differentiation for modules vs scripts then it seems only natural that it should also specify at least some generic means of entry into one mode or another. Then it's up to browsers or who ever to determine what external signifiers would trigger module instead of script. Or the language parsing logic could say that in the presence of module syntax it will always be treated as module. I don't know if that's feasible or not shrug

Modules and scripts can not always be identified by inspection. Consider:

foo.js -------------------------------
const answer = 42;
---------------------------------------

The semantics of this are quite different depending upon whether foo.js is evaluated as a script or loaded as a module.

# Axel Rauschmayer (11 years ago)

Modules and scripts can not always be identified by inspection. Consider:

foo.js ------------------------------- const answer = 42;

The semantics of this are quite different depending upon whether foo.js is evaluated as a script or loaded as a module.

Given that module files and script files have different semantics, I would definitely want different file endings for them – for both humans and machines. 1JS doesn’t apply here.

Axel

# John Barton (11 years ago)

On Wed, Sep 10, 2014 at 9:35 AM, Allen Wirfs-Brock <allen at wirfs-brock.com>

wrote:

On Sep 10, 2014, at 9:28 AM, Matthew Robb wrote:

As soon as the language decided it would have a differentiation for modules vs scripts then it seems only natural that it should also specify at least some generic means of entry into one mode or another. Then it's up to browsers or who ever to determine what external signifiers would trigger module instead of script. Or the language parsing logic could say that in the presence of module syntax it will always be treated as module. I don't know if that's feasible or not shrug

Modules and scripts can not always be identified by inspection. Consider:

foo.js ------------------------------- const answer = 42;

The semantics of this are quite different depending upon whether foo.js is evaluated as a script or loaded as a module.

This case is clearly as script, as a module it has no effect right? Isn't the only ambiguous case would be explicit global manipulation, where we could decide module is used and (most of the time ;-) win.

jjb

# Matthew Robb (11 years ago)

Alternatively you could argue that some of the hooks in Loader shouldn't be in the language spec because they should likely exist outside of something that is hyper-specifically a module loader. So if the web has a resource loader construct similar to ES6 Loader and it would handle resolving paths and it would handle fetching etc then the ES6 Loader needs to be concerned with much less.

If .js is not in any ES spec then why was there ever the idea of auto appending it to modules? I feel like this whole region of concerns is a bit mixed up right now.

  • Matthew Robb
# Todd Kennedy (11 years ago)

On Sep 10, 2014, at 12:23, Matthew Robb <matthewwrobb at gmail.com> wrote:

On Wed, Sep 10, 2014 at 12:20 PM, Anne van Kesteren <annevk at annevk.nl> wrote:

(I think text/javascript is just fine btw. text/* works great for HTML and CSS too. In any event, for the purposes of the browser JavaScript does not really have a MIME type. We parse anything we get...) ​The problem is that there are now two distinctly different types of javascript file, some should be parsed as script and some should be parsed as module. Assuming

This is just another part of the modules system that really makes no sense when you step back from it. We are really, like REALLY, going to make people decide of they're writing a "script" or a "module" (both being just javascript, with just some semantic concept being different) and we are going to load and name them separately?

In what other languages has this been a good idea?

Why the semantic difference between a "module" of javascript and a "script" of javascript.

# Todd Kennedy (11 years ago)

On Sep 10, 2014, at 12:35, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:

On Sep 10, 2014, at 9:28 AM, Matthew Robb wrote:

As soon as the language decided it would have a differentiation for modules vs scripts then it seems only natural that it should also specify at least some generic means of entry into one mode or another. Then it's up to browsers or who ever to determine what external signifiers would trigger module instead of script. Or the language parsing logic could say that in the presence of module syntax it will always be treated as module. I don't know if that's feasible or not shrug

Modules and scripts can not always be identified by inspection. Consider:

foo.js ------------------------------- const answer = 42;

The semantics of this are quite different depending upon whether foo.js is evaluated as a script or loaded as a module.

Allen

But why?

To be completely serious. Why do we have to make a difference?

# Matthew Robb (11 years ago)

There are numerous discussions about this throughout the last two years and you can find record of them throughout es-discuss. Someone closer to the topic can likely fill you in but I won't try to pull that information off the top of my head.

  • Matthew Robb
# Matthew Robb (11 years ago)

Some info was discussed here: esdiscuss.org/notes/2014-01-28

  • Matthew Robb
# Kevin Smith (11 years ago)

But why?

To be completely serious. Why do we have to make a difference?

Because we have implicit module bodies, which have different variable-scoping and strict-mode semantics than regular scripts. The alternative would have been boilerplate in every module forever.

# Allen Wirfs-Brock (11 years ago)

On Sep 10, 2014, at 9:41 AM, John Barton wrote:

On Wed, Sep 10, 2014 at 9:35 AM, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:

On Sep 10, 2014, at 9:28 AM, Matthew Robb wrote:

As soon as the language decided it would have a differentiation for modules vs scripts then it seems only natural that it should also specify at least some generic means of entry into one mode or another. Then it's up to browsers or who ever to determine what external signifiers would trigger module instead of script. Or the language parsing logic could say that in the presence of module syntax it will always be treated as module. I don't know if that's feasible or not shrug

Modules and scripts can not always be identified by inspection. Consider:

foo.js ------------------------------- const answer = 42;

The semantics of this are quite different depending upon whether foo.js is evaluated as a script or loaded as a module.

This case is clearly as script, as a module it has no effect right? Isn't the only ambiguous case would be explicit global manipulation, where we could decide module is used and (most of the time ;-) win.

so make it:

foo.js ------------------------------- const answer = 42; bar();

now whose mind are you going to read to decide if it is intended to be a module or script.

Plus, there is the dream that over the long term, modules (including script like modules) will completely displace scripts for new code which means we would have an always "strict" world for new code.

From that perspective, if we want to informally debate file extensions to distinguish such new usage from legacy usage, I suggest "js2" as the extensions for source files that are intended to be parsed using the ES grammar Module goal symbol. This but the focus on "new style" vs "old style" rather than the subtle distinction between Script and Module.

# Matthew Robb (11 years ago)

Yeah heres a bit more in depth discussion on the topic: esdiscuss.org/topic/detecting-js-language-mode-for-tools#content-12

  • Matthew Robb
# Guy Bedford (11 years ago)

The question of whether a file is a module or script is the same problem as to whether a module is ES6 or AMD or CommonJS.

Moving it to the extension makes as much sense as having every CommonJS module written as script.cjs.

We know that we need outside metadata to work out how to interpret modules, and that the loader will have meta-configuration injection at some level, not determined by TC39.

In NodeJS, this can be through package.json properties which inform what module format the package is. In the browser, this could be a header, or part of package configuration.

John, in your case specifically, it would be good to get more background to understand what type of meta process is most suitable.

# Matthew Robb (11 years ago)

So my thought based on this comment: esdiscuss.org/topic/detecting-js-language-mode-for-tools#content-14

Why not deprecate sloppy-script mode explicitly and encourage the movement to module-strict for all scripts moving forward. Once you do that then you can make the decision to spec the legacy code path as separate from the modern code path. Then implementors would already be adhering to the legacy code path for existing stuff and a convention would need to be decided upon (somewhere) for differentiating the from the new.

I would go so far as to suggest the file extension .es to denote this and at some point a different mime-type probably. So files with .es extension or that contain module syntax of any kind would be treated as modules and anything not conforming to that would be treated like a sloppy script... Including files imported from modules that don't meet either of those requirements.

  • Matthew Robb
# Brendan Eich (11 years ago)

Allen Wirfs-Brock wrote:

I suggest "js2"

Nope.

Nope Nope Nope Octopus

# John Barton (11 years ago)

On Wed, Sep 10, 2014 at 10:07 AM, Guy Bedford <guybedford at gmail.com> wrote:

The question of whether a file is a module or script is the same problem as to whether a module is ES6 or AMD or CommonJS.

Moving it to the extension makes as much sense as having every CommonJS module written as script.cjs.

I don't think these are the same problem. Existing JS, AMD and CommonJS can be parsed by the same parser, the ES6 Script parser. They can't be parsed by the ES6 Module parser. It is a problem, just not the same as this one.

We know that we need outside metadata to work out how to interpret modules, and that the loader will have meta-configuration injection at some level, not determined by TC39.

One of the purposes of having modules in ES was to unify the module work in mode and browser. Having two or more incompatible meta-data solutions to this simple problem will defeat that goal.

In NodeJS, this can be through package.json properties which inform what module format the package is. In the browser, this could be a header, or part of package configuration.

John, in your case specifically, it would be good to get more background to understand what type of meta process is most suitable.

What more can I say? Some files need to be parsed as Script and some as Module. Sometimes they are in the same project and sometimes in the same directory. They work on browser and node.

jjb

# Matthew Robb (11 years ago)

Well it sounds like in lieu of .js2 we will need .js-a and .js-b and will need to explain this to new developers. It would be easier to explain the world as it should be and then explain the legacy path as what it is... Legacy and should be ignored as much as possible.

  • Matthew Robb
# Brendan Eich (11 years ago)

Boil the ocean schemes never work, especially not on the Web. Indeed Allen's use of "dream" to describe the hope that in the far future everything is module code is not unfair. Dreams do come true, but only incrementally where there's local advantage.

Saw your followup to my Nope-topus post. You wrote "Legacy and should be ignored as much as possible." Good luck with that, I don't see how it flies. Is everyone going to switch to Traceur quickly or even slowly?

# Matthew Robb (11 years ago)

I think the following section should change: people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-language-scripts-and-modules

Rather than presenting two separate but equal things here it should be instead describe the ideal and as an addition reference the legacy.

  • Matthew Robb
# Kevin Smith (11 years ago)

In NodeJS, this can be through package.json properties which inform what module format the package is.

Right - although having a runtime system looking at json config files is a terrible idea. : ) In es6now, I'm experimenting with the following rule:

  • If some folder that might be a "package" contains a "default.js" file, then load it as an ES6 module/package.
  • Otherwise, use the old-school algorithm (package.json or index.js).

In any case, it makes sense (when possible) to make the module vs. script decision at package boundaries.

# Matthew Robb (11 years ago)

I don't see why they have to? Traceur should be used as a build time tool that ultimately runs in legacy mode. Only REAL modern ES6 module implementations would run in this other world. Basically .es files today would be transpiled into .js files.

  • Matthew Robb
# Brendan Eich (11 years ago)

Matthew Robb wrote:

I don't see why they have to? Traceur should be used as a build time tool that ultimately runs in legacy mode. Only REAL modern ES6 module implementations would run in this other world. Basically .es files today would be transpiled into .js files.

I doubt people will do any such thing. We can have more suffixes (I was against .js2 in particular -- that particularly confusing proposal was why I unleashed the Nope-topus), but if people can adapt their existing practices with AMD/Require/CommonJS modules and use just .js, I bet they will.

Tools will have to read metadata, tea-leaves, and etheric winds to keep up. Same as ever.

# Matthew Robb (11 years ago)

I just think the idea of 1JS has already been compromised and really what we have is a spec that supports two almost-entirely different sets of expectations. The maintenance of keeping them of equal priority seems like it will only get worse over time. The "use strict" pragma is already sort of an opt-in to the new mode. To me the more graceful path forward is the one where the world as people know it stays the same but then there is an opt-in path for moving to the supersets of the future. Dong this once after having considered many of the issues of the old model seems reasonable to me specially with the amount of buy in people are doing on transpilers and even buy in on other languages/runtimes such as dart.

  • Matthew Robb
# Allen Wirfs-Brock (11 years ago)

On Sep 10, 2014, at 10:33 AM, Brendan Eich wrote:

Tools will have to read metadata, tea-leaves, and etheric winds to keep up. Same as ever.

And humans. When scanning a big directly of "js" files it's going to be real useful for code readers to be able to quickly identify what they are reading for each file.

# Guy Bedford (11 years ago)

On 10 September 2014 19:23, Kevin Smith <zenparsing at gmail.com> wrote:

In NodeJS, this can be through package.json properties which inform what module format the package is.

Right - although having a runtime system looking at json config files is a terrible idea. : ) In es6now, I'm experimenting with the following rule:

Why would it be a terrible idea to read the package.json as part of a server-based import mechanism?

  • If some folder that might be a "package" contains a "default.js" file, then load it as an ES6 module/package.
  • Otherwise, use the old-school algorithm (package.json or index.js).

Interesting idea, but there may be backwards-compatibility issues.

In any case, it makes sense (when possible) to make the module vs. script decision at package boundaries.

It certainly helps.

# L2L 2L (11 years ago)

E-S4L N-S4L

On Sep 10, 2014, at 12:14 PM, "Brendan Eich" <brendan at mozilla.org> wrote:

Matthew Robb wrote:

Personally I have felt this way for a long time as well. I think .esm is somewhat confusing since most js developers don't really think about it as EcmaScript.

(sounds like a skin disease...)

I have to comment on this... I have read the fact that you felt like this about the name ES, but reading your words exactly expression this, is another thing.

I would think you could just as easily do .jsm but this also suggests that files of this alternate should be served with a different mime type such as text/javascript-module or something along those lines.

RFC4329 rightly favors application/ -- but this is all beyond the scope of ECMA-262. Do Not Want TC39 deciding suffixes. Let developers develop conventions. (Just so long as they do not sound like skin diseases.)

Or easily be em--ECMAScript-Module-- and the same for jm

Someone need to set a convention...

I on the other hand will be using esm extension, cause I favorite the spec name more.

The name JavaScript is the language the program is in the browser to me.

# Guy Bedford (11 years ago)

On 10 September 2014 19:18, John Barton <johnjbarton at google.com> wrote:

On Wed, Sep 10, 2014 at 10:07 AM, Guy Bedford <guybedford at gmail.com> wrote:

The question of whether a file is a module or script is the same problem as to whether a module is ES6 or AMD or CommonJS.

Moving it to the extension makes as much sense as having every CommonJS module written as script.cjs.

I don't think these are the same problem. Existing JS, AMD and CommonJS can be parsed by the same parser, the ES6 Script parser. They can't be parsed by the ES6 Module parser. It is a problem, just not the same as this one.

We know that we need outside metadata to work out how to interpret modules, and that the loader will have meta-configuration injection at some level, not determined by TC39.

One of the purposes of having modules in ES was to unify the module work in mode and browser. Having two or more incompatible meta-data solutions to this simple problem will defeat that goal.

Yes - we need to use meta-data solutions that can be cross-compatible.

In NodeJS, this can be through package.json properties which inform what module format the package is. In the browser, this could be a header, or part of package configuration.

John, in your case specifically, it would be good to get more background to understand what type of meta process is most suitable.

What more can I say? Some files need to be parsed as Script and some as Module. Sometimes they are in the same project and sometimes in the same directory. They work on browser and node.

For Traceur, the default interpretation is as Module, so it sounds like you want a way to indicate files which break this rule and need to be interpreted as Script?

Can you give an example of a type of file this would apply to?

# Rick Waldron (11 years ago)

On Wed, Sep 10, 2014 at 10:40 AM, Matthew Robb <matthewwrobb at gmail.com>

wrote:

I just think the idea of 1JS has already been compromised and really what we have is a spec that supports two almost-entirely different sets of expectations. The maintenance of keeping them of equal priority seems like it will only get worse over time. The "use strict" pragma is already sort of an opt-in to the new mode.

Only in non-strict Script ( people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-language-scripts-and-modules) sense. Modules ( people.mozilla.org/~jorendorff/es6-draft.html#sec-modules) are strict-by-default.

To me the more graceful path forward is the one where the world as people know it stays the same but then there is an opt-in path for moving to the supersets of the future.

Unnecessary when nothing about the future directly changes the extant works of the past.

# Matthew Robb (11 years ago)

But if the goal is for everything going forward to use the scope environment characteristics of modules (strict-mode and local-global) then why not specify that and move the old model to a legacy mode. This just shifts all existing implementations to be compliant with legacy mode but not yet compliant with the new mode. This should be fine it's mostly about how to view and focus efforts when writing the spec, adding features, using new features, and teaching the language.

  • Matthew Robb
# Brendan Eich (11 years ago)

Rick Waldron wrote:

On Wed, Sep 10, 2014 at 10:40 AM, Matthew Robb <matthewwrobb at gmail.com <mailto:matthewwrobb at gmail.com>> wrote:

I just think the idea of 1JS has already been compromised and
really what we have is a spec that supports two almost-entirely
different sets of expectations. The maintenance of keeping them of
equal priority seems like it will only get worse over time. The
`"use strict"` pragma is already sort of an opt-in to the new mode.

Only in non-strict Script (people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-language-scripts-and-modules, people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-language-scripts-and-modules) sense. Modules (people.mozilla.org/~jorendorff/es6-draft.html#sec-modules, people.mozilla.org/~jorendorff/es6-draft.html#sec-modules) are strict-by-default.

Right. 1JS has not been compromised, and it never meant there wouldn't be new syntax with new semantics.

Matthew, if you want to use this kind of language, apply it to ES5 with its "use strict"; prologue directive. The directive is a useless expression in old browsers, and yet runtime semantics change in new.

No opt-in versioning, syntax is its own opt-in, was the 1JS insight. It predated modules as only expressed via out-of-line (in a file, or an archive member) bodies. This led to the current dilemma: new suffix or metadata?

In no case is 1JS compromised in favor of version opt-in to use new syntax. Otherwise we are off to the <script type=application/ecmascript;version=2015> race.

# John Barton (11 years ago)

On Wed, Sep 10, 2014 at 11:02 AM, Guy Bedford <guybedford at gmail.com> wrote:

On 10 September 2014 19:18, John Barton <johnjbarton at google.com> wrote:

In NodeJS, this can be through package.json properties which inform what module format the package is. In the browser, this could be a header, or part of package configuration.

John, in your case specifically, it would be good to get more background to understand what type of meta process is most suitable.

What more can I say? Some files need to be parsed as Script and some as Module. Sometimes they are in the same project and sometimes in the same directory. They work on browser and node.

For Traceur, the default interpretation is as Module, so it sounds like you want a way to indicate files which break this rule and need to be interpreted as Script?

Can you give an example of a type of file this would apply to?

Every file in test/ that does not end in module.js (and by extrapolation every file in every existing test suite based on mocha, jasmine etc). Every file in src/node/ (and by extrapolation every pre-es6 node file).

# Brendan Eich (11 years ago)

Matthew Robb wrote:

But if the goal is for everything going forward to use the scope environment characteristics of modules (strict-mode and local-global) then why not specify that and move the old model to a legacy mode.

What "old model"? There's one spec. We are not forking specs. Engines are not forking into two VMs.

# L2L 2L (11 years ago)

E-S4L N-S4L

On Sep 10, 2014, at 2:13 PM, "Matthew Robb" <matthewwrobb at gmail.com> wrote:

But if the goal is for everything going forward to use the scope environment characteristics of modules (strict-mode and local-global) then why not specify that and move the old model to a legacy mode. This just shifts all existing implementations to be compliant with legacy mode but not yet compliant with the new mode. This should be fine it's mostly about how to view and focus efforts when writing the spec, adding features, using new features, and teaching the language.

  • Matthew Robb

On Wed, Sep 10, 2014 at 2:05 PM, Rick Waldron <waldron.rick at gmail.com> wrote:

On Wed, Sep 10, 2014 at 10:40 AM, Matthew Robb <matthewwrobb at gmail.com> wrote: I just think the idea of 1JS has already been compromised and really what we have is a spec that supports two almost-entirely different sets of expectations. The maintenance of keeping them of equal priority seems like it will only get worse over time. The "use strict" pragma is already sort of an opt-in to the new mode.

Only in non-strict Script (people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-language-scripts-and-modules) sense. Modules (people.mozilla.org/~jorendorff/es6-draft.html#sec-modules) are strict-by-default.

To me the more graceful path forward is the one where the world as people know it stays the same but then there is an opt-in path for moving to the supersets of the future.

Yes!... If your saying do something similar as " use strict"; for module. Like "use module"; than yes I agree with this.

# Matthew Robb (11 years ago)

I don't think it should have anything to do with modules though. It's a fundamental change in the scoping/execution mechanics of any new script compiled into a running environment. Previously new code compiled and run would execute with global scope and sloppy mode. My suggestion is a pragma you COULD put at the top of script and if present that script will be compiled and run in the environment using the new scoping/execution mechanics of implicit strict mode and local-global scoping. Then the spec would simply state that modules are not compatible with the legacy mode and implementations should position the new mode as default some how. (file extension or what have you)

  • Matthew Robb
# Guy Bedford (11 years ago)

But within that you would also need a distinction of CommonJS or global as well?

One way might be to set up configuration to know which module names are of which format:

System.metadata['test/*'] = {
  format: 'global'
};

System.metadata['src/node/*'] = {
  format: 'cjs'
}

Of course this mechanism doesn't exist by default - but you can create it easily with the loader hooks in just a few lines.

# Matthew Robb (11 years ago)

I don't see how this is not forking: people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-language-scripts-and-modules

There are now two distinctly different models and yes they both work in the same VM simultaneously but that's not what authors would care about. Personally I want to be able to know at all times that a file I am looking at is a script or a module without using tools to assume one or the other.

The problem with the link above is that A) It associates this new local-global-scoping/implicit-strict-mode with modules rather than generically and B) Neither mode is specified as of higher importance which results in exactly a forked paradigm.

  • Matthew Robb
# Matthew Robb (11 years ago)

I'd prefer the heading be Scripts and LegacyScripts. Just so happens that the module features are only available in Scripts.

  • Matthew Robb
# Kevin Smith (11 years ago)

Why would it be a terrible idea to read the package.json as part of a server-based import mechanism?

Architecturally, it should be possible to write self-describing programs. Configuration files are good for tools (e.g. package managers and compilers) and application settings.

Node currently uses "package.json" to find the module entry point: the so-called "main" module. But with ES6 modules this is unnecessary. We can simply have a "default.js" file at the folder root which looks like this:

export * from "./lib/my-entry-point.js";

This accomplishes the same thing without having to parse JSON.

Also, we want to avoid having an explicit opt-in to the new module system. Nobody wants to have to do this:

{
    es6module: true
}
  • If some folder that might be a "package" contains a "default.js" file, then load it as an ES6 module/package.
  • Otherwise, use the old-school algorithm (package.json or index.js).

Interesting idea, but there may be backwards-compatibility issues.

If a legacy package has a "default.js" file at it's root, then it will be loaded as an ES6 module, causing an error. But:

  1. Old clients would be unaffected: require would not attempt to load ES6 modules.
  2. For new clients, there is a workaround: the client can just use require until the package is fixed upstream.
  3. I did some scanning of NPM packages and it appears quite difficult to find packages with "default.js" at their root. I think I looked at the top 500 packages and didn't find any instances, although I need to re-check that.
# Kevin Smith (11 years ago)
# John Barton (11 years ago)

On Wed, Sep 10, 2014 at 10:33 AM, Brendan Eich <brendan at mozilla.org> wrote:

Matthew Robb wrote:

I don't see why they have to? Traceur should be used as a build time tool that ultimately runs in legacy mode. Only REAL modern ES6 module implementations would run in this other world. Basically .es files today would be transpiled into .js files.

I doubt people will do any such thing. We can have more suffixes (I was against .js2 in particular -- that particularly confusing proposal was why I unleashed the Nope-topus), but if people can adapt their existing practices with AMD/Require/CommonJS modules and use just .js, I bet they will.

I was reporting on the problems in practice. I don't believe any of the problems with module vs script are specific to Traceur. This is not equivalent to the AMD/CommonJS problem. The AMD community agreed on a format and a function call; similarly commonjs. In the ES case, we have one syntax, import, with two meanings depending on an non-standard string interpretation.

Tools will have to read metadata, tea-leaves, and etheric winds to keep up. Same as ever.

This discussion is about the import statement and Loader.import(), not tools.

Ultimately TC39 needs to draw a line: what is ES and what belongs elsewhere. Overall Loader does a good job of drawing that line. But one area I think it has missed is related to module specifiers, given the reality that input source comes from individually named locations. Leaving this detail of module specifiers undefined just makes ES6 harder to adopt, its not very hard to fix compared to many complex problems solved already and I don't see how it has a big downside to fix.

jjb

# John Barton (11 years ago)

On Wed, Sep 10, 2014 at 11:28 AM, Guy Bedford <guybedford at gmail.com> wrote:

But within that you would also need a distinction of CommonJS or global as well?

One way might be to set up configuration to know which module names are of which format:

System.metadata['test/*'] = {
  format: 'global'
};

System.metadata['src/node/*'] = {
  format: 'cjs'
}

The property of "which parser is appropriate" applies to a file, rather than a directory. Thus I could imagine:

System.metadata['\.js$'] = {
  format: 'module'
};
System.metadata['\.jsm$'] = {
  format: 'global'
};

This strategy would allow module loaders to paper over the differences created by not having a standard extension.

Of course this mechanism doesn't exist by default - but you can create it easily with the loader hooks in just a few lines.

This is equally true for many features added to ES6.

jjb

# Guy Bedford (11 years ago)

I think the point I was trying to originally make was that if you want to take full advantage of the loader, you don't want to, in the long run, treat CommonJS as a global script, running the NodeJS loader and System loader both side-by-side, you want to be able to unify on a single loader.

When you load CommonJS through the loader, your problem of module or global becomes one of CommonJS or ES6 module in the scenarios you are looking at.

# Mark S. Miller (11 years ago)

On Wed, Sep 10, 2014 at 9:21 AM, Allen Wirfs-Brock <allen at wirfs-brock.com>

wrote:

On Sep 10, 2014, at 8:44 AM, Matthew Robb wrote:

Personally I have felt this way for a long time as well. I think .esm is somewhat confusing since most js developers don't really think about it as EcmaScript. I would think you could just as easily do .jsm but this also suggests that files of this alternate should be served with a different mime type such as text/javascript-module or something along those lines.

I also agree (and have argued) that an external discrimination of modules and scripts is going to be a practical necessity and that file extension is the most natural way to do so. Consider a couple basic situations:

  1. linters need to know whether whether to apply script or module (including implicit strict) to the source files they process.

  2. a command line js engine needs to know which source files listed on the command line are intended to be processed as scripts which need to be loaded as modules.

command line switches or other affordances could be used to make this discrimination. But file extensions are the more traditional approach.

But, such conventions seem to be outside the scope of ECMA-262.

Since it isn't in any else's scope, I propose it be in our's.

TC39 has other advisory outlets other than the 262 spec, such as < conventions:conventions>. If there

are no objections to recommending .js vs .jsm in this informal way, I propose that we place it there. With < conventions:no_non_standard_strict_decls>,

we successfully got agreement across all implementations of something we (accidentally?) omitted from the ES5 spec -- in time to make lexically scoped functions possible in ES6/strict.

If we also come to an informal consensus about mime type, we could also record it in this namespace. Or not.

# L2L 2L (11 years ago)

.... So... Your saying bring environmental scope to the script file... As having it's own context execution... Like each script tag is its own iframe or DOM environment, while in the same html page?

E-S4L N

# C. Scott Ananian (11 years ago)

For what it's worth, node already deals with 'modules' versus 'plain scripts'. The latter typically start with #! and are found in a bin subdirectory. In case of ambiguity you can add /* jshint ... */ directives as necessary to select the appropriate language mode. I don't see this as a big deal, although I wouldn't object to .jsm being standardized.

Wrt to the proposed default.js convention: node doesn't need to specify a main entry point in the package.json. It could have chosen an arbitrary convention. Overriding the entry point allows for extra flexibility in practice, especially when adapting to legacy projects' existing directory structures.

# Kevin Smith (11 years ago)

Wrt to the proposed default.js convention: node doesn't need to specify a main entry point in the package.json. It could have chosen an arbitrary convention.

Clearly, and it already did: "index.js". My (perhaps imperfect) understanding of history is that support for the "main" configuration setting arose out of a desire to support CommonJS's "package.json" format (which defined such a field).

Overriding the entry point allows for extra flexibility in practice, especially when adapting to legacy projects' existing directory structures.

I don't follow. Can you expand on this? How is using "main" any better than adding a "default.js" which simply re-exports the desired entry point?

# Yehuda Katz (11 years ago)

There's a difference between "ZOMG WORKING IN SECRET" and talking to people and working on something privately that is still being fleshed out.

Not every document on my laptop (or yours) is sufficiently ready for public consumption for me to put it on Github, even though I put many documents, in various levels of completion, on Github. Using a term like "secret" to refer to in-progress work is unnecessary inflammatory.

Yehuda Katz (ph) 718.877.1325

# Kevin Smith (11 years ago)

There's a difference between "ZOMG WORKING IN SECRET" and talking to people and working on something privately that is still being fleshed out.

Hmmm... In many other circles "talking to people and working on something" doesn't entail working in private. I've witnessed a repeated unwillingness to engage es-discuss or the broader community on some topics over the last year or two. Sorry to have to put it that way, and no disrespect, but that's how it is. : /

# Yehuda Katz (11 years ago)

On Thu, Sep 11, 2014 at 12:02 AM, Kevin Smith <zenparsing at gmail.com> wrote:

There's a difference between "ZOMG WORKING IN SECRET" and talking to

people and working on something privately that is still being fleshed out.

Hmmm... In many other circles "talking to people and working on something" doesn't entail working in private. I've witnessed a repeated unwillingness to engage es-discuss or the broader community on some topics over the last year or two. Sorry to have to put it that way, and no disrespect, but that's how it is. : /

If you're talking about modules, I hardly think that creating a reasonable fidelity transpiler in public, personally using it in my own (somewhat popular) open source projects, and working with the wider open source community qualifies as an unwillingness to engage.

Indeed, the vast majority of the changes to the module syntax over the past year have come from direct feedback from community members who were attempting to use the transpiler, and other community members who have built polyfills of other parts of the system.

If you're talking about long, endless threads on es-discuss mostly rehashing the same topics over and over again, largely by people without usage experience, I would suggest that "es-discuss" is not the equivalent of "the broader community". (which is not to say that feedback from es-discuss is ignored, just that there reaches a point where the salient points have already been made and are simply being rehashed).

Different people work in different ways. Personally, I try to give people working on standards the benefit of the doubt, especially at early stages when spec champions are still largely gathering feedback from people. You may find it useful to present drafts of ongoing work while still deep in the information gathering phase, but not everyone works that way. A bit of empathy would go a long way here.

# Jussi Kalliokoski (11 years ago)

On Thu, Sep 11, 2014 at 12:56 AM, Mark S. Miller <erights at google.com> wrote:

If there are no objections to recommending .js vs .jsm in this informal way, I propose that we place it there.

FWIW, .jsm extension is currently used as a convention in XUL for denoting "JavaScript modules" (not the same thing as ES6 modules): developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Using

For other associations of the .jsm extension, see filext.com/file-extension/JSM

# John Barton (11 years ago)

I work on Traceur's loader and participate in the loader discussions on es-discuss. I find the lack of engagement by the developers of the loader disheartening. The long, painful, sometimes contentious discussions about classes yielded an outstanding design that works well. Is the loader on track for similar success? We have no idea.

jjb

# Brendan Eich (11 years ago)

John Barton wrote:

The long, painful, sometimes contentious discussions about classes yielded an outstanding design that works well.

In no sense were ES6 classes designed by es-discuss draw-out contentious painful committee.

If you meant by "yielded" "reviewed the design after champions had gathered requirements and mapped out possible solutions", then ok