add named amd support

This commit is contained in:
Guy Bedford 2018-11-01 13:56:24 +02:00
parent 27a010efd8
commit 0f1adb38f9
5 changed files with 75 additions and 34 deletions

View File

@ -10,32 +10,11 @@
throw new Error('AMD require not supported.');
}
function unsupportedNamed () {
throw new Error('Named AMD not supported.');
}
function emptyFn () {}
const requireExportsModule = ['require', 'exports', 'module'];
// hook System.register to know the last declaration binding
let lastRegisterDeclare;
const systemRegister = systemPrototype.register;
systemPrototype.register = function (deps, declare) {
lastRegisterDeclare = declare;
systemRegister.call(this, deps, declare);
};
const getRegister = systemPrototype.getRegister;
systemPrototype.getRegister = function () {
const register = getRegister.call(this);
// if its an actual System.register leave it
if (register && register[1] === lastRegisterDeclare)
return register;
// otherwise AMD takes priority
// no registration -> attempt AMD detection
if (!amdDefineDeps)
return register || emptyInstantiation;
function createAMDRegister (amdDefineDeps, amdDefineExec) {
const exports = {};
const module = { exports: exports };
const depModules = [];
@ -69,29 +48,68 @@
if (splice)
amdDefineDeps.length -= splice;
const amdExec = amdDefineExec;
const registration = [amdDefineDeps, function (_export) {
return [amdDefineDeps, function (_export) {
_export('default', exports);
return {
setters: setters,
execute: function () {
_export('default', amdExec.apply(exports, depModules) || module.exports);
module.exports = amdExec.apply(exports, depModules) || module.exports;
if (exports !== module.exports)
_export('default', module.exports);
}
};
}];
}
// hook System.register to know the last declaration binding
let lastRegisterDeclare;
const systemRegister = systemPrototype.register;
// if we have named register support continue to use it
if (systemRegister.length === 3) {
systemPrototype.register = function (name, deps, declare) {
if (typeof name !== 'string')
lastRegisterDeclare = deps;
systemRegister.apply(this, arguments);
};
}
else {
systemPrototype.register = function (deps, declare) {
lastRegisterDeclare = declare;
systemRegister.apply(this, arguments);
};
}
const getRegister = systemPrototype.getRegister;
systemPrototype.getRegister = function () {
const register = getRegister.call(this);
// if its an actual System.register leave it
if (register && register[1] === lastRegisterDeclare)
return register;
// otherwise AMD takes priority
// no registration -> attempt AMD detection
if (!amdDefineDeps)
return register || emptyInstantiation;
const registration = createAMDRegister(amdDefineDeps, amdDefineExec);
amdDefineDeps = null;
return registration;
};
let amdDefineDeps;
let amdDefineExec;
let amdDefineDeps, amdDefineExec;
global.define = function (name, deps, execute) {
// define('', [], function () {})
if (typeof name === 'string') {
if (amdDefineDeps) {
if (!System.registerRegistry)
throw new Error('Include the named register extension named AMD support in SystemJS.');
System.registerRegistry[name] = createAMDRegister(deps, execute);
amdDefineDeps = [];
amdDefineExec = unsupportedNamed;
amdDefineExec = emptyFn;
return;
}
else {
if (System.registerRegistry)
System.registerRegistry[name] = createAMDRegister(deps, execute);
name = deps;
deps = execute;
}

View File

@ -8,26 +8,33 @@
(function () {
const systemJSPrototype = System.constructor.prototype;
const registerRegistry = Object.create(null);
const constructor = System.constructor;
const SystemJS = function () {
constructor.call(this);
this.registerRegistry = Object.create(null);
};
SystemJS.prototype = systemJSPrototype;
System = new SystemJS();
const register = systemJSPrototype.register;
systemJSPrototype.register = function (name, deps, declare) {
if (typeof name !== 'string')
return register.apply(this, arguments);
registerRegistry[name] = [deps, declare];
this.registerRegistry[name] = [deps, declare];
};
const resolve = systemJSPrototype.resolve;
systemJSPrototype.resolve = function (id, parentURL) {
if (id[0] === '/' || id[0] === '.' && (id[1] === '/' || id[1] === '.' && id[2] === '/'))
return resolve.call(this, id, parentURL);
if (registerRegistry[id])
if (id in this.registerRegistry)
return id;
return resolve.call(this, id, parentURL);
};
const instantiate = systemJSPrototype.instantiate;
systemJSPrototype.instantiate = function (url, firstParentUrl) {
return registerRegistry[url] || instantiate.call(this, url, firstParentUrl);
return this.registerRegistry[url] || instantiate.call(this, url, firstParentUrl);
};
})();

View File

@ -8,4 +8,14 @@ suite('Named System.register', function() {
assert.equal(m.a, 'b');
});
});
test('Loading a named AMD bundle', function () {
return System.import('./fixtures/browser/named-amd.js').then(function (m) {
assert.equal(Object.keys(m).length, 1);
return System.import('c');
})
.then(function (m) {
assert.equal(m.default.a, 'b');
});
});
});

View File

@ -1,7 +1,6 @@
suite('Translate Loader', function() {
suite('Transform Loader', function() {
System = new System.constructor();
let translateCnt = 0;
console.log('tf');
System.transform = function (url, source) {
translateCnt++;
return source;

7
test/fixtures/browser/named-amd.js vendored Normal file
View File

@ -0,0 +1,7 @@
define('c', ['exports', './d'], function (exports, b) {
exports.a = b.b;
});
define('d', [], function () {
return { b: 'b' };
});