import script --> .esm
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
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 astext/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.)
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...)
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 astext/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:
-
linters need to know whether whether to apply script or module (including implicit strict) to the source files they process.
-
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.
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.
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.)
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.
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
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.
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
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
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
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.
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?
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
Some info was discussed here: esdiscuss.org/notes/2014-01-28
- Matthew Robb
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.
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.
Yeah heres a bit more in depth discussion on the topic: esdiscuss.org/topic/detecting-js-language-mode-for-tools#content-12
- Matthew Robb
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.
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
Allen Wirfs-Brock wrote:
I suggest "js2"
Nope.
Nope Nope Nope Octopus
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
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
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?
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
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.
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
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.
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
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.
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.
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 astext/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.
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?
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.
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
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.
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).
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.
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.
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
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.
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
I'd prefer the heading be Scripts and LegacyScripts. Just so happens that the module features are only available in Scripts.
- Matthew Robb
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:
- Old clients would be unaffected:
require
would not attempt to load ES6 modules. - For new clients, there is a workaround: the client can just use
require
until the package is fixed upstream. - 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.
Here's the idea, in full:
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
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
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.
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 astext/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:
linters need to know whether whether to apply script or module (including implicit strict) to the source files they process.
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.
.... 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
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.
Wrt to the proposed
default.js
convention: node doesn't need to specify a main entry point in thepackage.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?
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
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. : /
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.
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
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
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
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