Created
November 22, 2013 10:30
-
-
Save spadgos/7597842 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Below is an incomplete snippet of code which is used to implement the Lazy Require Calls | |
method described here http://spadgos.github.io/rupy13/#/29 | |
Basically, it takes an AST like this: | |
var Foo = require('foo'); | |
function bar() { | |
Foo.quux(); | |
} | |
...into this: | |
var Foo; | |
function bar() { | |
(Foo || (Foo = require('foo'))).quux(); | |
} | |
The `ASTHelpers.transform` method is simply a wrapper for the standard Uglify transform, | |
which executes the callback only on nodes which match the given `type`. Hopefully it | |
should be understandable enough. | |
*/ | |
// Get the AST subtree to perform a lazy require call. Basically converts a reference to a variable which has been | |
// required into `variable || (variable = require("path/to/require"))` | |
function getReplacementRequireVar(name, req) { | |
var miniAST = uglify.parse(uglify.string_template('{name} || ({name} = require("{req}"))', { | |
name: name, | |
req: req | |
})); | |
// miniAST.body == [ SimpleStatement ] | |
return miniAST.body[0].body; | |
} | |
// see if this symbol is the same as the one defined at the top of the file | |
function matches (symbolDec) { | |
return symbolDec.start === this.start; | |
} | |
/** | |
* Finds all variables assigned to a require call and rewrites them to only make the call to require when necessary. | |
*/ | |
function rewriteRequires(ast) { | |
var map = {}; | |
ASTHelpers.transform(ast, [{ | |
type: 'VarDef', | |
handler: function (node) { | |
if (node.value | |
&& node.value instanceof uglify.AST_Call | |
&& node.value.expression.name === 'require' | |
&& node.value.expression.global()) { | |
map[node.name.name] = { | |
module: node.value.args[0].value, | |
node: node | |
}; | |
node.value = null; // delete the require call | |
} | |
} | |
}]); | |
ASTHelpers.transform(ast, [{ | |
type: 'SymbolRef', | |
handler: function (node) { | |
var reqInfo = map[node.name]; | |
if (reqInfo && node.thedef.orig.some(matches, reqInfo.node)) { | |
return getReplacementRequireVar(node.name, reqInfo.module); | |
} | |
} | |
}]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment