diff options
author | Florian Dold <florian.dold@gmail.com> | 2016-10-10 03:50:11 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2016-10-10 03:50:11 +0200 |
commit | 9af485a584e47fd503ed5c62b9f6482574715f1e (patch) | |
tree | 687abbcff412bd4ce5c51d51de030a06e3963cf5 /lib/cjs.js |
Squashed 'thirdparty/systemjs/' content from commit 5ed69b6
git-subtree-dir: thirdparty/systemjs
git-subtree-split: 5ed69b6344e8fc1cd43bf758350b2236f57e1499
Diffstat (limited to 'lib/cjs.js')
-rw-r--r-- | lib/cjs.js | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/lib/cjs.js b/lib/cjs.js new file mode 100644 index 000000000..c7327f181 --- /dev/null +++ b/lib/cjs.js @@ -0,0 +1,138 @@ +/* + SystemJS CommonJS Format +*/ +(function() { + // CJS Module Format + // require('...') || exports[''] = ... || exports.asd = ... || module.exports = ... + var cjsExportsRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF.])(exports\s*(\[['"]|\.)|module(\.exports|\['exports'\]|\["exports"\])\s*(\[['"]|[=,\.]))/; + // RegEx adjusted from https://github.com/jbrantly/yabble/blob/master/lib/yabble.js#L339 + var cjsRequireRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF."'])require\s*\(\s*("[^"\\]*(?:\\.[^"\\]*)*"|'[^'\\]*(?:\\.[^'\\]*)*')\s*\)/g; + var commentRegEx = /(^|[^\\])(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg; + + var stringRegEx = /("[^"\\\n\r]*(\\.[^"\\\n\r]*)*"|'[^'\\\n\r]*(\\.[^'\\\n\r]*)*')/g; + + // used to support leading #!/usr/bin/env in scripts as supported in Node + var hashBangRegEx = /^\#\!.*/; + + function getCJSDeps(source) { + cjsRequireRegEx.lastIndex = commentRegEx.lastIndex = stringRegEx.lastIndex = 0; + + var deps = []; + + var match; + + // track string and comment locations for unminified source + var stringLocations = [], commentLocations = []; + + function inLocation(locations, match) { + for (var i = 0; i < locations.length; i++) + if (locations[i][0] < match.index && locations[i][1] > match.index) + return true; + return false; + } + + if (source.length / source.split('\n').length < 200) { + while (match = stringRegEx.exec(source)) + stringLocations.push([match.index, match.index + match[0].length]); + + // TODO: track template literals here before comments + + while (match = commentRegEx.exec(source)) { + // only track comments not starting in strings + if (!inLocation(stringLocations, match)) + commentLocations.push([match.index + match[1].length, match.index + match[0].length - 1]); + } + } + + while (match = cjsRequireRegEx.exec(source)) { + // ensure we're not within a string or comment location + if (!inLocation(stringLocations, match) && !inLocation(commentLocations, match)) { + var dep = match[1].substr(1, match[1].length - 2); + // skip cases like require('" + file + "') + if (dep.match(/"|'/)) + continue; + // trailing slash requires are removed as they don't map mains in SystemJS + if (dep[dep.length - 1] == '/') + dep = dep.substr(0, dep.length - 1); + deps.push(dep); + } + } + + return deps; + } + + hook('instantiate', function(instantiate) { + return function(load) { + var loader = this; + if (!load.metadata.format) { + cjsExportsRegEx.lastIndex = 0; + cjsRequireRegEx.lastIndex = 0; + if (cjsRequireRegEx.exec(load.source) || cjsExportsRegEx.exec(load.source)) + load.metadata.format = 'cjs'; + } + + if (load.metadata.format == 'cjs') { + var metaDeps = load.metadata.deps; + var deps = load.metadata.cjsRequireDetection === false ? [] : getCJSDeps(load.source); + + for (var g in load.metadata.globals) + if (load.metadata.globals[g]) + deps.push(load.metadata.globals[g]); + + var entry = createEntry(); + + load.metadata.entry = entry; + + entry.deps = deps; + entry.executingRequire = true; + entry.execute = function(_require, exports, module) { + function require(name) { + if (name[name.length - 1] == '/') + name = name.substr(0, name.length - 1); + return _require.apply(this, arguments); + } + require.resolve = function(name) { + return loader.get('@@cjs-helpers').requireResolve(name, module.id); + }; + // support module.paths ish + module.paths = []; + module.require = _require; + + // ensure meta deps execute first + if (!load.metadata.cjsDeferDepsExecute) + for (var i = 0; i < metaDeps.length; i++) + require(metaDeps[i]); + + var pathVars = loader.get('@@cjs-helpers').getPathVars(module.id); + var __cjsWrapper = { + exports: exports, + args: [require, exports, module, pathVars.filename, pathVars.dirname, __global, __global] + }; + + var cjsWrapper = "(function(require, exports, module, __filename, __dirname, global, GLOBAL"; + + // add metadata.globals to the wrapper arguments + if (load.metadata.globals) + for (var g in load.metadata.globals) { + __cjsWrapper.args.push(require(load.metadata.globals[g])); + cjsWrapper += ", " + g; + } + + // disable AMD detection + var define = __global.define; + __global.define = undefined; + __global.__cjsWrapper = __cjsWrapper; + + load.source = cjsWrapper + ") {" + load.source.replace(hashBangRegEx, '') + "\n}).apply(__cjsWrapper.exports, __cjsWrapper.args);"; + + __exec.call(loader, load); + + __global.__cjsWrapper = undefined; + __global.define = define; + }; + } + + return instantiate.call(loader, load); + }; + }); +})(); |