168 lines
4.0 KiB
JavaScript
168 lines
4.0 KiB
JavaScript
import * as helpers from "@babel/helpers";
|
|
import generator from "@babel/generator";
|
|
import template from "@babel/template";
|
|
import * as t from "@babel/types";
|
|
import File from "../transformation/file/file";
|
|
|
|
// Wrapped to avoid wasting time parsing this when almost no-one uses
|
|
// build-external-helpers.
|
|
const buildUmdWrapper = replacements =>
|
|
template`
|
|
(function (root, factory) {
|
|
if (typeof define === "function" && define.amd) {
|
|
define(AMD_ARGUMENTS, factory);
|
|
} else if (typeof exports === "object") {
|
|
factory(COMMON_ARGUMENTS);
|
|
} else {
|
|
factory(BROWSER_ARGUMENTS);
|
|
}
|
|
})(UMD_ROOT, function (FACTORY_PARAMETERS) {
|
|
FACTORY_BODY
|
|
});
|
|
`(replacements);
|
|
|
|
function buildGlobal(whitelist) {
|
|
const namespace = t.identifier("babelHelpers");
|
|
|
|
const body = [];
|
|
const container = t.functionExpression(
|
|
null,
|
|
[t.identifier("global")],
|
|
t.blockStatement(body),
|
|
);
|
|
const tree = t.program([
|
|
t.expressionStatement(
|
|
t.callExpression(container, [
|
|
// typeof global === "undefined" ? self : global
|
|
t.conditionalExpression(
|
|
t.binaryExpression(
|
|
"===",
|
|
t.unaryExpression("typeof", t.identifier("global")),
|
|
t.stringLiteral("undefined"),
|
|
),
|
|
t.identifier("self"),
|
|
t.identifier("global"),
|
|
),
|
|
]),
|
|
),
|
|
]);
|
|
|
|
body.push(
|
|
t.variableDeclaration("var", [
|
|
t.variableDeclarator(
|
|
namespace,
|
|
t.assignmentExpression(
|
|
"=",
|
|
t.memberExpression(t.identifier("global"), namespace),
|
|
t.objectExpression([]),
|
|
),
|
|
),
|
|
]),
|
|
);
|
|
|
|
buildHelpers(body, namespace, whitelist);
|
|
|
|
return tree;
|
|
}
|
|
|
|
function buildModule(whitelist) {
|
|
const body = [];
|
|
const refs = buildHelpers(body, null, whitelist);
|
|
|
|
body.unshift(
|
|
t.exportNamedDeclaration(
|
|
null,
|
|
Object.keys(refs).map(name => {
|
|
return t.exportSpecifier(t.cloneNode(refs[name]), t.identifier(name));
|
|
}),
|
|
),
|
|
);
|
|
|
|
return t.program(body, [], "module");
|
|
}
|
|
|
|
function buildUmd(whitelist) {
|
|
const namespace = t.identifier("babelHelpers");
|
|
|
|
const body = [];
|
|
body.push(
|
|
t.variableDeclaration("var", [
|
|
t.variableDeclarator(namespace, t.identifier("global")),
|
|
]),
|
|
);
|
|
|
|
buildHelpers(body, namespace, whitelist);
|
|
|
|
return t.program([
|
|
buildUmdWrapper({
|
|
FACTORY_PARAMETERS: t.identifier("global"),
|
|
BROWSER_ARGUMENTS: t.assignmentExpression(
|
|
"=",
|
|
t.memberExpression(t.identifier("root"), namespace),
|
|
t.objectExpression([]),
|
|
),
|
|
COMMON_ARGUMENTS: t.identifier("exports"),
|
|
AMD_ARGUMENTS: t.arrayExpression([t.stringLiteral("exports")]),
|
|
FACTORY_BODY: body,
|
|
UMD_ROOT: t.identifier("this"),
|
|
}),
|
|
]);
|
|
}
|
|
|
|
function buildVar(whitelist) {
|
|
const namespace = t.identifier("babelHelpers");
|
|
|
|
const body = [];
|
|
body.push(
|
|
t.variableDeclaration("var", [
|
|
t.variableDeclarator(namespace, t.objectExpression([])),
|
|
]),
|
|
);
|
|
const tree = t.program(body);
|
|
buildHelpers(body, namespace, whitelist);
|
|
body.push(t.expressionStatement(namespace));
|
|
return tree;
|
|
}
|
|
|
|
function buildHelpers(body, namespace, whitelist) {
|
|
const getHelperReference = name => {
|
|
return namespace
|
|
? t.memberExpression(namespace, t.identifier(name))
|
|
: t.identifier(`_${name}`);
|
|
};
|
|
|
|
const refs = {};
|
|
helpers.list.forEach(function (name) {
|
|
if (whitelist && whitelist.indexOf(name) < 0) return;
|
|
|
|
const ref = (refs[name] = getHelperReference(name));
|
|
|
|
helpers.ensure(name, File);
|
|
const { nodes } = helpers.get(name, getHelperReference, ref);
|
|
|
|
body.push(...nodes);
|
|
});
|
|
return refs;
|
|
}
|
|
export default function (
|
|
whitelist?: Array<string>,
|
|
outputType: "global" | "module" | "umd" | "var" = "global",
|
|
) {
|
|
let tree;
|
|
|
|
const build = {
|
|
global: buildGlobal,
|
|
module: buildModule,
|
|
umd: buildUmd,
|
|
var: buildVar,
|
|
}[outputType];
|
|
|
|
if (build) {
|
|
tree = build(whitelist);
|
|
} else {
|
|
throw new Error(`Unsupported output type ${outputType}`);
|
|
}
|
|
|
|
return generator(tree).code;
|
|
}
|