archives

« Bugzilla Issues Index

#3294 — Mixed declarative and dynamic linking no longer supported


In the previous module loader implementation, significant effort was put into enabling ES6 to load legacy modules, which could in turn load ES6.

This is an important feature as it allows ES6 interop with CommonJS inside an ecosystem like npm. We can't automate conversion of modules to ES6 as circular references in CommonJS will break, so there isn't another way around this interop scenario that I can see.

One other proposal currently being suggested by some to enable this is the ability to write ES6 and CommonJS together using a CommonJS require for CommonJS and ES6 syntax for ES6:

require('cjs-module');
import 'es6-module';

I find this idea incredibly worrying, because there is no way to progressively move out of this scenario without rewriting all dependencies. We collectively progress into a hole where we're using two module systems, which I believe will leave everyone worse off.

Perhaps it is out of the scope of ES6 to consider the dynamics of progressive adoption at this level, in which case I concede, but the solution previously provided separating the legacy and ES6 layers and linking these layers alternately supporting circular references in both systems together, through the dynamic instantiation hook, was an incredibly general and elegant solution to this issue.

I'd ask that we consider bringing this back through a more general HostGetSource hook (HostGetModule perhaps) that supports the previous dynamic instantiate hook properties (deps and execute).


There may be a middle ground here by allowing loading CommonJS from ES6 but not vice-versa. This is effectively supported by the current HostGetSource implementation anyway.

While not perfect, compiling ES6 to CommonJS is generally less error-prone than the reverse (circular references don't break as easily) so that we do allow legacy compilation scenarios when using ES6:

npm package:
es6/app.js
cjs/app.js

Where cjs/app.js is generated from es6/app.js.

In this way, one can add an ES6 loader to Node, which would load from the es6 sources, in turn potentially loading CJS, while the package still supports being loaded without an ES6 loader through the CJS sources. But we do have to keep this compiled CJS folder around in npm for a little longer, which the reverse interop support scenario of allowing loading ES6 from CommonJS through an ES6 loader might help us progress past sooner.


fixed in rev34 editor's draft


fixed in rev34