This repository was archived by the owner on Jul 13, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathnode-es-module-loader.js
More file actions
168 lines (143 loc) · 5.64 KB
/
Copy pathnode-es-module-loader.js
File metadata and controls
168 lines (143 loc) · 5.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
import RegisterLoader from 'es-module-loader/core/register-loader.js';
import { ModuleNamespace } from 'es-module-loader/core/loader-polyfill.js';
import { isNode, baseURI, pathToFileUrl, fileUrlToPath } from 'es-module-loader/core/common.js';
import { resolveIfNotPlain } from 'es-module-loader/core/resolve.js';
var babel = require('babel-core');
var modulesRegister = require('babel-plugin-transform-es2015-modules-systemjs');
var importSyntax = require('babel-plugin-syntax-dynamic-import');
var path = require('path');
var Module = require('module');
var fs = require('fs');
var sourceMapSources = global.nodeEsModuleLoaderSourceMapSources = global.nodeEsModuleLoaderSourceMapSources || {};
require('source-map-support').install({
retrieveSourceMap: function(source) {
if (!sourceMapSources[source])
return null;
return {
url: source.replace('!transpiled', ''),
map: sourceMapSources[source]
};
}
});
function NodeESModuleLoader(baseKey, rcPath) {
if (!isNode)
throw new Error('Node module loader can only be used in Node');
if (baseKey)
this.baseKey = resolveIfNotPlain(baseKey, baseURI) || resolveIfNotPlain('./' + baseKey, baseURI);
else
this.baseKey = baseURI;
if (this.baseKey[this.baseKey.length - 1] !== '/')
this.baseKey += '/';
if (rcPath) {
if (typeof rcPath !== 'string')
throw new TypeError('Second argument to Node loader must be a valid file path to the babelrc file.');
this.rcPath = rcPath;
}
RegisterLoader.call(this);
var loader = this;
// ensure System.register is available
global.System = global.System || {};
global.System.register = function() {
loader.register.apply(loader, arguments);
};
}
NodeESModuleLoader.prototype = Object.create(RegisterLoader.prototype);
// normalize is never given a relative name like "./x", that part is already handled
NodeESModuleLoader.prototype[RegisterLoader.resolve] = function(key, parent) {
parent = parent || this.baseKey;
key = RegisterLoader.prototype[RegisterLoader.resolve].call(this, key, parent) || key;
return Promise.resolve()
.then(function() {
var parentPath = fileUrlToPath(parent);
var requireContext = new Module(parentPath);
requireContext.paths = Module._nodeModulePaths(parentPath);
var resolved = Module._resolveFilename(key.substr(0, 5) === 'file:' ? fileUrlToPath(key) : key, requireContext, true);
// core modules are returned as plain non-absolute paths
return path.isAbsolute(resolved) ? pathToFileUrl(resolved) : resolved;
});
};
// instantiate just needs to run System.register
// so we fetch the source, convert into the Babel System module format, then evaluate it
NodeESModuleLoader.prototype[RegisterLoader.instantiate] = function(key, processAnonRegister) {
var loader = this;
// first, try to load the module as CommonJS
var nodeModule = tryNodeLoad(key.substr(0, 5) === 'file:' ? fileUrlToPath(key) : key);
if (nodeModule)
return Promise.resolve(new ModuleNamespace({
default: nodeModule
}));
// otherwise load the buffe
return new Promise(function(resolve, reject) {
fs.readFile(fileUrlToPath(key), function(err, buffer) {
if (err)
return reject(err);
// first check if it is web assembly, detected by leading bytes
var bytes = new Uint8Array(buffer);
if (bytes[0] === 0 && bytes[1] === 97 && bytes[2] === 115) {
return WebAssembly.compile(bytes).then(function (m) {
var deps = [];
var setters = [];
var importObj = {};
if (WebAssembly.Module.imports)
WebAssembly.Module.imports(m).forEach(function (i) {
var key = i.module;
setters.push(function (m) {
importObj[key] = m;
});
if (deps.indexOf(key) === -1)
deps.push(key);
});
loader.register(deps, function (_export) {
return {
setters: setters,
execute: function () {
// for some reason exports are non-enumarable in the node build
// which seems to contradict the WASM spec
let exports = new WebAssembly.Instance(m, importObj).exports;
let exportNames = Object.getOwnPropertyNames(exports);
for (var i = 0; i < exportNames.length; i++) {
var name = exportNames[i];
_export(name, exports[name]);
}
}
};
});
processAnonRegister();
})
.then(resolve, reject);
}
// otherwise fall back to transform source with Babel
var output = babel.transform(buffer.toString(), {
compact: false,
filename: key + '!transpiled',
sourceFileName: key,
moduleIds: false,
sourceMaps: 'both',
plugins: [importSyntax, modulesRegister],
extends: loader.rcPath
});
// evaluate without require, exports and module variables
var path = fileUrlToPath(key) + '!transpiled';
output.map.sources = output.map.sources.map(fileUrlToPath);
sourceMapSources[path] = output.map;
(0,eval)(output.code + '\n//# sourceURL=' + path);
processAnonRegister();
resolve();
});
});
};
function tryNodeLoad(path) {
try {
return require(path);
}
catch(e) {
if (e instanceof SyntaxError &&
(e.message.indexOf('Unexpected token export') !== -1 ||
e.message.indexOf('Unexpected token import') !== -1 ||
e.message.indexOf('Unexpected reserved word') !== -1) ||
e.message.indexOf('Invalid or unexpected token') !== -1)
return;
throw e;
}
}
export default NodeESModuleLoader;