Skip to content

Instantly share code, notes, and snippets.

@caridy
Last active August 29, 2015 14:02
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save caridy/eefb9b104874465d4e1c to your computer and use it in GitHub Desktop.
Save caridy/eefb9b104874465d4e1c to your computer and use it in GitHub Desktop.

1. ModuleImport syntax <ImportDeclaration>

Should we kill the ModuleImport syntax?

module foo from "foo"; // drop this
import bar from "bar";

Pros:

  • module keyword is very confusing (e.g.: is this a definition of a new module? what is the from part?, etc.)
  • Removing ModuleImport will simplify the import/export syntax.

Cons:

  • without a way to access the module object, it is difficult to deal with modules with many exports (e.g.: underscore), but we could fix this by using a reflective API to access imported modules

Resolution:

  • let's kill it.
  • let's use an imperative syntax to access the module object (see 3rd bullet for more details)
  • @ericf will open the tickets to update the specs

(https://people.mozilla.org/~jorendorff/es6-draft.html#sec-imports)

2. What's the execution context for a module?

// this !== realm.global?
// this !== Reflect.global?
// this === <ModuleMeta>?
// this === Object.create(null) per module?
export function foo() {};

// potential confusing side effect: `this.exports.foo()`???

Pros:

  • this.something will not define global variables
  • this.something will not be shared between modules

Cons:

  • how to access realm.global from within the module?

Resolution:

  • let's change it.
  • Reflect.global will be the way to access the global scope
  • this === Object.create(null) can be created by loader, this object will provide this.module amoung other members. (see 3rd bullet for more details)
  • @ericf will open the tickets to update the specs

3. lazy loading modules

3.1 module = moduleMeta

updated: this proposal was dropped in favor of 3.2

module keyword points to the module meta (a la nodejs)

index.html

<script>
System.import('app');
</script>

app.js

export function init() {
  // critical initialization steps
  // ...
  module.import('./lazy-mod').then(m => { 
    // then, do less important things...
  });
};

In this example, module.import() is sugar to normalize the module name based on the host module metadata.

Pros:

  • module.import() is similar to System.import()
  • it is ergonomic
  • prevents loader leaks since loader instance is not accesible from the module code
  • module.name and module.address are available

Cons:

  • metamodule api has to be defined (whitelist/getters for loader records)
  • import method have to be attached to the metamodule per module (since it wraps the normalization for relative modules).
  • module.exports, a la nodejs, but immutable. Is this even an issue?
  • module happens thru some magic under the hood (nodejs does this by executing a function and passing arguments to it)

Resolution:

  • introducing a magical module variable is not desirable, instead we will stick to this, which is described in 3.2.

3.2 @wycats proposal this = moduleMeta

Similar to 3.1 but using this instead of module.

index.html

<script>
System.import('app');
</script>

app.js

let moduleMeta = this; // or Reflect.Loader.getModuleMeta(this);
export function init() {
  // critical initialization steps
  moduleMeta.import('./lazy-mod').then(m => {
    // then, do less important things...
  };
};

Pros:

  • prevents loader leaks since no loader is accesible from the module code
  • this.name and this.address available after normalization and location
  • seems to be easy to implement (no many changes in the specs are needed)

Cons:

  • this.import() might throw people off by thinking that this === System
  • metamodule api has to be defined (whitelist/getters for loader records)
  • import method have to be attached to the metamodule per module (since it wraps the normalization for relative modules).
  • potentially confusion with: this.import() vs import foo from "foo";
  • this might be confusing. footgun, imagine people trying this.import() within a function.

Resolution:

  • this is some sort of meta module (we need a better term) that provide access to some functionalities bound to the host module, like this.import(), this.get(), etc.
  • this.module provides access to the exports
  • Reflect.Loader.getModuleMeta(this) is unnecessary.
  • @ericf will open the tickets to update the specs

(https://people.mozilla.org/~jorendorff/es6-draft.html#sec-runtime-semantics-scriptevaluation)

1. bug:2601 System.import() promise cache

System.import('foo');
System.import('foo');
  • should the second import() return a promise bound to the previous call?

2. bug:2755, bug:2795 linkSet()

TBD (@guybedford will provide more information)

3. bug:2659 System.import() normalization

  • it should normalize the name of the module to match the declarative syntax
@ghostbar
Copy link

ghostbar commented Jun 7, 2014

What about just using require like Node.js does since it has already proved it works and people likes it?

@dminkovsky
Copy link

Yeah, pretty ignorant of me but I too have been wondering this. If anyone knows the ES6 development history and why a global require wasn't chosen to be the way to do it, please post and @ me. Thank you. require() is great and lets you divide inside and out quite nicely.

@benatkin
Copy link

benatkin commented Jun 7, 2014

This is good. Those who are shaping these changes represent a sizable chunk of the people who are currently using ES6 modules so I don't see the changes as being a big problem. Hopefully after this important change, the spec will be more stable!

@caridy
Copy link
Author

caridy commented Jun 8, 2014

@ghostbar, @dminkovsky, module, global, exports, etc are just "automagic", wrapping the module execution into a function with those arguments, we don't need that magic in ES6, instead, we will use reflective APIs and this to cover the cases.

@caridy
Copy link
Author

caridy commented Jun 8, 2014

@benatkin, there were no more open issues from implements and champions as far as I can tell, we will be ironing the details early next week.

@spacepluk
Copy link

Do we really need a new meaning for this?

@calvinmetcalf
Copy link

@dminkovsky import us a reserved word saved for using here, require is not, same reason node uses exports instead of export

@jbondc
Copy link

jbondc commented Oct 23, 2014

@caridy why this.import() instead of this.require() ? this.require() doesn't lead to System.import() confusion and is familiar to the nodejs module pattern.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment