add support for custom module formatters - #82

This commit is contained in:
Sebastian McKenzie 2014-10-19 12:11:12 +11:00
parent 4f15bfcf1d
commit a1adca6b65
31 changed files with 156 additions and 109 deletions

View File

@ -16,19 +16,27 @@ commander.option("-s, --source-maps", "Save source map alongside the compiled co
commander.option("-f, --filename [filename]", "Filename to use when reading from stdin - this will be used in source-maps, errors etc [stdin]", "stdin");
commander.option("-w, --watch", "Recompile files on changes");
commander.option("-m, --modules [modules]", "Module formatter type to use [common]", "common");
commander.option("-w, --whitelist [whitelist]", "Whitelist of transformers to ONLY use", util2.list);
commander.option("-b, --blacklist [blacklist]", "Blacklist of transformers to NOT use", util2.list);
commander.option("-o, --out-file [out]", "Compile all input files into a single file");
commander.option("-d, --out-dir [out]", "Compile an input directory of modules into an output directory");
commander.on("--help", function(){
console.log(" Transformers:");
var outKeys = function (title, obj) {
console.log(" " + title + ":");
console.log();
_.each(_.keys(transform.transformers).sort(), function (key) {
_.each(_.keys(obj).sort(), function (key) {
if (key[0] === "_") return;
console.log(" - " + key);
});
console.log();
};
outKeys("Transformers", transform.transformers);
outKeys("Module formatters", transform.moduleFormatters);
});
var pkg = require("../../package.json");
@ -83,7 +91,8 @@ exports.opts = {
sourceMapName: commander.outFile,
blacklist: commander.blacklist,
whitelist: commander.whitelist,
sourceMap: commander.sourceMaps || commander.sourceMapsInline
sourceMap: commander.sourceMaps || commander.sourceMapsInline,
modules: commander.modules
};
var fn;

View File

@ -9,9 +9,11 @@ var b = require("recast").types.builders;
var _ = require("lodash");
function File(opts) {
this.opts = File.normaliseOptions(opts);
this.moduleFormatter = this.getModuleFormatter(opts.modules);
this.declarations = {};
this.uids = {};
this.opts = File.normaliseOptions(opts);
this.ast = {};
}
@ -22,7 +24,8 @@ File.normaliseOptions = function (opts) {
blacklist: [],
whitelist: [],
sourceMap: false,
filename: "unknown"
filename: "unknown",
modules: "common"
});
_.defaults(opts, {
@ -36,6 +39,12 @@ File.normaliseOptions = function (opts) {
return opts;
};
File.prototype.getModuleFormatter = function (type) {
var ModuleLoader = transform.moduleFormatters[type];
if (!ModuleLoader) throw new ReferenceError("unknown module formatter type " + type);
return new ModuleLoader(this);
};
File.prototype.parseShebang = function (code) {
var shebangMatch = code.match(SHEBANG_REGEX);
if (shebangMatch) {

0
lib/6to5/modules/amd.js Normal file
View File

View File

@ -0,0 +1,96 @@
module.exports = CommonJSModuleFormatter;
var util = require("../util");
var b = require("recast").types.builders;
var getSpecifierName = function (specifier) {
return specifier.name || specifier.id;
};
function CommonJSModuleFormatter(file) {
this.file = file;
}
CommonJSModuleFormatter.prototype.import = function (node, nodes) {
// import "foo";
nodes.push(util.template("require", {
MODULE_NAME: node.source.raw
}, true));
};
CommonJSModuleFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
var variableName = getSpecifierName(specifier);
var key = specifier.id.name;
// import foo from "foo";
if (specifier.type === "ImportDefaultSpecifier") {
key = b.identifier("default");
}
var templateName = "require-assign";
// import * as bar from "foo";
if (specifier.type !== "ImportNamespaceSpecifier") templateName += "-key";
nodes.push(util.template(templateName, {
VARIABLE_NAME: variableName.name,
MODULE_NAME: node.source.raw,
KEY: key
}));
};
CommonJSModuleFormatter.prototype.export = function (node, nodes) {
var declar = node.declaration;
if (node.default) {
util.ensureExpressionType(declar);
nodes.push(util.template("exports-default", {
VALUE: declar
}, true));
} else {
var id = declar.id;
if (declar.type === "VariableDeclaration") {
id = declar.declarations[0].id;
}
var assign = util.template("exports-assign", {
VALUE: id,
KEY: id
}, true);
nodes.push(declar);
if (declar.type === "FunctionDeclaration") {
assign._blockHoist = true;
}
nodes.push(assign);
}
};
CommonJSModuleFormatter.prototype.exportSpecifier = function (specifier, node, nodes) {
var variableName = getSpecifierName(specifier);
if (node.source) {
if (specifier.type === "ExportBatchSpecifier") {
// export * from "foo";
nodes.push(util.template("exports-wildcard", {
MODULE_NAME: node.source.raw
}, true));
} else {
// export { foo } from "test";
nodes.push(util.template("exports-require-assign-key", {
VARIABLE_NAME: variableName.name,
MODULE_NAME: node.source.raw,
KEY: specifier.id
}, true));
}
} else {
// export { foo };
nodes.push(util.template("exports-assign", {
VALUE: specifier.id,
KEY: variableName
}, true));
}
};

0
lib/6to5/modules/umd.js Normal file
View File

View File

@ -106,6 +106,10 @@ transform.transformers = {
useStrict: require("./transformers/use-strict")
};
transform.moduleFormatters = {
common: require("./modules/common")
};
_.each(transform.transformers, function (transformer, key) {
transform.transformers[key] = new Transformer(key, transformer);
});

View File

@ -11,13 +11,13 @@ function Transformer(key, transformer) {
Transformer.normalise = function (transformer) {
if (_.isFunction(transformer)) {
transformer = { ast: transformer };
} else {
}
_.each(transformer, function (fns, type) {
if (type === "ast") return;
if (_.isFunction(fns)) fns = { enter: fns };
transformer[type] = fns;
});
}
return transformer;
};
@ -27,8 +27,8 @@ Transformer.prototype.transform = function (file) {
var transformer = this.transformer;
var ast = file.ast;
if (transformer.ast) {
transformer.ast(ast, file);
if (transformer.ast && transformer.ast.enter) {
transformer.ast.enter(ast, file);
}
var build = function (exit) {
@ -57,6 +57,14 @@ Transformer.prototype.transform = function (file) {
enter: build(),
exit: build(true)
});
if (transformer.ast && transformer.ast.exit) {
transformer.ast.exit(ast, file);
}
if (file.moduleFormatter.transform) {
file.moduleFormatter.transform(ast);
}
};
Transformer.prototype.canRun = function (file) {

View File

@ -1,110 +1,28 @@
var util = require("../util");
var b = require("recast").types.builders;
var _ = require("lodash");
exports.ImportDeclaration = function (node) {
exports.ImportDeclaration = function (node, parent, file) {
var nodes = [];
if (node.specifiers.length) {
_.each(node.specifiers, function (specifier) {
var variableName = getSpecifierName(specifier);
var key = specifier.id.name;
// import foo from "foo";
if (specifier.type === "ImportDefaultSpecifier") {
key = b.identifier("default");
}
var templateName = "require-assign";
// import * as bar from "foo";
if (specifier.type !== "ImportNamespaceSpecifier") templateName += "-key";
nodes.push(util.template(templateName, {
VARIABLE_NAME: variableName.name,
MODULE_NAME: node.source.raw,
KEY: key
}));
file.moduleFormatter.importSpecifier(specifier, node, nodes);
});
} else {
// import "foo";
nodes.push(util.template("require", {
MODULE_NAME: node.source.raw
}, true));
file.moduleFormatter.import(node, nodes);
}
return nodes;
};
var pushExportSpecifiers = function (node, nodes) {
_.each(node.specifiers, function (specifier) {
var variableName = getSpecifierName(specifier);
if (node.source) {
if (specifier.type === "ExportBatchSpecifier") {
// export * from "foo";
nodes.push(util.template("exports-wildcard", {
MODULE_NAME: node.source.raw
}, true));
} else {
// export { foo } from "test";
nodes.push(util.template("exports-require-assign-key", {
VARIABLE_NAME: variableName.name,
MODULE_NAME: node.source.raw,
KEY: specifier.id
}, true));
}
} else {
// export { foo };
nodes.push(util.template("exports-assign", {
VALUE: specifier.id,
KEY: variableName
}, true));
}
});
};
var getSpecifierName = function (specifier) {
return specifier.name || specifier.id;
};
var pushExportDeclaration = function (node, parent, nodes) {
var declar = node.declaration;
if (node.default) {
util.ensureExpressionType(declar);
nodes.push(util.template("exports-default", {
VALUE: declar
}, true));
} else {
var id = declar.id;
if (declar.type === "VariableDeclaration") {
id = declar.declarations[0].id;
}
var assign = util.template("exports-assign", {
VALUE: id,
KEY: id
}, true);
nodes.push(declar);
if (declar.type === "FunctionDeclaration") {
assign._blockHoist = true;
}
nodes.push(assign);
}
};
exports.ExportDeclaration = function (node, parent) {
exports.ExportDeclaration = function (node, parent, file) {
var nodes = [];
if (node.declaration) {
pushExportDeclaration(node, parent, nodes);
file.moduleFormatter.export(node, nodes);
} else {
pushExportSpecifiers(node, nodes);
_.each(node.specifiers, function (specifier) {
file.moduleFormatter.exportSpecifier(specifier, node, nodes);
});
}
return nodes;

View File

@ -0,0 +1,3 @@
{
"modules": "common"
}