Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

es6-module-loader

Package Overview
Dependencies
Maintainers
2
Versions
57
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

es6-module-loader - npm Package Compare versions

Comparing version 0.2.1 to 0.2.3

1420

lib/es6-module-loader.js

@@ -8,439 +8,478 @@ /*

*/
(function () {
(function (global) {
(function() {
var isBrowser = typeof window != 'undefined';
var global = isBrowser ? window : exports;
// new Loader( options ) - Module loader constructor
// The Loader constructor creates a new loader. The argument is the
// options object
//
// options.global - The loader's global object
// options.intrinsics - The loader's intrinsic methods
// options.strict - should code evaluated in the loader be in strict mode?
// options.normalize( request [, referer] ) - normalize hook
// options.resolve( normalized, { referer, metadata } ) - The URL resolution hook
// options.fetch( resolved, fulfill, reject, { normalized, referer, metadata } ) - The module loading hook
// options.translate( source, { normalized, address, metadata, type } ) - source translation hook
// options.link( source, { normalized, address, metadata, type } ) - the link hook
function Loader(options) {
// Initialization of loader state from options
// new Loader( options ) - Module loader constructor
// The Loader constructor creates a new loader. The argument is the
// options object
//
// options.global - The loader's global object
// options.intrinsics - The loader's intrinsic methods
// options.strict - should code evaluated in the loader be in strict mode?
// options.normalize( request [, referer] ) - normalize hook
// options.resolve( normalized, { referer, metadata } ) - The URL resolution hook
// options.fetch( resolved, fulfill, reject, { normalized, referer, metadata } ) - The module loading hook
// options.translate( source, { normalized, address, metadata, type } ) - source translation hook
// options.link( source, { normalized, address, metadata, type } ) - the link hook
function Loader(options) {
// the global prototype chain is:
// global instance (this._global) -> intrinsics (this._intrinsics) -> initial global (options.global = window)
// global instance is created fresh to have this chain
// also sets global.window = global for full global encapsulation
// Object.create(window) doesn't work...
var Global = function () {}
Global.prototype = options.global || window;
this._intrinsics = new Global();
// Initialization of loader state from options
// some standard intrinsics can't work through this prototype
// structure so we need to wrap them to allow this global
// abstraction layer
var wrapped = {};
var wrap = ['addEventListener', 'removeEventListener', 'getComputedStyle', 'setTimeout', 'setInterval'];
for (var i = 0; i < wrap.length; i++) (function (name) {
wrapped[name] = function () {
return window[name].apply(window, arguments);
}
})(wrap[i]);
// the global prototype chain is:
// global instance (this._global) -> intrinsics (this._intrinsics) -> initial global (options.global = window)
// global instance is created fresh to have this chain
// also sets global.window = global for full global encapsulation
// Object.create(window) doesn't work...
var Global = function () {}
Global.prototype = options.global || (isBrowser ? window : {});
this._builtins = new Global();
this.defineBuiltins(wrapped);
this.defineBuiltins(options.intrinsics && options.intrinsics._intrinsics || {});
// some standard builtins can't work through this prototype
// structure so we need to wrap them to allow this global
// abstraction layer
var wrapped = {};
var wrap = isBrowser ? ['addEventListener', 'removeEventListener', 'getComputedStyle', 'setTimeout', 'setInterval'] : [];
for (var i = 0; i < wrap.length; i++) (function (name) {
wrapped[name] = function () {
return window[name].apply(global, arguments);
}
})(wrap[i]);
Global = function () {}
Global.prototype = this._intrinsics;
this._global = new Global();
this.defineBuiltins(wrapped);
Object.defineProperty(this._global, 'window', { value: this._global });
Global = function () {}
Global.prototype = this._builtins;
this._global = new Global();
this._strict = !!options.strict;
this.normalize = options.normalize || global.System.normalize;
this.resolve = options.resolve || global.System.resolve;
this.fetch = options.fetch || global.System.fetch;
this.translate = options.translate || global.System.translate;
this.link = options.link || global.System.link;
Object.defineProperty(this._global, 'window', { value: this._global });
// The internal table of module instance objects
this._mios = {};
this._strict = !!options.strict;
this.normalize = options.normalize || global.System.normalize;
this.resolve = options.resolve || global.System.resolve;
this.fetch = options.fetch || global.System.fetch;
this.translate = options.translate || global.System.translate;
this.link = options.link || global.System.link;
// the internal table of loaded scripts
this._sloaded = {};
// modules currently loading
// key is normalized name, value is an array of callback functions to be queued (optional)
this._mloads = {};
// scripts
this._sloads = {};
}
// The internal table of module instance objects
this._mios = {};
Object.defineProperty(Loader.prototype, "global", {
configurable: true,
enumerable: true,
get: function () {
return this._global;
// the internal table of loaded scripts
this._sloaded = {};
// modules currently loading
// key is normalized name, value is an array of callback functions to be queued (optional)
this._mloads = {};
// scripts
this._sloads = {};
}
});
// Loader.prototype.load( address, callback, errback [, referer = null] )
//
// The load method takes a string representing a module URL and a
// callback that receives the result of loading, compiling, and
// executing the module at that URL. The compiled code is statically
// associated with this loader, and its URL is the given URL. The
// additional callback is used if an error occurs.
//
// load will handle import statements, but export statements are a
// syntax error
Loader.prototype.load = function (url, callback, errback) {
var self = this;
if (url instanceof Array) {
var scriptCnt = 0;
for (var i = 0; i < url.length; i++) (function (i) {
self.load(url[i], function () {
scriptCnt++;
if (scriptCnt == url.length) {
callback && callback();
}
}, errback)
})(i);
return;
}
if (this._sloaded[url]) {
callback && callback();
return;
}
Object.defineProperty(Loader.prototype, "global", {
configurable: true,
enumerable: true,
get: function () {
return this._global;
}
});
// store the callbacks in a load queue for multiple requests
if (this._sloads[url]) {
this._sloads[url].push({
callback: callback,
errback: errback
});
return;
}
else {
this._sloads[url] = [{
callback: callback,
errback: errback
}];
}
var _callback = function() {
for (var i = 0; i < self._sloads[url].length; i++)
self._sloads[url][i].callback && self._sloads[url][i].callback();
delete self._sloads[url];
}
var _errback = function(err) {
var allCalled = true;
for (var i = 0; i < self._sloads[url].length; i++) {
if (self._sloads[url][i].errback) {
self._sloads[url][i].errback(err);
// Loader.prototype.load( address, callback, errback [, referer = null] )
//
// The load method takes a string representing a module URL and a
// callback that receives the result of loading, compiling, and
// executing the module at that URL. The compiled code is statically
// associated with this loader, and its URL is the given URL. The
// additional callback is used if an error occurs.
//
// load will handle import statements, but export statements are a
// syntax error
Loader.prototype.load = function (url, callback, errback) {
var self = this;
if (url instanceof Array) {
var scriptCnt = 0;
for (var i = 0; i < url.length; i++) (function (i) {
self.load(url[i], function () {
scriptCnt++;
if (scriptCnt == url.length) {
callback && callback();
}
}, errback)
})(i);
return;
}
if (this._sloaded[url]) {
callback && callback();
return;
}
// store the callbacks in a load queue for multiple requests
if (this._sloads[url]) {
this._sloads[url].push({
callback: callback,
errback: errback
});
return;
}
else {
this._sloads[url] = [{
callback: callback,
errback: errback
}];
}
var _callback = function() {
for (var i = 0; i < self._sloads[url].length; i++)
self._sloads[url][i].callback && self._sloads[url][i].callback();
delete self._sloads[url];
}
var _errback = function(err) {
var allCalled = true;
for (var i = 0; i < self._sloads[url].length; i++) {
if (self._sloads[url][i].errback) {
self._sloads[url][i].errback(err);
}
else {
allCalled = false;
}
}
else {
allCalled = false;
}
delete self._sloads[url];
// if any didn't have an error handler, throw
if (!allCalled)
throw err;
}
delete self._sloads[url];
// if any didn't have an error handler, throw
if (!allCalled)
throw err;
}
this.fetch(url, function (source) {
this.fetch(url, function (source) {
var opt = {
address: url,
type: 'script'
};
source = self.translate(source, opt);
self._linkExecute(url, source, opt, _callback, _errback, true);
}, _errback);
};
// Loader.prototype.import( name, callback, errback, referer = null )
// Asynchronously load a module or sequence of modules by name.
Loader.prototype.import = function (name, callback, errback, referer) {
var self = this;
if (name instanceof Array) {
var modules = [];
var moduleCnt = 0;
var self = this;
for (var i = 0; i < name.length; i++) (function(i) {
self.import(name[i], function(m) {
modules[i] = m;
moduleCnt++;
if (moduleCnt == name.length) {
callback && callback.apply(null, modules);
}
}, errback, referer);
})(i);
return;
}
name = this.normalize(name, referer);
var opt = {
address: url,
type: 'script'
referer: referer,
metadata: typeof name == 'object' ? name.metadata : null
};
source = self.translate(source, opt);
// name is now the normalized name in this function
if (typeof name != 'string') {
name = name.normalized;
}
self._linkExecute(url, source, opt, _callback, _errback, true);
}, _errback);
};
if (this._mios[name]) {
return callback && callback(this._mios[name]);
}
// Loader.prototype.import( name, callback, errback, referer = null )
// Asynchronously load a module or sequence of modules by name.
Loader.prototype.import = function (name, callback, errback, referer) {
var self = this;
if (name instanceof Array) {
var modules = [];
var moduleCnt = 0;
var self = this;
for (var i = 0; i < name.length; i++) (function(i) {
self.import(name[i], function(m) {
modules[i] = m;
moduleCnt++;
if (moduleCnt == name.length) {
callback && callback.apply(null, modules);
// store the callbacks in a load queue for multiple requests
if (this._mloads[name]) {
this._mloads[name].push({
callback: callback,
errback: errback
});
return;
}
else {
this._mloads[name] = [{
callback: callback,
errback: errback
}];
}
var _callback = function(module) {
self._mios[name] = module;
for (var i = 0; i < self._mloads[name].length; i++)
self._mloads[name][i].callback && self._mloads[name][i].callback(module);
delete self._mloads[name];
}
var _errback = function(err) {
var allCalled = true;
if (!self._mloads[name])
throw err;
for (var i = 0; i < self._mloads[name].length; i++) {
if (self._mloads[name][i].errback) {
self._mloads[name][i].errback(err);
}
}, errback);
})(i);
return;
}
name = this.normalize(name, referer);
var opt = {
referer: referer,
metadata: typeof name == 'object' ? name.metadata : null
};
// name is now the normalized name in this function
if (typeof name != 'string') {
name = name.normalized;
}
if (this._mios[name]) {
return callback && callback(this._mios[name]);
}
// store the callbacks in a load queue for multiple requests
if (this._mloads[name]) {
this._mloads[name].push({
callback: callback,
errback: errback
});
return;
}
else {
this._mloads[name] = [{
callback: callback,
errback: errback
}];
}
var _callback = function(module) {
self._mios[name] = module;
for (var i = 0; i < self._mloads[name].length; i++)
self._mloads[name][i].callback && self._mloads[name][i].callback(module);
delete self._mloads[name];
}
var _errback = function(err) {
var allCalled = true;
for (var i = 0; i < self._mloads[name].length; i++) {
if (self._mloads[name][i].errback) {
self._mloads[name][i].errback(err);
else {
allCalled = false;
}
}
else {
allCalled = false;
}
delete self._mloads[name];
// if any didn't have an error handler, throw
if (!allCalled)
throw err;
}
delete self._mloads[name];
// if any didn't have an error handler, throw
if (!allCalled)
throw err;
}
var url = this.resolve(name, opt);
var url = this.resolve(name, opt);
if (typeof url != 'string') {
url = url.address;
// NB what to do with 'extra'?
}
if (typeof url != 'string') {
url = url.address;
// NB what to do with 'extra'?
}
opt.normalized = name;
opt.normalized = name;
this.fetch(url, function(source) {
opt.address = url;
opt.type = 'module';
source = self.translate(source, opt);
self._linkExecute(name, source, opt, _callback, _errback);
}, _errback, opt);
};
this.fetch(url, function(source) {
opt.address = url;
opt.type = 'module';
source = self.translate(source, opt);
self._linkExecute(name, source, opt, _callback, _errback);
}, _errback, opt);
};
// Loader.prototype.fetch
// NB spec issue here - this clashes with the instance fetch function!?
// Loader.prototype.fetch
// NB spec issue here - this clashes with the instance fetch function!?
// _linkExecute - private function
// given a normalized module name, the source, and the options metadata
// run the link and execute hooks, with the callback returning the
// defined module object
// isScript = true implies loading a script so don't define exports
var evalCnt = 0;
Loader.prototype._linkExecute = function (name, source, opt, callback, errback) {
// when no name is given,
// provide a unique name to cache the syntax tree parsing
if (!name) {
name = '__eval' + evalCnt++;
}
// _linkExecute - private function
// given a normalized module name, the source, and the options metadata
// run the link and execute hooks, with the callback returning the
// defined module object
// isScript = true implies loading a script so don't define exports
var evalCnt = 0;
Loader.prototype._linkExecute = function (name, source, opt, callback, errback) {
// when no name is given,
// provide a unique name to cache the syntax tree parsing
if (!name) {
name = '__eval' + evalCnt++;
}
var isScript = opt.type == 'script';
var isScript = opt.type == 'script';
var link = this.link(source, opt);
var link = this.link(source, opt);
// 1. module
if (link instanceof Module && !isScript) {
return callback(link);
}
// preload esprima if necessary
var self = this;
ES6Parser.loadEsprima(name, source, function() {
var imports, execute;
// 2. specified imports and execute
if (typeof link == 'object' && !isScript) {
imports = link.imports;
execute = link.execute;
// 1. module
if (link instanceof Module && !isScript) {
return callback(link);
}
// 3. undefined -> default
else
imports = ES6Parser.parseImports(name, source);
// stops an unnecessary load cascade
if (errback.called)
return;
// preload esprima if necessary
var self = this;
ES6Parser.loadEsprima(name, source, function() {
var imports, execute;
// 2. specified imports and execute
if (typeof link == 'object' && !isScript) {
imports = link.imports;
execute = link.execute;
}
// 3. undefined -> default
else {
var defaultLink = self._link(source, opt);
imports = defaultLink.imports;
execute = defaultLink.execute;
}
var _source = source;
var normalizeMap = {};
execute = execute || function() {
var exports;
// parses export statements and evaluates in the correct context
// returning the exports object
exports = ES6Parser.parseEval(_source, self, {
name: name,
normalizeMap: normalizeMap,
sourceURL: opt.address,
isEval: isScript
});
// only return exports for a module when not doing script eval
if (name && !isScript)
return new Module(exports || {});
}
// stops an unnecessary load cascade
if (errback.called)
return;
if (!imports.length)
return callback(execute.call(self));
if (!imports.length)
return callback(execute.call(self));
var deps = [];
var depCnt = 0;
for (var i = 0; i < imports.length; i++) (function(i) {
var referer = { name: name, address: opt.address };
opt.normalizeMap = {};
// run the normalization to get the canonical module name
// to allow imports to be loaded
var normalized = self.normalize(imports[i], referer);
var deps = [];
var depCnt = 0;
for (var i = 0; i < imports.length; i++) (function(i) {
var referer = { name: name, address: opt.address };
if (typeof normalized == 'object')
normalized = normalized.normalized;
// run the normalization to get the canonical module name
// to allow imports to be loaded
var normalized = self.normalize(imports[i], referer);
imports[i] = normalizeMap[imports[i]] = normalized;
if (typeof normalized == 'object')
normalized = normalized.normalized;
self.import(imports[i], function (module) {
depCnt++;
deps[i] = module;
if (depCnt == imports.length) {
try {
var output = execute.apply(self, deps);
callback(output);
opt.normalizeMap[imports[i]] = normalized;
self.import(imports[i], function (module) {
depCnt++;
deps[i] = module;
if (depCnt == imports.length) {
try {
var output = execute.apply(self, deps);
callback(output);
}
catch(e) {
errback(e);
return;
}
}
catch(e) {
errback(e);
return;
}
}
}, errback, referer);
})(i);
}, errback, referer);
})(i);
}, errback);
};
}, errback);
};
Loader.prototype._link = function(source, opt) {
var self = this;
return {
imports: ES6Parser.parseImports(opt.normalized, source),
execute: function() {
var exports;
// parses export statements and evaluates in the correct context
// returning the exports object
exports = ES6Parser.parseEval(source, self, {
name: opt.normalized,
sourceURL: opt.address,
isEval: opt.type == 'script',
normalizeMap: opt.normalizeMap
});
// only return exports for a module when not doing script eval
if (opt.normalized && opt.type != 'script')
return new Module(exports || {});
}
};
}
// Loader.prototype.eval( source )
// Synchronously executes a Script non-terminal.
// If the compilation process results in a fetch, a SyntaxError is thrown.
// The compiled code is statically associated with this loader.
Loader.prototype.eval = function (source) {
ES6Parser.parseEval(source, this, {
isEval: true
});
};
// Loader.prototype.parseEval( source )
// Asynchronously executes a Script non-terminal.
// The compiled code is statically associated with this loader.
Loader.prototype.evalAsync = function (source, callback, errback) {
// links and then evals
this._linkExecute(null, source, { type: 'script' }, callback || function() {}, errback || function() {});
}
// Loader.prototype.eval( source )
// Synchronously executes a Script non-terminal.
// If the compilation process results in a fetch, a SyntaxError is thrown.
// The compiled code is statically associated with this loader.
Loader.prototype.eval = function (source) {
ES6Parser.parseEval(source, this, {
isEval: true
});
};
// Loader.prototype.get ( name )
//
// Look up a module in the loader’s registry, using a name that is assumed
// to be normalized.
Loader.prototype.get = function (name) {
return this._mios[name] || null;
};
// Loader.prototype.parseEval( source )
// Asynchronously executes a Script non-terminal.
// The compiled code is statically associated with this loader.
Loader.prototype.evalAsync = function (source, callback, errback) {
// links and then evals
this._linkExecute(null, source, { type: 'script' }, callback || function() {}, errback || function() {});
}
// Loader.prototype.get ( name )
//
// Look up a module in the loader’s registry, using a name that is assumed
// to be normalized.
Loader.prototype.get = function (name) {
return this._mios[name] || null;
};
// Loader.prototype.set( name, mod )
//
// Stores (possibly overwriting) a module instance object
// in the loader’s registry, using a name that is assumed to be normalized.
Loader.prototype.set = function (name, mod) {
this._mios[name] = Module(mod);
};
Loader.prototype.has = function (name) {
return !!this._mios[name];
};
// Loader.prototype.set( name, mod )
//
// Stores (possibly overwriting) a module instance object
// in the loader’s registry, using a name that is assumed to be normalized.
Loader.prototype.set = function (name, mod) {
this._mios[name] = new Module(mod);
};
Loader.prototype.delete = function (name) {
delete this._mios[name];
};
Loader.prototype.has = function (name) {
return !!this._mios[name];
};
// Loader.prototype.defineBuiltins( [ obj ] )
//
// The defineBuiltins method takes an object and defines all the built-in
// objects and functions of the ES6 standard library associated with this
// loader's intrinsics as properties on the object.
Loader.prototype.defineBuiltins = function (o) {
for (var p in o) {
if (o.hasOwnProperty(p)) {
this._intrinsics[p] = o[p];
Loader.prototype.delete = function (name) {
delete this._mios[name];
};
// Loader.prototype.defineBuiltins( [ obj ] )
//
// The defineBuiltins method takes an object and defines all the built-in
// objects and functions of the ES6 standard library associated with this
// loader's intrinsics as properties on the object.
Loader.prototype.defineBuiltins = function (o) {
for (var p in o) {
if (o.hasOwnProperty(p)) {
this._builtins[p] = o[p];
}
}
}
};
};
function Module (o) {
if (typeof o != 'object') throw new TypeError("Expected object");
if (o instanceof Module) {
return o;
} else {
var self = this;
for (var key in o) {
(function (key) {
Object.defineProperty(self, key, {
configurable: false,
enumerable: true,
get: function () {
return o[key];
function Module (o) {
if (typeof o != 'object') throw new TypeError("Expected object");
if (o instanceof Module) {
return o;
} else {
var self = this;
for (var key in o) {
(function (key) {
Object.defineProperty(self, key, {
configurable: false,
enumerable: true,
get: function () {
return o[key];
}
});
})(key);
}
}
};
// Pre-configured Loader instance for easier use
var absUrlRegEx = /^\/|([^\:\/]*:\/\/)/;
var isUrl = function(name) {
return name.substr(name.length - 3, 3) == '.js' || name.match(absUrlRegEx);
}
var fetch;
if (isBrowser) {
fetch = function(url, fulfill, reject) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200 || (xhr.status == 0 && xhr.responseText)) {
fulfill(xhr.responseText);
} else {
reject(xhr.statusText || 'XHR error');
}
});
})(key);
}
};
xhr.open("GET", url, true);
xhr.send(null);
}
}
};
function ToModule (o) {
return new Module(o);
}
// Pre-configured Loader instance for easier use
var absUrlRegEx = /^\/|([^\:\/]*:)/;
var isUrl = function(name) {
return name.substr(name.length - 3, 3) == '.js' || name.match(absUrlRegEx);
}
var defaultSystemLoader = new Loader({
global: window,
strict: false,
normalize: function(name, referer) {
if (isUrl(name))
else {
var fs = require('fs');
fetch = function(url, fulfill, reject) {
return fs.readFile(url, function(err, data) {
if (err)
return reject(err);
else
fulfill(data + '');
});
}
}
var defaultSystemLoader = new Loader({
global: isBrowser ? window : global,
strict: false,
normalize: function(name, referer) {
if (isUrl(name))
return name;
var parentName = referer && referer.name;
if (name.substr(0, 2) == './') {
var parentParts = parentName.split('/');
if (!parentParts.length)
var parentParts = parentName && parentName.split('/');
if (!parentParts || !parentParts.length)
return name.substr(2);

@@ -452,48 +491,37 @@ parentParts.pop();

if (name.substr(0, 3) == '../') {
var parentParts = parentName.split('/');
if (!parentParts.length)
var parentParts = parentName && parentName.split('/');
if (!parentParts || !parentParts.length)
throw "Path below baseUrl";
parentParts.pop();
return this.normalize(name.substr(3), { name: parentParts.join('/') });
return this.normalize('./' + name.substr(3), { name: parentParts.join('/') });
}
return name;
},
resolve: function (name, options) {
for (var r in this.ondemandTable)
if (this.ondemandTable[r].indexOf(name) != -1)
},
resolve: function (name, options) {
for (var r in this.ondemandTable)
if (this.ondemandTable[r].indexOf(name) != -1)
return name;
if (isUrl(name))
return name;
if (isUrl(name))
return name;
return this.baseURL + (this.baseURL.substr(this.baseURL.length - 1, 1) != '/' ? '/' : '') + name + (name.split('/').pop().indexOf('.') == -1 ? '.js' : '');
},
fetch: function (url, fulfill, reject, options) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200 || (xhr.status == 0 && xhr.responseText)) {
fulfill(xhr.responseText);
} else {
reject(xhr.statusText);
}
}
};
xhr.open("GET", url, true);
xhr.send(null);
},
translate: function (source, options) {
return source;
},
link: function (source, options) {}
});
defaultSystemLoader.baseURL = document.URL.substring(0, window.location.href.lastIndexOf('\/') + 1);
defaultSystemLoader.ondemandTable = {};
defaultSystemLoader.ondemand = function (ondemandTable) {
for (var r in ondemandTable) {
this.ondemandTable[r] = this.ondemandTable[r] || [];
if (ondemandTable[r] instanceof Array)
this.ondemandTable[r] = this.ondemandTable[r].concat(ondemandTable[r]);
else
this.ondemandTable[r].push(ondemandTable[r]);
return this.baseURL + (this.baseURL.substr(this.baseURL.length - 1, 1) != '/' ? '/' : '') + name + (name.substr(name.length - 3, 3) == '.js' ? '' : '.js');
},
fetch: fetch,
translate: function (source, options) {
return source;
},
link: function (source, options) {}
});
defaultSystemLoader.baseURL = isBrowser ? document.URL.substring(0, window.location.href.lastIndexOf('\/') + 1) : './';
defaultSystemLoader.ondemandTable = {};
defaultSystemLoader.ondemand = function (ondemandTable) {
for (var r in ondemandTable) {
this.ondemandTable[r] = this.ondemandTable[r] || [];
if (ondemandTable[r] instanceof Array)
this.ondemandTable[r] = this.ondemandTable[r].concat(ondemandTable[r]);
else
this.ondemandTable[r].push(ondemandTable[r]);
}
}
}

@@ -503,155 +531,144 @@

// Syntax Parsing and Source Modifying Polyfills
// Syntax Parsing and Source Modifying Polyfills
// esprima-based parser for module syntax, with pluggable polyfill support
// esprima-based parser for module syntax, with pluggable polyfill support
var scripts = document.getElementsByTagName('script');
var curPath = scripts[scripts.length - 1].src;
var basePath = curPath.substr(0, curPath.lastIndexOf('/') + 1);
var ES6Parser = {
// iterate the entire syntax tree node object with the given iterator function
traverse: function(object, iterator) {
var key, child;
if (iterator(object) === false)
return;
for (key in object) {
child = object[key];
if (typeof child == 'object' && child !== null)
this.traverse(child, iterator);
}
},
// module syntax regexs - may over-classify but not under-classify
// simply designed as a first level check to catch any use of
// module syntax, before loading esprima for deeper analysis
importRegEx: /^\s*import\s+./m,
exportRegEx: /^\s*export\s+(\{|\*|var|class|function|default)/m,
moduleRegEx: /^\s*module\s+("[^"]+"|'[^']+')\s*\{/m,
checkModuleSyntax: function(name, source) {
if (name == null || this.parseNames[name] === undefined)
this.parseNames[name] = source && !!(source.match(this.importRegEx) || source.match(this.exportRegEx) || source.match(this.moduleRegEx));
return this.parseNames[name];
},
loadEsprima: function(name, source, callback, errback) {
if (this.esprima)
return callback();
// use a regex to check if the source contains 'import', 'export' or 'module' statements
// may incorrectly fire, but the damage is only an http request to do better parsing shortly
if (!this.checkModuleSyntax(name, source))
return callback();
var ES6Parser = {
// iterate the entire syntax tree node object with the given iterator function
traverse: function(object, iterator) {
var key, child;
if (iterator(object) === false)
return;
for (key in object) {
child = object[key];
if (typeof child == 'object' && child !== null)
this.traverse(child, iterator);
}
},
// module syntax regexs - may over-classify but not under-classify
// simply designed as a first level check to catch any use of
// module syntax, before loading esprima for deeper analysis
importRegEx: /^\s*import\s+./m,
exportRegEx: /^\s*export\s+(\{|\*|var|class|function|default)/m,
moduleRegEx: /^\s*module\s+("[^"]+"|'[^']+')\s*\{/m,
checkModuleSyntax: function(name, source) {
if (name == null || this.parseNames[name] === undefined)
this.parseNames[name] = source && !!(source.match(this.importRegEx) || source.match(this.exportRegEx) || source.match(this.moduleRegEx));
return this.parseNames[name];
},
loadEsprima: function(name, source, callback, errback) {
if (this.esprima)
return callback();
var self = this;
System.load(basePath + 'esprima-es6.min.js', function() {
self.esprima = System.global.esprima;
callback();
});
},
// store the names of modules which needed to be parsed by esprima
parseNames: {},
// store the syntax trees for modules parsed by esprima
treeCache: {},
// parse the list of import module names for a given source
parseImports: function(name, source) {
// regex showed no need for esprima -> return empty
if (!this.checkModuleSyntax(name, source))
return [];
// use a regex to check if the source contains 'import', 'export' or 'module' statements
// may incorrectly fire, but the damage is only an http request to do better parsing shortly
if (!this.polyfills.length && !this.checkModuleSyntax(name, source))
return callback();
var tree = this.treeCache[name] || (this.treeCache[name] = this.esprima.parse(source, { range: true }));
var imports = [];
this.traverse(tree, function(node) {
if (node.type == 'ImportDeclaration') {
var moduleName;
// import 'jquery' as $;
if (node.from.type == 'Literal')
moduleName = node.from.value;
// import * from foo;
else if (node.from.type == 'Path')
moduleName = node.from.body[0].name;
imports.push(moduleName);
// current script tags used to produce the esprima src (converting collection to array)
var scripts = document.getElementsByTagName('script');
var curScript;
var esprimaSrc;
for (var i = 0; i < scripts.length; i++) {
curScript = scripts[i];
if (curScript.src.match(/es6-module-loader(\.min)?\.js/))
esprimaSrc = curScript.src.substr(0, curScript.src.lastIndexOf('/') + 1) + 'esprima-es6.min.js';
else
esprimaSrc = curScript.getAttribute('data-esprima-src');
if (esprimaSrc)
break;
}
else if (node.type == 'ExportDeclaration') {
// export ... from blah
// export ... from 'blah'
if (node.specifiers && node.specifiers[0] && node.specifiers[0].from) {
if (node.specifiers[0].from.body == 'Path')
imports.push(node.specifiers[0].from.body[0].name);
else
imports.push(node.specifiers[0].from.value);
}
var self = this;
global.System.load(esprimaSrc, function() {
self.esprima = global.System.global.esprima;
callback();
});
},
// store the names of modules which needed to be parsed by esprima
parseNames: {},
// store the syntax trees for modules parsed by esprima
treeCache: {},
// parse the list of import module names for a given source
parseImports: function(name, source) {
// regex showed no need for esprima -> return empty
if (!this.checkModuleSyntax(name, source))
return [];
try {
var tree = this.treeCache[name] || (this.treeCache[name] = this.esprima.parse(source, { range: true }));
}
});
return imports;
},
// allow custom polyfills to be added in the form of syntax functions
addPolyfill: function(polyfill, callback, errback) {
// by virtue of adding a polyfill, we now load esprima by default
this.loadEsprima(null, null, callback, errback);
this.polyfills.push(polyfill);
},
polyfills: [],
applyPolyfill: function(node, tSource) {
for (var i = 0; i < this.polyfills.length; i++)
this.polyfills[i](node, tSource);
},
catch(e) {
e.message = 'Esprima parser error in "' + name + '"\n ' + e.message;
throw e;
}
var imports = [];
this.traverse(tree, function(node) {
// runs an eval of code with module syntax
// opt = {
// name: name, // normalized module name, used to load cached syntax tree
// normalizeMap: normalizeMap, // normalization map to save having to renormalize again
// sourceURL: opt.address, // used for source map
// isEval: isScript // indicate if exports should be parsed
// }
// return value is any exports as a plain object
parseEval: function(source, loader, opt) {
if (node.type == 'ImportDeclaration') {
imports.push(node.source.value);
}
// export * from 'foo';
// export { ... } from 'foo';
else if (node.type == 'ExportDeclaration' && node.source) {
imports.push(node.source.value);
}
});
return imports;
},
// allow custom polyfills to be added in the form of syntax functions
addPolyfill: function(polyfill) {
// by virtue of adding a polyfill, we now load esprima by default
this.loadEsprima(null, null, function(){}, function(){});
this.polyfills.push(polyfill);
},
polyfills: [],
applyPolyfill: function(node, tSource) {
for (var i = 0; i < this.polyfills.length; i++)
this.polyfills[i](node, tSource);
},
// regex showed no need for esprima - normal eval
if (!this.checkModuleSyntax(opt.name, source)) {
var __Loader = loader;
eval('(function(window) { with(__Loader.global) { ' + (loader._strict ? '"use strict";\n' : '') + source + ' } }).call(__Loader.global, __Loader.global); ' + (opt.sourceURL ? '\n//# sourceURL=' + opt.sourceURL : ''));
return;
}
// runs an eval of code with module syntax
// opt = {
// name: name, // normalized module name, used to load cached syntax tree
// normalizeMap: normalizeMap, // normalization map to save having to renormalize again
// sourceURL: opt.address, // used for source map
// isEval: isScript // indicate if exports should be parsed
// }
// return value is any exports as a plain object
parseEval: function(source, loader, opt) {
// NB if no normalizeMap, run normalization function
var tree = this.treeCache[opt.name] || this.esprima.parse(source, { range: true });
// regex showed no need for esprima - normal eval
if (!this.polyfills.length && !this.checkModuleSyntax(opt.name, source)) {
loader.global.__Loader = loader;
scopedEval((loader._strict ? '"use strict";\n' : '') + source, loader.global, opt.sourceURL);
delete loader.global.__Loader;
return;
}
var normalizeMap = opt.normalizeMap || {};
var tree = this.treeCache[opt.name] || this.esprima.parse(source, { range: true });
var tSource = new SourceModifier(source);
var normalizeMap = opt.normalizeMap || {};
var self = this;
this.traverse(tree, function(node) {
// --- Imports ---
// replaces imports with Loader.get
// https://github.com/ariya/esprima/blob/harmony/test/harmonytest.js#L4067
var tSource = new SourceModifier(source);
if (node.type == 'ImportDeclaration') {
// import 'jquery' as $;
if (node.from.type == 'Literal' && node.specifiers[0].type != 'ImportSpecifier') {
tSource.replace(node.range[0], node.range[1],
"var " + node.as.name + " = __Loader.get('" + (normalizeMap[node.from.value] || node.from.value) + "');");
}
var self = this;
this.traverse(tree, function(node) {
// import ... from foo
else {
var moduleName;
if (node.from.body)
moduleName = node.from.body[0].name;
else if (node.from.type == 'Literal')
moduleName = node.from.value;
// --- Imports ---
if (node.type == 'ImportDeclaration') {
var moduleName = normalizeMap[node.source.value] || node.source.value;
moduleName = normalizeMap[moduleName] || moduleName;
// import * from foo;
if (node.specifiers[0].type == 'Glob')
tSource.replace(node.range[0], node.range[1],
"var __module = __Loader.get('" + moduleName + "');" +
"for (var m in __module)" +
" __global[m] = __module[m];");
// import $ from 'jquery';
if (node.kind == 'default') {
tSource.replace(node.range[0], node.range[1], "var " + node.specifiers[0].id.name + " = __Loader.get('" + moduleName + "')['default'];");
}
// import { a } from foo;
// import { a: mapping, of: imports } from foo
else if (node.specifiers[0].type == 'ImportSpecifier') {
// import { ... } from 'jquery';
else {
var replaceSource = "var __module = __Loader.get('" + moduleName + "');";
for (var i = 0; i < node.specifiers.length; i++ ) {
replaceSource += "var " + node.specifiers[i].id.name + " = " +
"__module['" + (node.specifiers[i].from ? node.specifiers[i].from.body[0].name : node.specifiers[i].id.name) + "'];";
for (var i = 0; i < node.specifiers.length; i++) {
var specifier = node.specifiers[i];
replaceSource += "var " + (specifier.name ? specifier.name.name : specifier.id.name) + " = __module['" + specifier.id.name + "'];";
}

@@ -661,195 +678,174 @@ tSource.replace(node.range[0], node.range[1], replaceSource);

}
}
// --- Exports ---
// NB throw an error for exports being present when (name && name.substr(0, 6) != '__eval')
// replace exports with __exports.export = ...
// https://github.com/ariya/esprima/blob/harmony/test/harmonytest.js#L3288
// --- Exports ---
else if (node.type == 'ExportDeclaration') {
// exports = ...
else if (node.type == 'AssignmentExpression' && node.left.name && node.left.name == 'exports')
tSource.replace(node.left.range[0], node.left.range[1], '__exports');
else if (node.type == 'ExportDeclaration') {
var fromModule;
var exports;
// export ... from blah
// export ... from 'blah'
if (node.specifiers && node.specifiers[0] && node.specifiers[0].from) {
if (node.specifiers[0].from.body == 'Path')
fromModule = node.specifiers[0].from.body[0].name;
else
fromModule = node.specifiers[0].from.value;
}
if (!node.declaration && node.specifiers) {
// export *
if (node.specifiers[0].id.type == 'Glob')
exports = true;
if (node.declaration) {
// export { A: some.thing, B: another.thing, C }
else if (node.specifiers[0].type == 'ExportSpecifierSet') {
exports = {};
for (var i = 0; i < node.specifiers[0].specifiers.length; i++) {
if (node.specifiers[0].specifiers[i].from)
exports[node.specifiers[0].specifiers[i].id.name] = tSource.getRange.apply(tSource, node.specifiers[0].specifiers[i].from.range);
else
exports[node.specifiers[0].specifiers[i].id.name] = node.specifiers[0].specifiers[i].id.name;
var exportName;
var declarationIndex = node.declaration.range[0] - 1;
if (node.declaration.type == 'VariableDeclaration') {
var declaration = node.declaration.declarations[0];
// export var p = ...
if (declaration.init) {
exportName = declaration.id.name;
declarationIndex = declaration.init.range[0] - 1;
}
}
// export function q() {}
// export class q {}
else if (node.declaration.type == 'FunctionDeclaration' || node.declaration.type == 'ClassDeclaration')
exportName = node.declaration.id.name;
// export default ... overrides any other name
if (node.default)
exportName = 'default';
tSource.replace(node.range[0], declarationIndex, "__exports['" + exportName + "'] = ");
}
// export varA, varB, varC
else if (node.specifiers[0].type = 'ExportSpecifier') {
exports = {};
for (var i = 0; i < node.specifiers.length; i++)
exports[node.specifiers[i].id.name] = node.specifiers[i].id.name;
else if (node.source) {
var moduleName = normalizeMap[node.source.value] || node.source.value;
// export * from 'jquery'
if (node.specifiers[0].type == 'ExportBatchSpecifier') {
tSource.replace(node.range[0], node.range[1], "var __module = __Loader.get('" + moduleName + "'); for (var m in __module) { __exports[m] = __module[m]; }; ");
}
// export { a as b, c as d } from 'jquery'
else {
var replaceSource = "var __module = __Loader.get('" + moduleName + "'); ";
for (var i = 0; i < node.specifiers.length; i++) {
var specifier = node.specifiers[i];
replaceSource += "__exports['" + (specifier.name ? specifier.name.name : specifier.id.name) + "'] = __module['" + specifier.id.name + "']; ";
}
tSource.replace(node.range[0], node.range[1], replaceSource);
}
}
}
// export var p
else if (node.declaration.type == 'VariableDeclaration')
exports = node.declaration.declarations[0].id.name;
// export function p() {}
else if (node.declaration.type == 'FunctionDeclaration')
exports = node.declaration.id.name;
// export module p {}
// export class p {}
else if (node.declaration.type == 'ModuleDeclaration' || node.declaration.type == 'ClassDeclaration')
exports = node.declaration.declarations[0].id.name;
else {
if (fromModule) {
fromModule = normalize(fromModule);
// export * from someModule
if (exports === true)
tSource.replace(node.range[0], node.range[1], "__exports = __Loader.get('" + fromModule + "');");
// export { some: var } from someModule
else {
// export {a as b, c as d}
var replaceSource = "";
for (var e in exports)
replaceSource += "__exports['" + e + "'] = __Loader.get('" + fromModule + "')['" + exports[e] + "'];";
for (var i = 0; i < node.specifiers.length; i++) {
var specifier = node.specifiers[i];
replaceSource += "__exports['" + specifier.id.name + "'] = " + (specifier.name ? specifier.name.name : specifier.id.name) + "; ";
}
tSource.replace(node.range[0], node.range[1], replaceSource);
}
}
else if (typeof exports == 'object') {
// export { a, b, c: d }
var replaceSource = "";
for (var e in exports)
replaceSource += "__exports['" + e + "'] = " + exports[e] + "; ";
tSource.replace(node.range[0], node.range[1], replaceSource);
}
else if (typeof exports == 'string') {
// export var p = 5 etc
if (node.declaration.declarations)
tSource.replace(node.range[0], node.declaration.declarations[0].id.range[0] - 1, "__exports['" + exports + "'] = ");
// export function q() { ... }
else if (node.declaration.type == 'FunctionDeclaration')
tSource.replace(node.range[0], node.declaration.range[0] - 1, "__exports['" + exports + "'] = ");
else
tSource.replace(node.range[0], node.declaration.id.range[0] - 1, "__exports['" + exports + "'] = ");
}
}
// --- Modules ---
// replaces modules with Loader.set
// --- Modules ---
else if (node.type == 'ModuleDeclaration' && node.body.type == 'BlockStatement') {
// module 'foo' { ..code.. }
// -> (function() { var __exports = {}; ..code.. __Loader.set("foo", new Module(__exports)); })();
else if (node.type == 'ModuleDeclaration') {
var moduleName = node.id.name;
// module foo { ..code.. }
// -> (function() { var __exports = {}; ..code.. __Loader.set("foo", new Module(__exports)); })();
if (node.body.type == 'BlockStatement') {
tSource.replace(node.range[0], node.body.range[0] + 1, "(function() { var __exports = {}; ");
tSource.replace(node.body.range[1], node.range[1], " __Loader.set('" + moduleName + "', new Module(__exports)); })();");
tSource.replace(node.body.range[1], node.range[1], " __Loader.set('" + node.id.name + "', new Module(__exports)); })();");
}
// module names are assumed to be normalized already
// so nested modules not currently supported
}
// --- Polyfills ---
// --- Polyfills ---
else if (self.polyfills.length)
self.applyPolyfill(node, tSource);
});
else if (self.polyfills.length)
self.applyPolyfill(node, tSource);
});
delete this.treeCache[opt.name];
delete this.treeCache[opt.name];
loader.global.__Loader = loader;
var exports = loader.global.__exports = {};
var __Loader = loader;
var __exports = {};
var evalSource = '(function(window) { with(__Loader.global) { ' + (loader._strict ? '"use strict";\n' : '') + tSource.toString() + ' } }).call(__Loader.global, __Loader.global);' + (opt.sourceURL ? '\n//# sourceURL=' + opt.sourceURL : '');
eval(evalSource);
scopedEval((loader._strict ? '"use strict";\n' : '') + tSource.toString(), loader.global, opt.sourceURL);
// if exports are defined and it is an eval, throw
if (opt.isEval) {
for (var e in __exports) {
throw 'Exports only supported for modules, not script evaluation.'
delete loader.global.__Loader;
delete loader.global.__exports;
// if exports are defined and it is an eval, throw
if (opt.isEval) {
for (var e in exports) {
throw 'Exports only supported for modules, not script evaluation.'
}
}
return exports;
}
};
return __exports;
if (!isBrowser)
ES6Parser.esprima = require('./esprima-es6.min.js');
/*
* SourceModifier
*
* Allows for partial modification of a source file based on successive
* range adjustment operations consistent with the original source file
*
* Example:
* 012345678910
* var h = new SourceModifier('hello world');
* h.replace(2, 4, 'y');
* h.replace(6, 10, 'person');
* h.source == 'hey person';
* h.rangeOps == [{start: 2, end: 4, diff: -2}, {start: 4, end: 9, diff: 1}]
*
*/
var SourceModifier = function(source) {
this.source = source;
this.rangeOps = [];
}
};
SourceModifier.prototype = {
mapIndex: function(index) {
// apply the range operations in order to the index
for (var i = 0; i < this.rangeOps.length; i++) {
var curOp = this.rangeOps[i];
if (curOp.start >= index)
continue;
if (curOp.end <= index) {
index += curOp.diff;
continue;
}
throw 'Source location ' + index + ' has already been transformed!';
}
return index;
},
replace: function(start, end, replacement) {
var diff = replacement.length - (end - start + 1);
/*
* SourceModifier
*
* Allows for partial modification of a source file based on successive
* range adjustment operations consistent with the original source file
*
* Example:
* 012345678910
* var h = new SourceModifier('hello world');
* h.replace(2, 4, 'y');
* h.replace(6, 10, 'person');
* h.source == 'hey person';
* h.rangeOps == [{start: 2, end: 4, diff: -2}, {start: 4, end: 9, diff: 1}]
*
*/
var SourceModifier = function(source) {
this.source = source;
this.rangeOps = [];
}
SourceModifier.prototype = {
mapIndex: function(index) {
// apply the range operations in order to the index
for (var i = 0; i < this.rangeOps.length; i++) {
var curOp = this.rangeOps[i];
if (curOp.start >= index)
continue;
if (curOp.end <= index) {
index += curOp.diff;
continue;
}
throw 'Source location ' + index + ' has already been transformed!';
start = this.mapIndex(start);
end = this.mapIndex(end);
this.source = this.source.substr(0, start) + replacement + this.source.substr(end + 1);
this.rangeOps.push({
start: start,
end: end,
diff: diff
});
},
getRange: function(start, end) {
return this.source.substr(this.mapIndex(start), this.mapIndex(end));
},
toString: function() {
return this.source;
}
return index;
},
replace: function(start, end, replacement) {
var diff = replacement.length - (end - start + 1);
};
start = this.mapIndex(start);
end = this.mapIndex(end);
this.source = this.source.substr(0, start) + replacement + this.source.substr(end + 1);
// Export the Loader class
global.Loader = Loader;
// Export the Module class
global.Module = Module;
// Export the System object
global.System = defaultSystemLoader;
this.rangeOps.push({
start: start,
end: end,
diff: diff
});
},
getRange: function(start, end) {
return this.source.substr(this.mapIndex(start), this.mapIndex(end));
},
toString: function() {
return this.source;
}
};
})();
// Export the Loader class
global.Loader = Loader;
// Export the Module class
global.Module = Module;
global.ToModule = ToModule;
// Export the System object
global.System = defaultSystemLoader;
// carefully scoped eval with given global
var scopedEval = function(source, global, sourceURL) {
eval('(function(window) { with(global) { ' + source + ' } }).call(global, global);' + (sourceURL ? '\n//# sourceURL=' + sourceURL : ''));
}
})(window);
})();
{
"name": "es6-module-loader",
"description": "An ES6 Module Loader shim",
"version": "0.2.1",
"version": "0.2.3",
"homepage": "https://github.com/ModuleLoader/es6-module-loader",

@@ -26,3 +26,5 @@ "author": {

"devDependencies": {
"grunt": "~0.3.0"
"grunt": "~0.4.1",
"grunt-contrib-uglify": "~0.2.2",
"grunt-contrib-jshint": "~0.6.0"
},

@@ -36,3 +38,3 @@ "keywords": [

"engines": {
"node": ">= 0.7.9-pre"
"node": ">=0.8.0"
},

@@ -42,3 +44,4 @@ "main": "lib/es6-module-loader",

"test": "grunt test"
}
}
},
"files": ["lib/es6-module-loader.js"]
}

@@ -9,4 +9,4 @@ # ES6 Module Loader

* [Minified build](https://raw.github.com/ModuleLoader/es6-module-loader/master/dist/es6-module-loader.min.js) ~ 12KB
* [Unminified build](https://raw.github.com/ModuleLoader/es6-module-loader/master/dist/es6-module-loader.js) ~ 28KB
* [Minified build](https://raw.github.com/ModuleLoader/es6-module-loader/master/dist/es6-module-loader.min.js) ~ 11KB
* [Unminified](https://raw.github.com/ModuleLoader/es6-module-loader/master/lib/es6-module-loader.js) ~ 26KB

@@ -60,5 +60,8 @@ ## Getting Started

```javascript
var loader = new Loader(Loader, {
var loader = new Loader({
global: window,
strict: false,
normalize: function (name, referer) {
return normalized(name, referer.name);
},
resolve: function (normalized, options) {

@@ -68,17 +71,16 @@ return '/' + normalized + '.js';

fetch: function (url, fulfill, reject, options) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
fulfill(xhr.responseText);
} else {
reject(xhr.statusText);
}
fulfill(source);
},
translate: function (source, options) {
return compile(source);
},
link: function (source, options) {
return {
imports: ['some', 'dependencies'],
execute: function(depA, depB) {
return new Module({
some: 'export'
});
}
};
xhr.open("GET", url, true);
xhr.send(null);
},
translate: function (source, options) {
return source;
}

@@ -88,2 +90,6 @@ });

The above hooks are all optional, using the default System hooks when not present.
For an overview of working with custom loaders, see [Yehuda Katz's essay](https://gist.github.com/wycats/51c96e3adcdb3a68cbc3) or the [ES6 Module Specification](http://wiki.ecmascript.org/doku.php?id=harmony:module_loaders).
Define an ES6 module programatically (useful in optimized / production environments):

@@ -100,16 +106,51 @@

### Specification Notes
### Syntax Parsing
The polyfill is implemented exactly to the specification now, except for the following items:
The [Esprima ES6 Harmony parser](https://github.com/ariya/esprima/tree/harmony) is being used to do parsing, loaded only when necessary.
* The `extra` metadata property is not yet handled in the resolve.
* The `fetch` function is given a different specification between the prototype (`Loader.prototype.fetch`) and loader instance (`options.fetch`). Since instance functions are provided on the instance object as in the @wycats essay (`System.normalize`, `System.fetch` etc), there seems to be a conflict between these.
* The intrinsics encapsulation is a tricky one to polyfill, but we have done our best based on a global prototype chain behaviour, where `global.__proto__ == intrinsics`. And `intrinsics.__proto__ == window`. All code is evaluated with the `window` and `this` properties referencing the `global` allowing full global encapsulation.
The following module statements are currently supported:
### Syntax Parsing
```javascript
import 'jquery'; // import a module
import $ from 'jquery'; // import the default export of a module
import { $ } from 'jquery'; // import a named export of a module
import { $ as jQuery } from 'jquery'; // import a named export to a different name
The [Esprima ES6 Harmony parser](https://github.com/ariya/esprima/tree/harmony) is being used to do parsing, loaded only when necessary. This parser still uses an older syntax, which is currently the major critical issue to sort out for this polyfill.
export var x = 42; // export a named variable
export function foo() {}; // export a named function
The issue tracking this is here - https://github.com/ModuleLoader/es6-module-loader/issues/10
export default var x = 42; // export the default export
export default function foo() {}; // export the default export as a function
export default = function foo() {}; // export the default export by assignment
export { encrypt }; // export an existing variable
export { decrypt as dec }; // export a variable as a new name
export { encrypt as en } from 'crypto'; // export an export from another module
export * from 'crypto'; // export all exports from another module
module 'crypto' { ... } // define a module
```
### NodeJS Support
For use in NodeJS, the `Module`, `Loader` and `System` globals are provided as exports:
```
var System = require('es6-module-loader').System;
System.import('some-module', callback);
```
### Custom Esprima Location
To set a custom path to the Esprima Harmony parser, specify the `data-esprima-src` attribute on the `<script>` tag used to include the module loader.
### Specification Notes
The polyfill is implemented exactly to the specification, except where areas are currently under debate.
The only feature which is not possible to fully polyfill is the intrinsics functionality and sandboxing of the loader. Custom builtins and full global encapsulation is still provided.
To follow the current the specification changes, see https://github.com/ModuleLoader/es6-module-loader/issues?labels=specification&page=1&state=open.
## Projects using us

@@ -116,0 +157,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc