System.import FTW

# C. Scott Ananian (11 years ago)

Can someone point me to the spec for System.import?

jorendorff/js-loaders/blob/master/browser-loader.js doesn't seem to include it.

It seems to me that it would be worthwhile to ensure that System.import had good semantics. It would allow a nice migration path for existing AMD and node-style modules. For example:

// AMD-style define!
// (Promise.map and Promise.spread would be nice here; see
//  https://github.com/cscott/prfun)
function define(deps, f) {
  return Promise.all(deps.map(d => System.import(d)))
    .then( (...args) => f(...args) )
    .then( registerModule )
}

and

// Node-style require needs more magic.
Promise.async(function*() {
  /* start module text */
  var fs = yield System.import('fs');
  // etc.
  /* end module text */
  return module.exports;
}).then( registerModule );

But that implies that System.import has well defined cycle-breaking, extensibility, etc. Could it? --scott

ps. gist.github.com/wycats/51c96e3adcdb3a68cbc3/#comment-1006744

-- ( cscott.net )

# Guy Bedford (11 years ago)

On 14 February 2014 14:13, C. Scott Ananian <ecmascript at cscott.net> wrote:

Can someone point me to the spec for System.import?

It's in the ES6 specification draft under Loader.prototype.import - people.mozilla.org/~jorendorff/es6-draft.html#sec-loader.prototype.import .

jorendorff/js-loaders/blob/master/browser-loader.js doesn't seem to include it.

It seems to me that it would be worthwhile to ensure that System.import had good semantics. It would allow a nice migration path for existing AMD and node-style modules. For example:

// AMD-style define!
// (Promise.map and Promise.spread would be nice here; see
//  https://github.com/cscott/prfun)
function define(deps, f) {
  return Promise.all(deps.map(d => System.import(d)))
    .then( (...args) => f(...args) )
    .then( registerModule )
}

This is not the recommended way to register a module - rather this is what Dynamic Instantiation is designed to handle for you, so there is no need to work out how to link the dependencies manually. See gist.github.com/dherman/7568080 or the outdated (using old syntax, but the principles remain) essay gist.github.com/wycats/51c96e3adcdb3a68cbc3 for more info.

and

// Node-style require needs more magic.
Promise.async(function*() {
  /* start module text */
  var fs = yield System.import('fs');
  // etc.
  /* end module text */
  return module.exports;
}).then( registerModule );

Again, this is solved by dynamic instantiation.

# C. Scott Ananian (11 years ago)

Thanks. I was missing the relationship between System and Loader somehow.

So System.import is intended to be exactly the same as the import keyword (except promise-returning). That's good! Is there a way to do without the export keyword as well (I've heard rumors of "anonymous exports" but haven't named to track down a spec)? If so, it seems like as ES5 shim (not a full polyfill) could enable module authors to start tying into ES6 modules without corrupting their source with new keywords.

# Erik Arvidsson (11 years ago)

On Fri Feb 14 2014 at 2:20:07 PM, C. Scott Ananian <ecmascript at cscott.net>

wrote:

Thanks. I was missing the relationship between System and Loader somehow.

So System.import is intended to be exactly the same as the import keyword (except promise-returning).

There is a big difference here. The syntax for import normalizes the name and then resolves the name relative to the current module. System.import only takes an already normalized name relative to the baseURL. So, you need to do the normalization and resolviong manually first. There was a proposal to have import do the normalizing and also take an optional referrerName. I'm afraid I don't remember what the outcome of that was.

That's good! Is there a way to do without the export keyword as well (I've heard rumors of "anonymous exports" but haven't named to track down a spec)?

There is a default export. It is just syntactic sugar over exporting and importing something with the name default.

# John Barton (11 years ago)

(There is no spec on "System", just rumors that it will be a predefined, global instance of Loader).

As far I know the only way to use the es6 module loader without exports or imports is to set values on 'this', the global object. I guess it's not very different from using IIFE (function() { this.foo = 2; })(); vs a module containing the body of the function.

# C. Scott Ananian (11 years ago)

erik: I'd be interested in learning the outcome of the normalization discussion. As one of the maintainers of es6-shim I'm particularly interested in ways to access ES6 features with ES5 syntax. If that looks like:

 this['default'] = Promise.join(System.import('foo'),
System.import('bar')).spread(function(foo, bar) {
      ....
      return { ... exports ... };
});

I can live with that. Any chance that we will accept and unwrap a promise for the exported value? (Not that it really matters for the above, since Promise.join will do recursive unwrapping, but it would be nice for compatibility if this were transparent in general.)

john: yes, I suspected that System was underspecified. That's too bad.

# David Herman (11 years ago)

On Feb 14, 2014, at 12:32 PM, C. Scott Ananian <ecmascript at cscott.net> wrote:

john: yes, I suspected that System was underspecified. That's too bad.

It's a separation of responsibilities. System is the point where the ECMAScript language (core module system) meets the host environment (filesystem/web browsers/etc). We are working towards a separate spec for the behavior of the browser's System binding, which will be a web spec, not a part of the ECMAScript spec.

# David Herman (11 years ago)

On Feb 14, 2014, at 12:09 PM, John Barton <johnjbarton at google.com> wrote:

(There is no spec on "System", just rumors that it will be a predefined, global instance of Loader).

"Rumors" is a bit much. :) The notes do show the discussion but the resolution for some reason didn't get recorded. IIRC there was agreement that Reflect and System will both be globals (this has also been the general understanding for a long time, so it's nothing new).

rwaldron/tc39-notes/blob/9ac398908394f9e2f8a1ac9b1e0c83952cd2f2fa/es6/2014-01/jan-28.md#spec

# C. Scott Ananian (11 years ago)

On Fri, Feb 14, 2014 at 12:59 PM, David Herman <dherman at mozilla.com> wrote:

rwaldron/tc39-notes/blob/9ac398908394f9e2f8a1ac9b1e0c83952cd2f2fa/es6/2014-01/jan-28.md#spec-status-update

Yeah, I read that, and I thought the absence of a 'Resolution' was a bit suspicious. I thought there was a strong argument to export only one additional global, Loader, and to make the-instance-formerly-known-as-System available via Loader.

I don't have a particular opinion here, but I will note that Java has a System class with very different semantics, so there may be some mental variable shadowing for some developers.

# John Barton (11 years ago)

I don't think the details in System will be important, as you suggest there is not much to say. The critical issue is whether we will have access to an ES6 specified Loader class. The Loader class and System.fetch is enough I think to do any custom loader thing one wants. If we only have System then our customization options will be limited since we won't be able to call super methods.