These use the module loader system in the Browser.
When a module is loaded, it has a special name that is only available within this module loader system. The special name is why import
doesn't work with modules that import
other modules using that special name, because import()
cannot assign that name.
Loading is possible with:
import
is capable of loading the module's script and setting the special name of the module. This allows other modules to access it. It is not capable ofload
orerror
events or a retry function or subresource integrity.import()
is capable of a Promise but it does not allow access to the special name of the module and does not have subresource integrity.importmap
is capable of loading module scripts, setting the special names and subresource integrity. It is not capable ofload
orerror
events or a retry function.
You can load a module script with import()
with certainty, then access it but other modules that look for it's special name must be rewritten to access it using the global namespace. Modules loaded dynamically with import()
cannot set a special name. However, there is a Promise that allows retrying with error handling.
Using import
and setting the special name: import { * as specialname } from "./modules/specialname.js";
then other modules can import
the special name. However, there are no load
or error
events or a retry function.
// this module could use module system special names to access other modules
import { func1 } from specialname1;
func1 = function() {
var o = {data_to_keep: 'asdf'};
// return the object
return o;
}
export {func1};
These use module.exports
.
module.exports = class AClass {
constructor() {
// ran on init
this.data_to_keep = 'asdf';
}
}
Raw classes are the easiest and work in the browser.
It's simply a class in the global scope.
It is easy to load into a script element that has a load
event and can be retried by using an XHR
request and Blob.URL
.
The script element can easily implement subresource integrity.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
class Rectangle {
constructor(height, width) {
// ran on init
this.height = height;
this.width = width;
}
// Getter
get area() {
return this.calcArea();
}
// Method
calcArea() {
return this.height * this.width;
}
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield
// (uses .next() as an iterator)
*getSides() {
yield this.height;
yield this.width;
yield this.height;
yield this.width;
}
}
const square = new Rectangle(10, 10);
console.log(square.area); // 100
console.log([...square.getSides()]); // [10, 10, 10, 10]
A explanation of the problem with ECMAScript/ES modules.
mrdoob/three.js#29346
importmap
could add support forload
events as it already supports subresource integrity.https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap
Regardless:
importmap
should work with events and have a retry function that can be invoked. (https://issues.chromium.org/issues/365076686)import()
should have subresource integrity (https://issues.chromium.org/issues/365076679) and already has a Promise.OrbitControls.js
should be able to access window.THREE instead of accessing a module name that is only in the module system. (mrdoob/three.js#29346 (comment))