aboutsummaryrefslogtreecommitdiff
path: root/lib/esm.js
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2016-10-10 03:50:11 +0200
committerFlorian Dold <florian.dold@gmail.com>2016-10-10 03:50:11 +0200
commit9af485a584e47fd503ed5c62b9f6482574715f1e (patch)
tree687abbcff412bd4ce5c51d51de030a06e3963cf5 /lib/esm.js
Squashed 'thirdparty/systemjs/' content from commit 5ed69b6
git-subtree-dir: thirdparty/systemjs git-subtree-split: 5ed69b6344e8fc1cd43bf758350b2236f57e1499
Diffstat (limited to 'lib/esm.js')
-rw-r--r--lib/esm.js161
1 files changed, 161 insertions, 0 deletions
diff --git a/lib/esm.js b/lib/esm.js
new file mode 100644
index 000000000..84ac0f353
--- /dev/null
+++ b/lib/esm.js
@@ -0,0 +1,161 @@
+/*
+ * Extension to detect ES6 and auto-load Traceur or Babel for processing
+ */
+(function() {
+ // good enough ES6 module detection regex - format detections not designed to be accurate, but to handle the 99% use case
+ var esmRegEx = /(^\s*|[}\);\n]\s*)(import\s*(['"]|(\*\s+as\s+)?[^"'\(\)\n;]+\s*from\s*['"]|\{)|export\s+\*\s+from\s+["']|export\s*(\{|default|function|class|var|const|let|async\s+function))/;
+
+ var traceurRuntimeRegEx = /\$traceurRuntime\s*\./;
+ var babelHelpersRegEx = /babelHelpers\s*\./;
+
+ hook('translate', function(translate) {
+ return function(load) {
+ var loader = this;
+ var args = arguments;
+ return translate.apply(loader, args)
+ .then(function(source) {
+ // detect & transpile ES6
+ if (load.metadata.format == 'esm' || load.metadata.format == 'es6' || !load.metadata.format && source.match(esmRegEx)) {
+ if (load.metadata.format == 'es6')
+ warn.call(loader, 'Module ' + load.name + ' has metadata setting its format to "es6", which is deprecated.\nThis should be updated to "esm".');
+
+ load.metadata.format = 'esm';
+
+ if (load.metadata.deps) {
+ var depInject = '';
+ for (var i = 0; i < load.metadata.deps.length; i++)
+ depInject += 'import "' + load.metadata.deps[i] + '"; ';
+ load.source = depInject + source;
+ }
+
+ if (loader.transpiler === false) {
+ // we accept translation to esm for builds though to enable eg rollup optimizations
+ if (loader.builder)
+ return source;
+ throw new TypeError('Unable to dynamically transpile ES module as SystemJS.transpiler set to false.');
+ }
+
+ // setting _loader.loadedTranspiler = false tells the next block to
+ // do checks for setting transpiler metadata
+ loader._loader.loadedTranspiler = loader._loader.loadedTranspiler || false;
+ if (loader.pluginLoader)
+ loader.pluginLoader._loader.loadedTranspiler = loader._loader.loadedTranspiler || false;
+
+ // do transpilation
+ return (loader._loader.transpilerPromise || (
+ loader._loader.transpilerPromise = Promise.resolve(
+ __global[loader.transpiler == 'typescript' ? 'ts' : loader.transpiler] || (loader.pluginLoader || loader).normalize(loader.transpiler)
+ .then(function(normalized) {
+ loader._loader.transpilerNormalized = normalized;
+ return (loader.pluginLoader || loader).load(normalized)
+ .then(function() {
+ return (loader.pluginLoader || loader).get(normalized);
+ });
+ })
+ ))).then(function(transpiler) {
+ loader._loader.loadedTranspilerRuntime = true;
+
+ // translate hooks means this is a transpiler plugin instead of a raw implementation
+ if (transpiler.translate) {
+ // if transpiler is the same as the plugin loader, then don't run twice
+ if (transpiler == load.metadata.loaderModule)
+ return load.source;
+ load.metadata.loaderModule = transpiler;
+ load.metadata.loader = loader._loader.transpilerNormalized;
+
+ // convert the source map into an object for transpilation chaining
+ if (typeof load.metadata.sourceMap == 'string')
+ load.metadata.sourceMap = JSON.parse(load.metadata.sourceMap);
+
+ return Promise.resolve(transpiler.translate.apply(loader, args))
+ .then(function(source) {
+ // sanitize sourceMap if an object not a JSON string
+ var sourceMap = load.metadata.sourceMap;
+ if (sourceMap && typeof sourceMap == 'object') {
+ var originalName = load.address.split('!')[0];
+
+ // force set the filename of the original file
+ if (!sourceMap.file || sourceMap.file == load.address)
+ sourceMap.file = originalName + '!transpiled';
+
+ // force set the sources list if only one source
+ if (!sourceMap.sources || sourceMap.sources.length <= 1 && (!sourceMap.sources[0] || sourceMap.sources[0] == load.address))
+ sourceMap.sources = [originalName];
+ }
+
+ if (load.metadata.format == 'esm' && !loader.builder && detectRegisterFormat(source))
+ load.metadata.format = 'register';
+ return source;
+ });
+ }
+
+ // legacy builder support
+ if (loader.builder)
+ load.metadata.originalSource = load.source;
+
+ // defined in es6-module-loader/src/transpile.js
+ return transpile.call(loader, load)
+ .then(function(source) {
+ // clear sourceMap as transpiler embeds it
+ load.metadata.sourceMap = undefined;
+ return source;
+ });
+ }, function(err) {
+ throw addToError(err, 'Unable to load transpiler to transpile ' + load.name);
+ });
+ }
+
+ // skip transpiler and transpiler runtime loading when transpiler is disabled
+ if (loader.transpiler === false)
+ return source;
+
+ // load the transpiler correctly
+ if (loader._loader.loadedTranspiler === false && (loader.transpiler == 'traceur' || loader.transpiler == 'typescript' || loader.transpiler == 'babel')
+ && load.name == loader.normalizeSync(loader.transpiler)) {
+
+ // always load transpiler as a global
+ if (source.length > 100 && !load.metadata.format) {
+ load.metadata.format = 'global';
+
+ if (loader.transpiler === 'traceur')
+ load.metadata.exports = 'traceur';
+ if (loader.transpiler === 'typescript')
+ load.metadata.exports = 'ts';
+ }
+
+ loader._loader.loadedTranspiler = true;
+ }
+
+ // load the transpiler runtime correctly
+ if (loader._loader.loadedTranspilerRuntime === false) {
+ if (load.name == loader.normalizeSync('traceur-runtime')
+ || load.name == loader.normalizeSync('babel/external-helpers*')) {
+ if (source.length > 100)
+ load.metadata.format = load.metadata.format || 'global';
+
+ loader._loader.loadedTranspilerRuntime = true;
+ }
+ }
+
+ // detect transpiler runtime usage to load runtimes
+ if ((load.metadata.format == 'register' || load.metadata.bundle) && loader._loader.loadedTranspilerRuntime !== true) {
+ if (loader.transpiler == 'traceur' && !__global.$traceurRuntime && load.source.match(traceurRuntimeRegEx)) {
+ loader._loader.loadedTranspilerRuntime = loader._loader.loadedTranspilerRuntime || false;
+ return loader['import']('traceur-runtime').then(function() {
+ return source;
+ });
+ }
+ if (loader.transpiler == 'babel' && !__global.babelHelpers && load.source.match(babelHelpersRegEx)) {
+ loader._loader.loadedTranspilerRuntime = loader._loader.loadedTranspilerRuntime || false;
+ return loader['import']('babel/external-helpers').then(function() {
+ return source;
+ });
+ }
+ }
+
+ return source;
+ });
+ };
+ });
+
+})();