* Add transform-new-target to standalone. * Add missed stage-3 plugins for babel-standalone.
263 lines
12 KiB
JavaScript
263 lines
12 KiB
JavaScript
/**
|
|
* Entry point for babel-standalone. This wraps Babel's API in a version that's
|
|
* friendlier for use in web browers. It removes the automagical detection of
|
|
* plugins, instead explicitly registering all the available plugins and
|
|
* presets, and requiring custom ones to be registered through `registerPlugin`
|
|
* and `registerPreset` respectively.
|
|
*/
|
|
|
|
/* global VERSION */
|
|
/* eslint-disable max-len */
|
|
|
|
import * as Babel from "babel-core";
|
|
|
|
import { runScripts } from "./transformScriptTags";
|
|
|
|
const isArray =
|
|
Array.isArray ||
|
|
(arg => Object.prototype.toString.call(arg) === "[object Array]");
|
|
|
|
/**
|
|
* Loads the given name (or [name, options] pair) from the given table object
|
|
* holding the available presets or plugins.
|
|
*
|
|
* Returns undefined if the preset or plugin is not available; passes through
|
|
* name unmodified if it (or the first element of the pair) is not a string.
|
|
*/
|
|
function loadBuiltin(builtinTable, name) {
|
|
if (isArray(name) && typeof name[0] === "string") {
|
|
if (builtinTable.hasOwnProperty(name[0])) {
|
|
return [builtinTable[name[0]]].concat(name.slice(1));
|
|
}
|
|
return;
|
|
} else if (typeof name === "string") {
|
|
return builtinTable[name];
|
|
}
|
|
// Could be an actual preset/plugin module
|
|
return name;
|
|
}
|
|
|
|
/**
|
|
* Parses plugin names and presets from the specified options.
|
|
*/
|
|
function processOptions(options) {
|
|
// Parse preset names
|
|
const presets = (options.presets || []).map(presetName => {
|
|
const preset = loadBuiltin(availablePresets, presetName);
|
|
|
|
if (preset) {
|
|
// workaround for babel issue
|
|
// at some point, babel copies the preset, losing the non-enumerable
|
|
// buildPreset key; convert it into an enumerable key.
|
|
if (
|
|
isArray(preset) &&
|
|
typeof preset[0] === "object" &&
|
|
preset[0].hasOwnProperty("buildPreset")
|
|
) {
|
|
preset[0] = { ...preset[0], buildPreset: preset[0].buildPreset };
|
|
}
|
|
} else {
|
|
throw new Error(
|
|
`Invalid preset specified in Babel options: "${presetName}"`,
|
|
);
|
|
}
|
|
return preset;
|
|
});
|
|
|
|
// Parse plugin names
|
|
const plugins = (options.plugins || []).map(pluginName => {
|
|
const plugin = loadBuiltin(availablePlugins, pluginName);
|
|
|
|
if (!plugin) {
|
|
throw new Error(
|
|
`Invalid plugin specified in Babel options: "${pluginName}"`,
|
|
);
|
|
}
|
|
return plugin;
|
|
});
|
|
|
|
return {
|
|
babelrc: false,
|
|
...options,
|
|
presets,
|
|
plugins,
|
|
};
|
|
}
|
|
|
|
export function transform(code, options) {
|
|
return Babel.transform(code, processOptions(options));
|
|
}
|
|
|
|
export function transformFromAst(ast, code, options) {
|
|
return Babel.transformFromAst(ast, code, processOptions(options));
|
|
}
|
|
export const availablePlugins = {};
|
|
export const availablePresets = {};
|
|
export const buildExternalHelpers = Babel.buildExternalHelpers;
|
|
/**
|
|
* Registers a named plugin for use with Babel.
|
|
*/
|
|
export function registerPlugin(name, plugin) {
|
|
if (availablePlugins.hasOwnProperty(name)) {
|
|
console.warn(
|
|
`A plugin named "${name}" is already registered, it will be overridden`,
|
|
);
|
|
}
|
|
availablePlugins[name] = plugin;
|
|
}
|
|
/**
|
|
* Registers multiple plugins for use with Babel. `newPlugins` should be an object where the key
|
|
* is the name of the plugin, and the value is the plugin itself.
|
|
*/
|
|
export function registerPlugins(newPlugins) {
|
|
Object.keys(newPlugins).forEach(name =>
|
|
registerPlugin(name, newPlugins[name]),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Registers a named preset for use with Babel.
|
|
*/
|
|
export function registerPreset(name, preset) {
|
|
if (availablePresets.hasOwnProperty(name)) {
|
|
console.warn(
|
|
`A preset named "${name}" is already registered, it will be overridden`,
|
|
);
|
|
}
|
|
availablePresets[name] = preset;
|
|
}
|
|
/**
|
|
* Registers multiple presets for use with Babel. `newPresets` should be an object where the key
|
|
* is the name of the preset, and the value is the preset itself.
|
|
*/
|
|
export function registerPresets(newPresets) {
|
|
Object.keys(newPresets).forEach(name =>
|
|
registerPreset(name, newPresets[name]),
|
|
);
|
|
}
|
|
|
|
// All the plugins we should bundle
|
|
registerPlugins({
|
|
"check-es2015-constants": require("babel-plugin-check-es2015-constants"),
|
|
"external-helpers": require("babel-plugin-external-helpers"),
|
|
"syntax-async-functions": require("babel-plugin-syntax-async-functions"),
|
|
"syntax-async-generators": require("babel-plugin-syntax-async-generators"),
|
|
"syntax-class-properties": require("babel-plugin-syntax-class-properties"),
|
|
"syntax-decorators": require("babel-plugin-syntax-decorators"),
|
|
"syntax-do-expressions": require("babel-plugin-syntax-do-expressions"),
|
|
"syntax-dynamic-import": require("babel-plugin-syntax-dynamic-import"),
|
|
"syntax-exponentiation-operator": require("babel-plugin-syntax-exponentiation-operator"),
|
|
"syntax-export-extensions": require("babel-plugin-syntax-export-extensions"),
|
|
"syntax-flow": require("babel-plugin-syntax-flow"),
|
|
"syntax-function-bind": require("babel-plugin-syntax-function-bind"),
|
|
"syntax-function-sent": require("babel-plugin-syntax-function-sent"),
|
|
"syntax-jsx": require("babel-plugin-syntax-jsx"),
|
|
"syntax-object-rest-spread": require("babel-plugin-syntax-object-rest-spread"),
|
|
"syntax-optional-catch-binding": require("babel-plugin-syntax-optional-catch-binding"),
|
|
"syntax-trailing-function-commas": require("babel-plugin-syntax-trailing-function-commas"),
|
|
"transform-async-functions": require("babel-plugin-transform-async-functions"),
|
|
"transform-async-to-generator": require("babel-plugin-transform-async-to-generator"),
|
|
"transform-async-to-module-method": require("babel-plugin-transform-async-to-module-method"),
|
|
"transform-class-properties": require("babel-plugin-transform-class-properties"),
|
|
"transform-decorators": require("babel-plugin-transform-decorators"),
|
|
"transform-do-expressions": require("babel-plugin-transform-do-expressions"),
|
|
"transform-es2015-arrow-functions": require("babel-plugin-transform-es2015-arrow-functions"),
|
|
"transform-es2015-block-scoped-functions": require("babel-plugin-transform-es2015-block-scoped-functions"),
|
|
"transform-es2015-block-scoping": require("babel-plugin-transform-es2015-block-scoping"),
|
|
"transform-es2015-classes": require("babel-plugin-transform-es2015-classes"),
|
|
"transform-es2015-computed-properties": require("babel-plugin-transform-es2015-computed-properties"),
|
|
"transform-es2015-destructuring": require("babel-plugin-transform-es2015-destructuring"),
|
|
"transform-es2015-duplicate-keys": require("babel-plugin-transform-es2015-duplicate-keys"),
|
|
"transform-es2015-for-of": require("babel-plugin-transform-es2015-for-of"),
|
|
"transform-es2015-function-name": require("babel-plugin-transform-es2015-function-name"),
|
|
"transform-es2015-instanceof": require("babel-plugin-transform-es2015-instanceof"),
|
|
"transform-es2015-literals": require("babel-plugin-transform-es2015-literals"),
|
|
"transform-es2015-modules-amd": require("babel-plugin-transform-es2015-modules-amd"),
|
|
"transform-es2015-modules-commonjs": require("babel-plugin-transform-es2015-modules-commonjs"),
|
|
"transform-es2015-modules-systemjs": require("babel-plugin-transform-es2015-modules-systemjs"),
|
|
"transform-es2015-modules-umd": require("babel-plugin-transform-es2015-modules-umd"),
|
|
"transform-es2015-object-super": require("babel-plugin-transform-es2015-object-super"),
|
|
"transform-es2015-parameters": require("babel-plugin-transform-es2015-parameters"),
|
|
"transform-es2015-shorthand-properties": require("babel-plugin-transform-es2015-shorthand-properties"),
|
|
"transform-es2015-spread": require("babel-plugin-transform-es2015-spread"),
|
|
"transform-es2015-sticky-regex": require("babel-plugin-transform-es2015-sticky-regex"),
|
|
"transform-es2015-template-literals": require("babel-plugin-transform-es2015-template-literals"),
|
|
"transform-es2015-typeof-symbol": require("babel-plugin-transform-es2015-typeof-symbol"),
|
|
"transform-es2015-unicode-regex": require("babel-plugin-transform-es2015-unicode-regex"),
|
|
"transform-es3-member-expression-literals": require("babel-plugin-transform-es3-member-expression-literals"),
|
|
"transform-es3-property-literals": require("babel-plugin-transform-es3-property-literals"),
|
|
"transform-es5-property-mutators": require("babel-plugin-transform-es5-property-mutators"),
|
|
"transform-eval": require("babel-plugin-transform-eval"),
|
|
"transform-exponentiation-operator": require("babel-plugin-transform-exponentiation-operator"),
|
|
"transform-export-extensions": require("babel-plugin-transform-export-extensions"),
|
|
"transform-flow-comments": require("babel-plugin-transform-flow-comments"),
|
|
"transform-flow-strip-types": require("babel-plugin-transform-flow-strip-types"),
|
|
"transform-function-bind": require("babel-plugin-transform-function-bind"),
|
|
"transform-jscript": require("babel-plugin-transform-jscript"),
|
|
"transform-new-target": require("babel-plugin-transform-new-target"),
|
|
"transform-object-assign": require("babel-plugin-transform-object-assign"),
|
|
"transform-object-rest-spread": require("babel-plugin-transform-object-rest-spread"),
|
|
"transform-object-set-prototype-of-to-assign": require("babel-plugin-transform-object-set-prototype-of-to-assign"),
|
|
"transform-optional-catch-binding": require("babel-plugin-transform-optional-catch-binding"),
|
|
"transform-proto-to-assign": require("babel-plugin-transform-proto-to-assign"),
|
|
"transform-react-constant-elements": require("babel-plugin-transform-react-constant-elements"),
|
|
"transform-react-display-name": require("babel-plugin-transform-react-display-name"),
|
|
"transform-react-inline-elements": require("babel-plugin-transform-react-inline-elements"),
|
|
"transform-react-jsx": require("babel-plugin-transform-react-jsx"),
|
|
"transform-react-jsx-compat": require("babel-plugin-transform-react-jsx-compat"),
|
|
"transform-react-jsx-self": require("babel-plugin-transform-react-jsx-self"),
|
|
"transform-react-jsx-source": require("babel-plugin-transform-react-jsx-source"),
|
|
"transform-regenerator": require("babel-plugin-transform-regenerator"),
|
|
"transform-runtime": require("babel-plugin-transform-runtime"),
|
|
"transform-strict-mode": require("babel-plugin-transform-strict-mode"),
|
|
"transform-unicode-property-regex": require("babel-plugin-transform-unicode-property-regex"),
|
|
});
|
|
|
|
// All the presets we should bundle
|
|
registerPresets({
|
|
es2015: require("babel-preset-es2015"),
|
|
es2016: require("babel-preset-es2016"),
|
|
es2017: require("babel-preset-es2017"),
|
|
react: require("babel-preset-react"),
|
|
"stage-0": require("babel-preset-stage-0"),
|
|
"stage-1": require("babel-preset-stage-1"),
|
|
"stage-2": require("babel-preset-stage-2"),
|
|
"stage-3": require("babel-preset-stage-3"),
|
|
"es2015-loose": {
|
|
presets: [[require("babel-preset-es2015"), { loose: true }]],
|
|
},
|
|
// ES2015 preset with es2015-modules-commonjs removed
|
|
"es2015-no-commonjs": {
|
|
presets: [[require("babel-preset-es2015"), { modules: false }]],
|
|
},
|
|
typescript: require("babel-preset-typescript"),
|
|
flow: require("babel-preset-flow"),
|
|
});
|
|
|
|
export const version = VERSION;
|
|
|
|
// Listen for load event if we're in a browser and then kick off finding and
|
|
// running of scripts with "text/babel" type.
|
|
if (typeof window !== "undefined" && window && window.addEventListener) {
|
|
window.addEventListener(
|
|
"DOMContentLoaded",
|
|
() => transformScriptTags(),
|
|
false,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Transform <script> tags with "text/babel" type.
|
|
* @param {Array} scriptTags specify script tags to transform, transform all in the <head> if not given
|
|
*/
|
|
export function transformScriptTags(scriptTags) {
|
|
runScripts(transform, scriptTags);
|
|
}
|
|
|
|
/**
|
|
* Disables automatic transformation of <script> tags with "text/babel" type.
|
|
*/
|
|
export function disableScriptTags() {
|
|
window.removeEventListener("DOMContentLoaded", transformScriptTags);
|
|
}
|