commonjs concatenation

node v4.9.1
version: master
endpointsharetweet
Prototyped http://www.nonblocking.io/2011/12/experimental-support-for-common-js-and.html without depending on closure and it's strict/arcane dependency resolution Motivated by: https://nolanlawson.com/2016/08/15/the-cost-of-small-modules/
var TEST_MODULE = ` var a = require('foo'), b = require('bar'), c = require('baz').baz; var test2 = 5 + c.a.b; var test = function(c) { 5 + c.a.b(); }; var test3 = { a: 1 }; test3[a] = 5; exports.bar = function() { return exports.baz + a; }; module.exports.foo = function() { return foo + b(); }; `;
var recast = require('recast'); var types = require('ast-types'); var b = types.builders; var n = types.namedTypes; var ast = recast.parse(TEST_MODULE);
var moduleName = 'test'; var modulePrefix = '__module-'; var localPrefix = '__local-' + moduleName + '-'; var moduleExports = modulePrefix + moduleName; var localVariables = {}; // Collect all local variables so we can rescope them types.visit(ast, { visitVariableDeclarator: function(path) { localVariables[path.node.id.name] = true; return false; } }); // Rescope non property identifiers (so we don't have scope collision) types.visit(ast, { visitIdentifier: function(path) { if (!localVariables[path.node.name]) { this.traverse(path); return; } if (path.name == 'key') { this.traverse(path); return; } if (path.name == 'property' &&!path.parentPath.value.computed) { this.traverse(path); return; } // if (path.node.name == 'a') { // console.log(path.node, path.name); // } path.replace(b.identifier(localPrefix + path.node.name)); return false; } }); types.visit(ast, { // Replace require calls with literals visitCallExpression: function(path) { if (path.node.callee.name == 'require') { var name = modulePrefix + path.node.arguments[0].value; var replacementNode = b.identifier(name); path.replace(replacementNode); return false; } this.traverse(path); }, // Replace module.exports and exports.* with literals visitMemberExpression: function(path) { if (n.Identifier.check(path.node.object) && path.node.object.name == 'exports') { var replacementNode = b.memberExpression( b.identifier(moduleExports), path.node.property, false) path.replace(replacementNode); return false; } if (n.Identifier.check(path.node.object) && path.node.object.name == 'module') { path.replace(b.identifier(moduleExports)); return false; } this.traverse(path); } }); // Prepend the module.exports variable declaration var varStatement = b.variableDeclaration('var', [ b.variableDeclarator(b.identifier(moduleExports), null) ]); ast.program.body.unshift(varStatement); var output = recast.print(ast).code;
Loading…

no comments

    sign in to comment