Merge branch '7.0' into fix-require-debug
This commit is contained in:
@@ -1,112 +0,0 @@
|
||||
/* eslint max-len: 0 */
|
||||
/* eslint no-new-func: 0 */
|
||||
|
||||
import { transform } from "./node";
|
||||
export {
|
||||
File,
|
||||
options,
|
||||
buildExternalHelpers,
|
||||
template,
|
||||
version,
|
||||
util,
|
||||
messages,
|
||||
types,
|
||||
traverse,
|
||||
OptionManager,
|
||||
Plugin,
|
||||
Pipeline,
|
||||
analyse,
|
||||
transform,
|
||||
transformFromAst,
|
||||
transformFile,
|
||||
transformFileSync
|
||||
} from "./node";
|
||||
|
||||
export function run(code: string, opts: Object = {}): any {
|
||||
return new Function(transform(code, opts).code)();
|
||||
}
|
||||
|
||||
export function load(url: string, callback: Function, opts: Object = {}, hold?: boolean) {
|
||||
opts.filename = opts.filename || url;
|
||||
|
||||
let xhr = global.ActiveXObject ? new global.ActiveXObject("Microsoft.XMLHTTP") : new global.XMLHttpRequest();
|
||||
xhr.open("GET", url, true);
|
||||
if ("overrideMimeType" in xhr) xhr.overrideMimeType("text/plain");
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState !== 4) return;
|
||||
|
||||
let status = xhr.status;
|
||||
if (status === 0 || status === 200) {
|
||||
let param = [xhr.responseText, opts];
|
||||
if (!hold) run(param);
|
||||
if (callback) callback(param);
|
||||
} else {
|
||||
throw new Error(`Could not load ${url}`);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send(null);
|
||||
}
|
||||
|
||||
function runScripts() {
|
||||
let scripts: Array<Array<any> | Object> = [];
|
||||
let types = ["text/ecmascript-6", "text/6to5", "text/babel", "module"];
|
||||
let index = 0;
|
||||
|
||||
/**
|
||||
* Transform and execute script. Ensures correct load order.
|
||||
*/
|
||||
|
||||
function exec() {
|
||||
let param = scripts[index];
|
||||
if (param instanceof Array) {
|
||||
run(param, index);
|
||||
index++;
|
||||
exec();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load, transform, and execute all scripts.
|
||||
*/
|
||||
|
||||
function run(script: Object, i: number) {
|
||||
let opts = {};
|
||||
|
||||
if (script.src) {
|
||||
load(script.src, function (param) {
|
||||
scripts[i] = param;
|
||||
exec();
|
||||
}, opts, true);
|
||||
} else {
|
||||
opts.filename = "embedded";
|
||||
scripts[i] = [script.innerHTML, opts];
|
||||
}
|
||||
}
|
||||
|
||||
// Collect scripts with Babel `types`.
|
||||
|
||||
let _scripts = global.document.getElementsByTagName("script");
|
||||
|
||||
for (let i = 0; i < _scripts.length; ++i) {
|
||||
let _script = _scripts[i];
|
||||
if (types.indexOf(_script.type) >= 0) scripts.push(_script);
|
||||
}
|
||||
|
||||
for (let i = 0; i < scripts.length; i++) {
|
||||
run(scripts[i], i);
|
||||
}
|
||||
|
||||
exec();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register load event to transform and execute scripts.
|
||||
*/
|
||||
|
||||
if (global.addEventListener) {
|
||||
global.addEventListener("DOMContentLoaded", runScripts, false);
|
||||
} else if (global.attachEvent) {
|
||||
global.attachEvent("onload", runScripts);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default function getPossiblePluginNames(pluginName: string): Array<string> {
|
||||
return [`babel-plugin-${pluginName}`, pluginName];
|
||||
}
|
||||
13
packages/babel-core/src/helpers/get-possible-preset-names.js
Normal file
13
packages/babel-core/src/helpers/get-possible-preset-names.js
Normal file
@@ -0,0 +1,13 @@
|
||||
export default function getPossiblePresetNames(presetName: string): Array<string> {
|
||||
const possibleNames = [`babel-preset-${presetName}`, presetName];
|
||||
|
||||
// trying to resolve @organization shortcat
|
||||
// @foo/es2015 -> @foo/babel-preset-es2015
|
||||
const matches = presetName.match(/^(@[^/]+)\/(.+)$/);
|
||||
if (matches) {
|
||||
const [, orgName, presetPath] = matches;
|
||||
possibleNames.push(`${orgName}/babel-preset-${presetPath}`);
|
||||
}
|
||||
|
||||
return possibleNames;
|
||||
}
|
||||
@@ -5,9 +5,9 @@ export default function (dest?: Object, src?: Object): ?Object {
|
||||
|
||||
return mergeWith(dest, src, function (a, b) {
|
||||
if (b && Array.isArray(a)) {
|
||||
let newArray = b.slice(0);
|
||||
const newArray = b.slice(0);
|
||||
|
||||
for (let item of a) {
|
||||
for (const item of a) {
|
||||
if (newArray.indexOf(item) < 0) {
|
||||
newArray.push(item);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import resolve from "./resolve";
|
||||
|
||||
export default function resolveFromPossibleNames(possibleNames: Array<string>, dirname: string): ?string {
|
||||
return possibleNames.reduce((accum, curr) => accum || resolve(curr, dirname), null);
|
||||
}
|
||||
6
packages/babel-core/src/helpers/resolve-plugin.js
Normal file
6
packages/babel-core/src/helpers/resolve-plugin.js
Normal file
@@ -0,0 +1,6 @@
|
||||
import resolveFromPossibleNames from "./resolve-from-possible-names";
|
||||
import getPossiblePluginNames from "./get-possible-plugin-names";
|
||||
|
||||
export default function resolvePlugin(pluginName: string, dirname: string = process.cwd()): ?string {
|
||||
return resolveFromPossibleNames(getPossiblePluginNames(pluginName), dirname);
|
||||
}
|
||||
6
packages/babel-core/src/helpers/resolve-preset.js
Normal file
6
packages/babel-core/src/helpers/resolve-preset.js
Normal file
@@ -0,0 +1,6 @@
|
||||
import resolveFromPossibleNames from "./resolve-from-possible-names";
|
||||
import getPossiblePresetNames from "./get-possible-preset-names";
|
||||
|
||||
export default function resolvePreset(presetName: string, dirname: string = process.cwd()): ?string {
|
||||
return resolveFromPossibleNames(getPossiblePresetNames(presetName), dirname);
|
||||
}
|
||||
@@ -1,33 +1,8 @@
|
||||
import Module from "module";
|
||||
import path from "path";
|
||||
|
||||
let relativeModules = {};
|
||||
import resolve from "resolve";
|
||||
|
||||
export default function (loc: string, relative: string = process.cwd()): ?string {
|
||||
// we're in the browser, probably
|
||||
if (typeof Module === "object") return null;
|
||||
|
||||
let relativeMod = relativeModules[relative];
|
||||
|
||||
if (!relativeMod) {
|
||||
relativeMod = new Module;
|
||||
|
||||
// We need to define an id and filename on our "fake" relative` module so that
|
||||
// Node knows what "." means in the case of us trying to resolve a plugin
|
||||
// such as "./myPlugins/somePlugin.js". If we don't specify id and filename here,
|
||||
// Node presumes "." is process.cwd(), not our relative path.
|
||||
// Since this fake module is never "loaded", we don't have to worry about mutating
|
||||
// any global Node module cache state here.
|
||||
let filename = path.join(relative, ".babelrc");
|
||||
relativeMod.id = filename;
|
||||
relativeMod.filename = filename;
|
||||
|
||||
relativeMod.paths = Module._nodeModulePaths(relative);
|
||||
relativeModules[relative] = relativeMod;
|
||||
}
|
||||
|
||||
try {
|
||||
return Module._resolveFilename(loc, relativeMod);
|
||||
return resolve.sync(loc, { basedir: relative });
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import isFunction from "lodash/isFunction";
|
||||
import fs from "fs";
|
||||
|
||||
export { default as File } from "../transformation/file";
|
||||
export { default as options } from "../transformation/file/options/config";
|
||||
export { default as buildExternalHelpers } from "../tools/build-external-helpers";
|
||||
export { default as File } from "./transformation/file";
|
||||
export { default as options } from "./transformation/file/options/config";
|
||||
export { default as buildExternalHelpers } from "./tools/build-external-helpers";
|
||||
export { default as template } from "babel-template";
|
||||
export { version } from "../../package";
|
||||
export { default as resolvePlugin } from "./helpers/resolve-plugin";
|
||||
export { default as resolvePreset } from "./helpers/resolve-preset";
|
||||
export { version } from "../package";
|
||||
|
||||
import * as util from "../util";
|
||||
import * as util from "./util";
|
||||
export { util };
|
||||
|
||||
import * as messages from "babel-messages";
|
||||
@@ -19,23 +20,18 @@ export { t as types };
|
||||
import traverse from "babel-traverse";
|
||||
export { traverse };
|
||||
|
||||
import OptionManager from "../transformation/file/options/option-manager";
|
||||
import OptionManager from "./transformation/file/options/option-manager";
|
||||
export { OptionManager };
|
||||
|
||||
export function Plugin(alias) {
|
||||
throw new Error(`The (${alias}) Babel 5 plugin is being run with Babel 6.`);
|
||||
}
|
||||
|
||||
import Pipeline from "../transformation/pipeline";
|
||||
export { Pipeline };
|
||||
|
||||
let pipeline = new Pipeline;
|
||||
export let analyse = pipeline.analyse.bind(pipeline);
|
||||
export let transform = pipeline.transform.bind(pipeline);
|
||||
export let transformFromAst = pipeline.transformFromAst.bind(pipeline);
|
||||
import { transform, analyse, transformFromAst } from "./transformation/pipeline";
|
||||
export { transform, analyse, transformFromAst };
|
||||
|
||||
export function transformFile(filename: string, opts?: Object, callback: Function) {
|
||||
if (isFunction(opts)) {
|
||||
if (typeof opts === "function") {
|
||||
callback = opts;
|
||||
opts = {};
|
||||
}
|
||||
@@ -1,22 +1,24 @@
|
||||
export default class Store extends Map {
|
||||
export default class Store {
|
||||
constructor() {
|
||||
super();
|
||||
this.dynamicData = {};
|
||||
this._map = new Map();
|
||||
this._map.dynamicData = {};
|
||||
}
|
||||
|
||||
dynamicData: Object;
|
||||
|
||||
setDynamic(key, fn) {
|
||||
this.dynamicData[key] = fn;
|
||||
this._map.dynamicData[key] = fn;
|
||||
}
|
||||
|
||||
set(key: string, val) {
|
||||
this._map.set(key, val);
|
||||
}
|
||||
|
||||
get(key: string): any {
|
||||
if (this.has(key)) {
|
||||
return super.get(key);
|
||||
if (this._map.has(key)) {
|
||||
return this._map.get(key);
|
||||
} else {
|
||||
if (Object.prototype.hasOwnProperty.call(this.dynamicData, key)) {
|
||||
let val = this.dynamicData[key]();
|
||||
this.set(key, val);
|
||||
if (Object.prototype.hasOwnProperty.call(this._map.dynamicData, key)) {
|
||||
const val = this._map.dynamicData[key]();
|
||||
this._map.set(key, val);
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
/* eslint max-len: 0 */
|
||||
|
||||
import * as helpers from "babel-helpers";
|
||||
import generator from "babel-generator";
|
||||
import * as messages from "babel-messages";
|
||||
import template from "babel-template";
|
||||
import each from "lodash/each";
|
||||
import * as t from "babel-types";
|
||||
|
||||
let buildUmdWrapper = template(`
|
||||
const buildUmdWrapper = template(`
|
||||
(function (root, factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define(AMD_ARGUMENTS, factory);
|
||||
@@ -22,15 +19,17 @@ let buildUmdWrapper = template(`
|
||||
`);
|
||||
|
||||
function buildGlobal(namespace, builder) {
|
||||
let body = [];
|
||||
let container = t.functionExpression(null, [t.identifier("global")], t.blockStatement(body));
|
||||
let tree = t.program([t.expressionStatement(t.callExpression(container, [helpers.get("selfGlobal")]))]);
|
||||
const body = [];
|
||||
const container = t.functionExpression(null, [t.identifier("global")], t.blockStatement(body));
|
||||
const tree = t.program([
|
||||
t.expressionStatement(t.callExpression(container, [helpers.get("selfGlobal")]))]);
|
||||
|
||||
body.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(
|
||||
namespace,
|
||||
t.assignmentExpression("=", t.memberExpression(t.identifier("global"), namespace), t.objectExpression([]))
|
||||
)
|
||||
t.assignmentExpression("=", t.memberExpression(t.identifier("global"), namespace),
|
||||
t.objectExpression([]))
|
||||
),
|
||||
]));
|
||||
|
||||
builder(body);
|
||||
@@ -39,9 +38,9 @@ function buildGlobal(namespace, builder) {
|
||||
}
|
||||
|
||||
function buildUmd(namespace, builder) {
|
||||
let body = [];
|
||||
const body = [];
|
||||
body.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(namespace, t.identifier("global"))
|
||||
t.variableDeclarator(namespace, t.identifier("global")),
|
||||
]));
|
||||
|
||||
builder(body);
|
||||
@@ -49,23 +48,23 @@ function buildUmd(namespace, builder) {
|
||||
return t.program([
|
||||
buildUmdWrapper({
|
||||
FACTORY_PARAMETERS: t.identifier("global"),
|
||||
BROWSER_ARGUMENTS: t.assignmentExpression(
|
||||
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")
|
||||
})
|
||||
COMMON_ARGUMENTS: t.identifier("exports"),
|
||||
AMD_ARGUMENTS: t.arrayExpression([t.stringLiteral("exports")]),
|
||||
FACTORY_BODY: body,
|
||||
UMD_ROOT: t.identifier("this"),
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
function buildVar(namespace, builder) {
|
||||
let body = [];
|
||||
const body = [];
|
||||
body.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(namespace, t.objectExpression([]))
|
||||
t.variableDeclarator(namespace, t.objectExpression([])),
|
||||
]));
|
||||
builder(body);
|
||||
body.push(t.expressionStatement(namespace));
|
||||
@@ -73,10 +72,10 @@ function buildVar(namespace, builder) {
|
||||
}
|
||||
|
||||
function buildHelpers(body, namespace, whitelist) {
|
||||
each(helpers.list, function (name) {
|
||||
helpers.list.forEach(function (name) {
|
||||
if (whitelist && whitelist.indexOf(name) < 0) return;
|
||||
|
||||
let key = t.identifier(name);
|
||||
const key = t.identifier(name);
|
||||
body.push(t.expressionStatement(
|
||||
t.assignmentExpression("=", t.memberExpression(namespace, key), helpers.get(name))
|
||||
));
|
||||
@@ -86,18 +85,18 @@ export default function (
|
||||
whitelist?: Array<string>,
|
||||
outputType: "global" | "umd" | "var" = "global",
|
||||
) {
|
||||
let namespace = t.identifier("babelHelpers");
|
||||
const namespace = t.identifier("babelHelpers");
|
||||
|
||||
let builder = function (body) {
|
||||
const builder = function (body) {
|
||||
return buildHelpers(body, namespace, whitelist);
|
||||
};
|
||||
|
||||
let tree;
|
||||
|
||||
let build = {
|
||||
const build = {
|
||||
global: buildGlobal,
|
||||
umd: buildUmd,
|
||||
var: buildVar,
|
||||
umd: buildUmd,
|
||||
var: buildVar,
|
||||
}[outputType];
|
||||
|
||||
if (build) {
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/* global BabelFileResult, BabelParserOptions, BabelFileMetadata */
|
||||
/* eslint max-len: 0 */
|
||||
|
||||
import getHelper from "babel-helpers";
|
||||
import * as metadataVisitor from "./metadata";
|
||||
import convertSourceMap from "convert-source-map";
|
||||
import OptionManager from "./options/option-manager";
|
||||
import type Pipeline from "../pipeline";
|
||||
import PluginPass from "../plugin-pass";
|
||||
import { NodePath, Hub, Scope } from "babel-traverse";
|
||||
import sourceMap from "source-map";
|
||||
@@ -16,7 +14,7 @@ import traverse from "babel-traverse";
|
||||
import Logger from "./logger";
|
||||
import Store from "../../store";
|
||||
import { parse } from "babylon";
|
||||
import * as util from "../../util";
|
||||
import * as util from "../../util";
|
||||
import path from "path";
|
||||
import * as t from "babel-types";
|
||||
|
||||
@@ -29,50 +27,48 @@ const shebangRegex = /^#!.*/;
|
||||
|
||||
const INTERNAL_PLUGINS = [
|
||||
[blockHoistPlugin],
|
||||
[shadowFunctionsPlugin]
|
||||
[shadowFunctionsPlugin],
|
||||
];
|
||||
|
||||
let errorVisitor = {
|
||||
const errorVisitor = {
|
||||
enter(path, state) {
|
||||
let loc = path.node.loc;
|
||||
const loc = path.node.loc;
|
||||
if (loc) {
|
||||
state.loc = loc;
|
||||
path.stop();
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default class File extends Store {
|
||||
constructor(opts: Object = {}, pipeline: Pipeline) {
|
||||
constructor(opts: Object = {}) {
|
||||
super();
|
||||
|
||||
this.pipeline = pipeline;
|
||||
this.log = new Logger(this, opts.filename || "unknown");
|
||||
|
||||
this.log = new Logger(this, opts.filename || "unknown");
|
||||
this.opts = this.initOptions(opts);
|
||||
opts = this.initOptions(opts);
|
||||
|
||||
let passes = [];
|
||||
if (opts.plugins) passes.push(opts.plugins);
|
||||
|
||||
// With "passPerPreset" enabled there may still be presets in the options.
|
||||
if (opts.presets) passes = passes.concat(opts.presets.map((preset) => preset.plugins).filter(Boolean));
|
||||
|
||||
this.pluginPasses = passes;
|
||||
this.opts = opts;
|
||||
|
||||
this.parserOpts = {
|
||||
sourceType: this.opts.sourceType,
|
||||
sourceType: this.opts.sourceType,
|
||||
sourceFileName: this.opts.filename,
|
||||
plugins: []
|
||||
plugins: [],
|
||||
};
|
||||
|
||||
this.pluginVisitors = [];
|
||||
this.pluginPasses = [];
|
||||
|
||||
// Plugins for top-level options.
|
||||
this.buildPluginsForOptions(this.opts);
|
||||
|
||||
// If we are in the "pass per preset" mode, build
|
||||
// also plugins for each preset.
|
||||
if (this.opts.passPerPreset) {
|
||||
// All the "per preset" options are inherited from the main options.
|
||||
this.perPresetOpts = [];
|
||||
this.opts.presets.forEach((presetOpts) => {
|
||||
let perPresetOpts = Object.assign(Object.create(this.opts), presetOpts);
|
||||
this.perPresetOpts.push(perPresetOpts);
|
||||
this.buildPluginsForOptions(perPresetOpts);
|
||||
});
|
||||
for (const pluginPairs of passes) {
|
||||
for (const [ plugin ] of pluginPairs) {
|
||||
if (plugin.manipulateOptions) {
|
||||
plugin.manipulateOptions(opts, this.parserOpts, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.metadata = {
|
||||
@@ -82,21 +78,21 @@ export default class File extends Store {
|
||||
imports: [],
|
||||
exports: {
|
||||
exported: [],
|
||||
specifiers: []
|
||||
}
|
||||
}
|
||||
specifiers: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
this.dynamicImportTypes = {};
|
||||
this.dynamicImportIds = {};
|
||||
this.dynamicImports = [];
|
||||
this.declarations = {};
|
||||
this.usedHelpers = {};
|
||||
this.dynamicImportIds = {};
|
||||
this.dynamicImports = [];
|
||||
this.declarations = {};
|
||||
this.usedHelpers = {};
|
||||
|
||||
this.path = null;
|
||||
this.ast = {};
|
||||
this.ast = {};
|
||||
|
||||
this.code = "";
|
||||
this.code = "";
|
||||
this.shebang = "";
|
||||
|
||||
this.hub = new Hub(this);
|
||||
@@ -104,9 +100,7 @@ export default class File extends Store {
|
||||
|
||||
static helpers: Array<string>;
|
||||
|
||||
pluginVisitors: Array<Object>;
|
||||
pluginPasses: Array<PluginPass>;
|
||||
pipeline: Pipeline;
|
||||
pluginPasses: Array<Array<[Plugin, Object]>>;
|
||||
parserOpts: BabelParserOptions;
|
||||
log: Logger;
|
||||
opts: Object;
|
||||
@@ -125,7 +119,7 @@ export default class File extends Store {
|
||||
|
||||
getMetadata() {
|
||||
let has = false;
|
||||
for (let node of (this.ast.program.body: Array<Object>)) {
|
||||
for (const node of (this.ast.program.body: Array<Object>)) {
|
||||
if (t.isModuleDeclaration(node)) {
|
||||
has = true;
|
||||
break;
|
||||
@@ -137,7 +131,7 @@ export default class File extends Store {
|
||||
}
|
||||
|
||||
initOptions(opts) {
|
||||
opts = new OptionManager(this.log, this.pipeline).init(opts);
|
||||
opts = this.log.wrap(() => new OptionManager().init(opts));
|
||||
|
||||
if (opts.inputSourceMap) {
|
||||
opts.sourceMaps = true;
|
||||
@@ -154,54 +148,29 @@ export default class File extends Store {
|
||||
if (opts.only) opts.only = util.arrayify(opts.only, util.regexify);
|
||||
|
||||
defaults(opts, {
|
||||
moduleRoot: opts.sourceRoot
|
||||
moduleRoot: opts.sourceRoot,
|
||||
});
|
||||
|
||||
defaults(opts, {
|
||||
sourceRoot: opts.moduleRoot
|
||||
sourceRoot: opts.moduleRoot,
|
||||
});
|
||||
|
||||
defaults(opts, {
|
||||
filenameRelative: opts.filename
|
||||
filenameRelative: opts.filename,
|
||||
});
|
||||
|
||||
let basenameRelative = path.basename(opts.filenameRelative);
|
||||
const basenameRelative = path.basename(opts.filenameRelative);
|
||||
|
||||
defaults(opts, {
|
||||
sourceFileName: basenameRelative,
|
||||
sourceMapTarget: basenameRelative
|
||||
sourceFileName: basenameRelative,
|
||||
sourceMapTarget: basenameRelative,
|
||||
});
|
||||
|
||||
return opts;
|
||||
}
|
||||
|
||||
buildPluginsForOptions(opts) {
|
||||
if (!Array.isArray(opts.plugins)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let plugins: Array<[PluginPass, Object]> = opts.plugins.concat(INTERNAL_PLUGINS);
|
||||
let currentPluginVisitors = [];
|
||||
let currentPluginPasses = [];
|
||||
|
||||
// init plugins!
|
||||
for (let ref of plugins) {
|
||||
let [plugin, pluginOpts] = ref; // todo: fix - can't embed in loop head because of flow bug
|
||||
|
||||
currentPluginVisitors.push(plugin.visitor);
|
||||
currentPluginPasses.push(new PluginPass(this, plugin, pluginOpts));
|
||||
|
||||
if (plugin.manipulateOptions) {
|
||||
plugin.manipulateOptions(opts, this.parserOpts, this);
|
||||
}
|
||||
}
|
||||
|
||||
this.pluginVisitors.push(currentPluginVisitors);
|
||||
this.pluginPasses.push(currentPluginPasses);
|
||||
}
|
||||
|
||||
getModuleName(): ?string {
|
||||
let opts = this.opts;
|
||||
const opts = this.opts;
|
||||
if (!opts.moduleIds) {
|
||||
return null;
|
||||
}
|
||||
@@ -224,7 +193,7 @@ export default class File extends Store {
|
||||
|
||||
if (opts.sourceRoot != null) {
|
||||
// remove sourceRoot from filename
|
||||
let sourceRootRegEx = new RegExp("^" + opts.sourceRoot + "\/?");
|
||||
const sourceRootRegEx = new RegExp("^" + opts.sourceRoot + "\/?");
|
||||
filenameRelative = filenameRelative.replace(sourceRootRegEx, "");
|
||||
}
|
||||
|
||||
@@ -245,20 +214,20 @@ export default class File extends Store {
|
||||
}
|
||||
|
||||
resolveModuleSource(source: string): string {
|
||||
let resolveModuleSource = this.opts.resolveModuleSource;
|
||||
const resolveModuleSource = this.opts.resolveModuleSource;
|
||||
if (resolveModuleSource) source = resolveModuleSource(source, this.opts.filename);
|
||||
return source;
|
||||
}
|
||||
|
||||
addImport(source: string, imported: string, name?: string = imported): Object {
|
||||
let alias = `${source}:${imported}`;
|
||||
const alias = `${source}:${imported}`;
|
||||
let id = this.dynamicImportIds[alias];
|
||||
|
||||
if (!id) {
|
||||
source = this.resolveModuleSource(source);
|
||||
id = this.dynamicImportIds[alias] = this.scope.generateUidIdentifier(name);
|
||||
|
||||
let specifiers = [];
|
||||
const specifiers = [];
|
||||
|
||||
if (imported === "*") {
|
||||
specifiers.push(t.importNamespaceSpecifier(id));
|
||||
@@ -268,7 +237,7 @@ export default class File extends Store {
|
||||
specifiers.push(t.importSpecifier(id, t.identifier(imported)));
|
||||
}
|
||||
|
||||
let declar = t.importDeclaration(specifiers, t.stringLiteral(source));
|
||||
const declar = t.importDeclaration(specifiers, t.stringLiteral(source));
|
||||
declar._blockHoist = 3;
|
||||
|
||||
this.path.unshiftContainer("body", declar);
|
||||
@@ -278,7 +247,7 @@ export default class File extends Store {
|
||||
}
|
||||
|
||||
addHelper(name: string): Object {
|
||||
let declar = this.declarations[name];
|
||||
const declar = this.declarations[name];
|
||||
if (declar) return declar;
|
||||
|
||||
if (!this.usedHelpers[name]) {
|
||||
@@ -286,17 +255,17 @@ export default class File extends Store {
|
||||
this.usedHelpers[name] = true;
|
||||
}
|
||||
|
||||
let generator = this.get("helperGenerator");
|
||||
let runtime = this.get("helpersNamespace");
|
||||
const generator = this.get("helperGenerator");
|
||||
const runtime = this.get("helpersNamespace");
|
||||
if (generator) {
|
||||
let res = generator(name);
|
||||
const res = generator(name);
|
||||
if (res) return res;
|
||||
} else if (runtime) {
|
||||
return t.memberExpression(runtime, t.identifier(name));
|
||||
}
|
||||
|
||||
let ref = getHelper(name);
|
||||
let uid = this.declarations[name] = this.scope.generateUidIdentifier(name);
|
||||
const ref = getHelper(name);
|
||||
const uid = this.declarations[name] = this.scope.generateUidIdentifier(name);
|
||||
|
||||
if (t.isFunctionExpression(ref) && !ref.id) {
|
||||
ref.body._compact = true;
|
||||
@@ -309,7 +278,7 @@ export default class File extends Store {
|
||||
this.scope.push({
|
||||
id: uid,
|
||||
init: ref,
|
||||
unique: true
|
||||
unique: true,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -323,31 +292,31 @@ export default class File extends Store {
|
||||
): Object {
|
||||
// Generate a unique name based on the string literals so we dedupe
|
||||
// identical strings used in the program.
|
||||
let stringIds = raw.elements.map(function(string) {
|
||||
const stringIds = raw.elements.map(function(string) {
|
||||
return string.value;
|
||||
});
|
||||
let name = `${helperName}_${raw.elements.length}_${stringIds.join(",")}`;
|
||||
const name = `${helperName}_${raw.elements.length}_${stringIds.join(",")}`;
|
||||
|
||||
let declar = this.declarations[name];
|
||||
const declar = this.declarations[name];
|
||||
if (declar) return declar;
|
||||
|
||||
let uid = this.declarations[name] = this.scope.generateUidIdentifier("templateObject");
|
||||
const uid = this.declarations[name] = this.scope.generateUidIdentifier("templateObject");
|
||||
|
||||
let helperId = this.addHelper(helperName);
|
||||
let init = t.callExpression(helperId, [strings, raw]);
|
||||
const helperId = this.addHelper(helperName);
|
||||
const init = t.callExpression(helperId, [strings, raw]);
|
||||
init._compact = true;
|
||||
this.scope.push({
|
||||
id: uid,
|
||||
init: init,
|
||||
_blockHoist: 1.9 // This ensures that we don't fail if not using function expression helpers
|
||||
_blockHoist: 1.9, // This ensures that we don't fail if not using function expression helpers
|
||||
});
|
||||
return uid;
|
||||
}
|
||||
|
||||
buildCodeFrameError(node: Object, msg: string, Error: typeof Error = SyntaxError): Error {
|
||||
let loc = node && (node.loc || node._loc);
|
||||
const loc = node && (node.loc || node._loc);
|
||||
|
||||
let err = new Error(msg);
|
||||
const err = new Error(msg);
|
||||
|
||||
if (loc) {
|
||||
err.loc = loc.start;
|
||||
@@ -367,26 +336,26 @@ export default class File extends Store {
|
||||
}
|
||||
|
||||
mergeSourceMap(map: Object) {
|
||||
let inputMap = this.opts.inputSourceMap;
|
||||
const inputMap = this.opts.inputSourceMap;
|
||||
|
||||
if (inputMap) {
|
||||
let inputMapConsumer = new sourceMap.SourceMapConsumer(inputMap);
|
||||
let outputMapConsumer = new sourceMap.SourceMapConsumer(map);
|
||||
const inputMapConsumer = new sourceMap.SourceMapConsumer(inputMap);
|
||||
const outputMapConsumer = new sourceMap.SourceMapConsumer(map);
|
||||
|
||||
let mergedGenerator = new sourceMap.SourceMapGenerator({
|
||||
const mergedGenerator = new sourceMap.SourceMapGenerator({
|
||||
file: inputMapConsumer.file,
|
||||
sourceRoot: inputMapConsumer.sourceRoot
|
||||
sourceRoot: inputMapConsumer.sourceRoot,
|
||||
});
|
||||
|
||||
// This assumes the output map always has a single source, since Babel always compiles a single source file to a
|
||||
// single output file.
|
||||
// This assumes the output map always has a single source, since Babel always compiles a
|
||||
// single source file to a single output file.
|
||||
const source = outputMapConsumer.sources[0];
|
||||
|
||||
inputMapConsumer.eachMapping(function (mapping) {
|
||||
const generatedPosition = outputMapConsumer.generatedPositionFor({
|
||||
line: mapping.generatedLine,
|
||||
column: mapping.generatedColumn,
|
||||
source: source
|
||||
source: source,
|
||||
});
|
||||
if (generatedPosition.column != null) {
|
||||
mergedGenerator.addMapping({
|
||||
@@ -394,15 +363,15 @@ export default class File extends Store {
|
||||
|
||||
original: mapping.source == null ? null : {
|
||||
line: mapping.originalLine,
|
||||
column: mapping.originalColumn
|
||||
column: mapping.originalColumn,
|
||||
},
|
||||
|
||||
generated: generatedPosition
|
||||
generated: generatedPosition,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
let mergedMap = mergedGenerator.toJSON();
|
||||
const mergedMap = mergedGenerator.toJSON();
|
||||
inputMap.mappings = mergedMap.mappings;
|
||||
return inputMap;
|
||||
} else {
|
||||
@@ -419,12 +388,13 @@ export default class File extends Store {
|
||||
|
||||
if (parserOpts.parser) {
|
||||
if (typeof parserOpts.parser === "string") {
|
||||
let dirname = path.dirname(this.opts.filename) || process.cwd();
|
||||
let parser = resolve(parserOpts.parser, dirname);
|
||||
const dirname = path.dirname(this.opts.filename) || process.cwd();
|
||||
const parser = resolve(parserOpts.parser, dirname);
|
||||
if (parser) {
|
||||
parseCode = require(parser).parse;
|
||||
} else {
|
||||
throw new Error(`Couldn't find parser ${parserOpts.parser} with "parse" method relative to directory ${dirname}`);
|
||||
throw new Error(`Couldn't find parser ${parserOpts.parser} with "parse" method ` +
|
||||
`relative to directory ${dirname}`);
|
||||
}
|
||||
} else {
|
||||
parseCode = parserOpts.parser;
|
||||
@@ -433,13 +403,13 @@ export default class File extends Store {
|
||||
parserOpts.parser = {
|
||||
parse(source) {
|
||||
return parse(source, parserOpts);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
this.log.debug("Parse start");
|
||||
let ast = parseCode(code, parserOpts || this.parserOpts);
|
||||
const ast = parseCode(code, parserOpts || this.parserOpts);
|
||||
this.log.debug("Parse stop");
|
||||
return ast;
|
||||
}
|
||||
@@ -450,10 +420,10 @@ export default class File extends Store {
|
||||
parentPath: null,
|
||||
parent: ast,
|
||||
container: ast,
|
||||
key: "program"
|
||||
key: "program",
|
||||
}).setContext();
|
||||
this.scope = this.path.scope;
|
||||
this.ast = ast;
|
||||
this.ast = ast;
|
||||
this.getMetadata();
|
||||
}
|
||||
|
||||
@@ -464,19 +434,25 @@ export default class File extends Store {
|
||||
}
|
||||
|
||||
transform(): BabelFileResult {
|
||||
// In the "pass per preset" mode, we have grouped passes.
|
||||
// Otherwise, there is only one plain pluginPasses array.
|
||||
for (let i = 0; i < this.pluginPasses.length; i++) {
|
||||
const pluginPasses = this.pluginPasses[i];
|
||||
this.call("pre", pluginPasses);
|
||||
for (const pluginPairs of this.pluginPasses) {
|
||||
const passes = [];
|
||||
const visitors = [];
|
||||
|
||||
for (const [ plugin, pluginOpts ] of pluginPairs.concat(INTERNAL_PLUGINS)) {
|
||||
const pass = new PluginPass(this, plugin, pluginOpts);
|
||||
passes.push(pass);
|
||||
visitors.push(plugin.visitor);
|
||||
}
|
||||
|
||||
this.call("pre", passes);
|
||||
this.log.debug("Start transform traverse");
|
||||
|
||||
// merge all plugin visitors into a single visitor
|
||||
let visitor = traverse.visitors.merge(this.pluginVisitors[i], pluginPasses, this.opts.wrapPluginVisitorMethod);
|
||||
const visitor = traverse.visitors.merge(visitors, passes, this.opts.wrapPluginVisitorMethod);
|
||||
traverse(this.ast, visitor, this.scope);
|
||||
|
||||
this.log.debug("End transform traverse");
|
||||
this.call("post", pluginPasses);
|
||||
this.call("post", passes);
|
||||
}
|
||||
|
||||
return this.generate();
|
||||
@@ -500,7 +476,7 @@ export default class File extends Store {
|
||||
|
||||
let message = err.message = `${this.opts.filename}: ${err.message}`;
|
||||
|
||||
let loc = err.loc;
|
||||
const loc = err.loc;
|
||||
if (loc) {
|
||||
err.codeFrame = codeFrame(code, loc.line, loc.column + 1, this.opts);
|
||||
message += "\n" + err.codeFrame;
|
||||
@@ -513,7 +489,7 @@ export default class File extends Store {
|
||||
}
|
||||
|
||||
if (err.stack) {
|
||||
let newStack = err.stack.replace(err.message, message);
|
||||
const newStack = err.stack.replace(err.message, message);
|
||||
err.stack = newStack;
|
||||
}
|
||||
|
||||
@@ -529,28 +505,28 @@ export default class File extends Store {
|
||||
|
||||
parseCode() {
|
||||
this.parseShebang();
|
||||
let ast = this.parse(this.code);
|
||||
const ast = this.parse(this.code);
|
||||
this.addAst(ast);
|
||||
}
|
||||
|
||||
shouldIgnore() {
|
||||
let opts = this.opts;
|
||||
const opts = this.opts;
|
||||
return util.shouldIgnore(opts.filename, opts.ignore, opts.only);
|
||||
}
|
||||
|
||||
call(key: "pre" | "post", pluginPasses: Array<PluginPass>) {
|
||||
for (let pass of pluginPasses) {
|
||||
let plugin = pass.plugin;
|
||||
let fn = plugin[key];
|
||||
for (const pass of pluginPasses) {
|
||||
const plugin = pass.plugin;
|
||||
const fn = plugin[key];
|
||||
if (fn) fn.call(pass, this);
|
||||
}
|
||||
}
|
||||
|
||||
parseInputSourceMap(code: string): string {
|
||||
let opts = this.opts;
|
||||
const opts = this.opts;
|
||||
|
||||
if (opts.inputSourceMap !== false) {
|
||||
let inputMap = convertSourceMap.fromSource(code);
|
||||
const inputMap = convertSourceMap.fromSource(code);
|
||||
if (inputMap) {
|
||||
opts.inputSourceMap = inputMap.toObject();
|
||||
code = convertSourceMap.removeComments(code);
|
||||
@@ -561,7 +537,7 @@ export default class File extends Store {
|
||||
}
|
||||
|
||||
parseShebang() {
|
||||
let shebangMatch = shebangRegex.exec(this.code);
|
||||
const shebangMatch = shebangRegex.exec(this.code);
|
||||
if (shebangMatch) {
|
||||
this.shebang = shebangMatch[0];
|
||||
this.code = this.code.replace(shebangRegex, "");
|
||||
@@ -569,13 +545,13 @@ export default class File extends Store {
|
||||
}
|
||||
|
||||
makeResult({ code, map, ast, ignored }: BabelFileResult): BabelFileResult {
|
||||
let result = {
|
||||
const result = {
|
||||
metadata: null,
|
||||
options: this.opts,
|
||||
ignored: !!ignored,
|
||||
code: null,
|
||||
ast: null,
|
||||
map: map || null
|
||||
options: this.opts,
|
||||
ignored: !!ignored,
|
||||
code: null,
|
||||
ast: null,
|
||||
map: map || null,
|
||||
};
|
||||
|
||||
if (this.opts.code) {
|
||||
@@ -594,10 +570,10 @@ export default class File extends Store {
|
||||
}
|
||||
|
||||
generate(): BabelFileResult {
|
||||
let opts = this.opts;
|
||||
let ast = this.ast;
|
||||
const opts = this.opts;
|
||||
const ast = this.ast;
|
||||
|
||||
let result: BabelFileResult = { ast };
|
||||
const result: BabelFileResult = { ast };
|
||||
if (!opts.code) return this.makeResult(result);
|
||||
|
||||
let gen = generate;
|
||||
@@ -605,21 +581,23 @@ export default class File extends Store {
|
||||
gen = opts.generatorOpts.generator;
|
||||
|
||||
if (typeof gen === "string") {
|
||||
let dirname = path.dirname(this.opts.filename) || process.cwd();
|
||||
let generator = resolve(gen, dirname);
|
||||
const dirname = path.dirname(this.opts.filename) || process.cwd();
|
||||
const generator = resolve(gen, dirname);
|
||||
if (generator) {
|
||||
gen = require(generator).print;
|
||||
} else {
|
||||
throw new Error(`Couldn't find generator ${gen} with "print" method relative to directory ${dirname}`);
|
||||
throw new Error(`Couldn't find generator ${gen} with "print" method relative ` +
|
||||
`to directory ${dirname}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.log.debug("Generation start");
|
||||
|
||||
let _result = gen(ast, opts.generatorOpts ? Object.assign(opts, opts.generatorOpts) : opts, this.code);
|
||||
const _result = gen(ast, opts.generatorOpts ? Object.assign(opts, opts.generatorOpts) : opts,
|
||||
this.code);
|
||||
result.code = _result.code;
|
||||
result.map = _result.map;
|
||||
result.map = _result.map;
|
||||
|
||||
this.log.debug("Generation end");
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import type File from "./index";
|
||||
import buildDebug from "debug";
|
||||
|
||||
let verboseDebug = buildDebug("babel:verbose");
|
||||
let generalDebug = buildDebug("babel");
|
||||
const verboseDebug = buildDebug("babel:verbose");
|
||||
const generalDebug = buildDebug("babel");
|
||||
|
||||
let seenDeprecatedMessages = [];
|
||||
const seenDeprecatedMessages = [];
|
||||
|
||||
export default class Logger {
|
||||
constructor(file: File, filename: string) {
|
||||
this.filename = filename;
|
||||
this.file = file;
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
filename: string;
|
||||
@@ -21,6 +21,15 @@ export default class Logger {
|
||||
return parts;
|
||||
}
|
||||
|
||||
wrap<T>(callback: () => T): T {
|
||||
try {
|
||||
return callback();
|
||||
} catch (e) {
|
||||
e.message = this._buildMessage(e.message);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
warn(msg: string) {
|
||||
console.warn(this._buildMessage(msg));
|
||||
}
|
||||
|
||||
@@ -1,45 +1,45 @@
|
||||
import * as t from "babel-types";
|
||||
|
||||
export let ModuleDeclaration = {
|
||||
export const ModuleDeclaration = {
|
||||
enter(path, file) {
|
||||
let { node } = path;
|
||||
const { node } = path;
|
||||
if (node.source) {
|
||||
node.source.value = file.resolveModuleSource(node.source.value);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export let ImportDeclaration = {
|
||||
export const ImportDeclaration = {
|
||||
exit(path, file) {
|
||||
let { node } = path;
|
||||
const { node } = path;
|
||||
|
||||
let specifiers = [];
|
||||
let imported = [];
|
||||
const specifiers = [];
|
||||
const imported = [];
|
||||
file.metadata.modules.imports.push({
|
||||
source: node.source.value,
|
||||
imported,
|
||||
specifiers
|
||||
specifiers,
|
||||
});
|
||||
|
||||
for (let specifier of (path.get("specifiers"): Array<Object>)) {
|
||||
let local = specifier.node.local.name;
|
||||
for (const specifier of (path.get("specifiers"): Array<Object>)) {
|
||||
const local = specifier.node.local.name;
|
||||
|
||||
if (specifier.isImportDefaultSpecifier()) {
|
||||
imported.push("default");
|
||||
specifiers.push({
|
||||
kind: "named",
|
||||
imported: "default",
|
||||
local
|
||||
local,
|
||||
});
|
||||
}
|
||||
|
||||
if (specifier.isImportSpecifier()) {
|
||||
let importedName = specifier.node.imported.name;
|
||||
const importedName = specifier.node.imported.name;
|
||||
imported.push(importedName);
|
||||
specifiers.push({
|
||||
kind: "named",
|
||||
imported: importedName,
|
||||
local
|
||||
local,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -47,38 +47,38 @@ export let ImportDeclaration = {
|
||||
imported.push("*");
|
||||
specifiers.push({
|
||||
kind: "namespace",
|
||||
local
|
||||
local,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export function ExportDeclaration(path, file) {
|
||||
let { node } = path;
|
||||
const { node } = path;
|
||||
|
||||
let source = node.source ? node.source.value : null;
|
||||
let exports = file.metadata.modules.exports;
|
||||
const source = node.source ? node.source.value : null;
|
||||
const exports = file.metadata.modules.exports;
|
||||
|
||||
// export function foo() {}
|
||||
// export let foo = "bar";
|
||||
let declar = path.get("declaration");
|
||||
const declar = path.get("declaration");
|
||||
if (declar.isStatement()) {
|
||||
let bindings = declar.getBindingIdentifiers();
|
||||
const bindings = declar.getBindingIdentifiers();
|
||||
|
||||
for (let name in bindings) {
|
||||
for (const name in bindings) {
|
||||
exports.exported.push(name);
|
||||
exports.specifiers.push({
|
||||
kind: "local",
|
||||
local: name,
|
||||
exported: path.isExportDefaultDeclaration() ? "default" : name
|
||||
exported: path.isExportDefaultDeclaration() ? "default" : name,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (path.isExportNamedDeclaration() && node.specifiers) {
|
||||
for (let specifier of (node.specifiers: Array<Object>)) {
|
||||
let exported = specifier.exported.name;
|
||||
for (const specifier of (node.specifiers: Array<Object>)) {
|
||||
const exported = specifier.exported.name;
|
||||
exports.exported.push(exported);
|
||||
|
||||
// export foo from "bar";
|
||||
@@ -87,7 +87,7 @@ export function ExportDeclaration(path, file) {
|
||||
kind: "external",
|
||||
local: exported,
|
||||
exported,
|
||||
source
|
||||
source,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -96,11 +96,11 @@ export function ExportDeclaration(path, file) {
|
||||
exports.specifiers.push({
|
||||
kind: "external-namespace",
|
||||
exported,
|
||||
source
|
||||
source,
|
||||
});
|
||||
}
|
||||
|
||||
let local = specifier.local;
|
||||
const local = specifier.local;
|
||||
if (!local) continue;
|
||||
|
||||
// export { foo } from "bar";
|
||||
@@ -110,7 +110,7 @@ export function ExportDeclaration(path, file) {
|
||||
kind: "external",
|
||||
local: local.name,
|
||||
exported,
|
||||
source
|
||||
source,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ export function ExportDeclaration(path, file) {
|
||||
exports.specifiers.push({
|
||||
kind: "local",
|
||||
local: local.name,
|
||||
exported
|
||||
exported,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -130,7 +130,7 @@ export function ExportDeclaration(path, file) {
|
||||
if (path.isExportAllDeclaration()) {
|
||||
exports.specifiers.push({
|
||||
kind: "external-all",
|
||||
source
|
||||
source,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
|
||||
import type Logger from "../logger";
|
||||
import resolve from "../../../helpers/resolve";
|
||||
import json5 from "json5";
|
||||
import isAbsolute from "path-is-absolute";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
|
||||
let existsCache = {};
|
||||
let jsonCache = {};
|
||||
const existsCache = {};
|
||||
const jsonCache = {};
|
||||
|
||||
const BABELRC_FILENAME = ".babelrc";
|
||||
const BABELRC_JS_FILENAME = ".babelrc.js";
|
||||
const PACKAGE_FILENAME = "package.json";
|
||||
const BABELIGNORE_FILENAME = ".babelignore";
|
||||
const BABELRC_FILENAME = ".babelrc";
|
||||
const PACKAGE_FILENAME = "package.json";
|
||||
|
||||
function exists(filename) {
|
||||
let cached = existsCache[filename];
|
||||
const cached = existsCache[filename];
|
||||
if (cached == null) {
|
||||
return existsCache[filename] = fs.existsSync(filename);
|
||||
} else {
|
||||
@@ -22,9 +20,9 @@ function exists(filename) {
|
||||
}
|
||||
}
|
||||
|
||||
export default function buildConfigChain(opts: Object = {}, log?: Logger) {
|
||||
let filename = opts.filename;
|
||||
let builder = new ConfigChainBuilder(log);
|
||||
export default function buildConfigChain(opts: Object = {}) {
|
||||
const filename = opts.filename;
|
||||
const builder = new ConfigChainBuilder();
|
||||
|
||||
// resolve all .babelrc files
|
||||
if (opts.babelrc !== false) {
|
||||
@@ -34,23 +32,27 @@ export default function buildConfigChain(opts: Object = {}, log?: Logger) {
|
||||
builder.mergeConfig({
|
||||
options: opts,
|
||||
alias: "base",
|
||||
dirname: filename && path.dirname(filename)
|
||||
dirname: filename && path.dirname(filename),
|
||||
});
|
||||
|
||||
return builder.configs;
|
||||
}
|
||||
|
||||
class ConfigChainBuilder {
|
||||
constructor(log?: Logger) {
|
||||
constructor() {
|
||||
this.resolvedConfigs = [];
|
||||
this.configs = [];
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
findConfigs(loc) {
|
||||
errorMultipleConfigs(loc1: string, loc2: string) {
|
||||
throw new Error(`Multiple configuration files found. Please remove one:\n- ${
|
||||
loc1}\n- ${loc2}`);
|
||||
}
|
||||
|
||||
findConfigs(loc: string) {
|
||||
if (!loc) return;
|
||||
|
||||
if (!isAbsolute(loc)) {
|
||||
if (!path.isAbsolute(loc)) {
|
||||
loc = path.join(process.cwd(), loc);
|
||||
}
|
||||
|
||||
@@ -59,20 +61,31 @@ class ConfigChainBuilder {
|
||||
|
||||
while (loc !== (loc = path.dirname(loc))) {
|
||||
if (!foundConfig) {
|
||||
let configLoc = path.join(loc, BABELRC_FILENAME);
|
||||
if (exists(configLoc)) {
|
||||
this.addConfig(configLoc);
|
||||
foundConfig = true;
|
||||
}
|
||||
const configLoc = path.join(loc, BABELRC_FILENAME);
|
||||
const configJSLoc = path.join(loc, BABELRC_JS_FILENAME);
|
||||
const pkgLoc = path.join(loc, PACKAGE_FILENAME);
|
||||
const configLocs = [configLoc, configJSLoc, pkgLoc];
|
||||
const foundConfigs = configLocs.reduce((arr, config) => {
|
||||
if (exists(config)) {
|
||||
const configAdded = config === pkgLoc
|
||||
? this.addConfig(config, "babel", JSON)
|
||||
: this.addConfig(config);
|
||||
|
||||
let pkgLoc = path.join(loc, PACKAGE_FILENAME);
|
||||
if (!foundConfig && exists(pkgLoc)) {
|
||||
foundConfig = this.addConfig(pkgLoc, "babel", JSON);
|
||||
}
|
||||
if (configAdded && arr.length) {
|
||||
this.errorMultipleConfigs(arr.pop(), config);
|
||||
}
|
||||
|
||||
arr.push(config);
|
||||
}
|
||||
|
||||
return arr;
|
||||
}, []);
|
||||
|
||||
foundConfig = !!foundConfigs.length;
|
||||
}
|
||||
|
||||
if (!foundIgnore) {
|
||||
let ignoreLoc = path.join(loc, BABELIGNORE_FILENAME);
|
||||
const ignoreLoc = path.join(loc, BABELIGNORE_FILENAME);
|
||||
if (exists(ignoreLoc)) {
|
||||
this.addIgnoreConfig(ignoreLoc);
|
||||
foundIgnore = true;
|
||||
@@ -83,8 +96,8 @@ class ConfigChainBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
addIgnoreConfig(loc) {
|
||||
let file = fs.readFileSync(loc, "utf8");
|
||||
addIgnoreConfig(loc: string) {
|
||||
const file = fs.readFileSync(loc, "utf8");
|
||||
let lines = file.split("\n");
|
||||
|
||||
lines = lines
|
||||
@@ -95,7 +108,7 @@ class ConfigChainBuilder {
|
||||
this.mergeConfig({
|
||||
options: { ignore: lines },
|
||||
alias: loc,
|
||||
dirname: path.dirname(loc)
|
||||
dirname: path.dirname(loc),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -107,21 +120,41 @@ class ConfigChainBuilder {
|
||||
|
||||
this.resolvedConfigs.push(loc);
|
||||
|
||||
let content = fs.readFileSync(loc, "utf8");
|
||||
let options;
|
||||
if (path.extname(loc) === ".js") {
|
||||
try {
|
||||
const configModule = require(loc);
|
||||
options = configModule && configModule.__esModule ? configModule.default : configModule;
|
||||
} catch (err) {
|
||||
err.message = `${loc}: Error while loading config - ${err.message}`;
|
||||
throw err;
|
||||
}
|
||||
|
||||
try {
|
||||
options = jsonCache[content] = jsonCache[content] || json.parse(content);
|
||||
if (key) options = options[key];
|
||||
} catch (err) {
|
||||
err.message = `${loc}: Error while parsing JSON - ${err.message}`;
|
||||
throw err;
|
||||
if (!options || typeof options !== "object") {
|
||||
throw new Error("Configuration should be an exported JavaScript object.");
|
||||
}
|
||||
} else {
|
||||
const content = fs.readFileSync(loc, "utf8");
|
||||
try {
|
||||
options = jsonCache[content] = jsonCache[content] || json.parse(content);
|
||||
} catch (err) {
|
||||
err.message = `${loc}: Error while parsing JSON - ${err.message}`;
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
if (key) {
|
||||
if (!options[key]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
options = options[key];
|
||||
}
|
||||
|
||||
this.mergeConfig({
|
||||
options,
|
||||
alias: loc,
|
||||
dirname: path.dirname(loc)
|
||||
dirname: path.dirname(loc),
|
||||
});
|
||||
|
||||
return !!options;
|
||||
@@ -131,7 +164,7 @@ class ConfigChainBuilder {
|
||||
options,
|
||||
alias,
|
||||
loc,
|
||||
dirname
|
||||
dirname,
|
||||
}) {
|
||||
if (!options) {
|
||||
return false;
|
||||
@@ -144,11 +177,11 @@ class ConfigChainBuilder {
|
||||
|
||||
// add extends clause
|
||||
if (options.extends) {
|
||||
let extendsLoc = resolve(options.extends, dirname);
|
||||
const extendsLoc = resolve(options.extends, dirname);
|
||||
if (extendsLoc) {
|
||||
this.addConfig(extendsLoc);
|
||||
} else {
|
||||
if (this.log) this.log.error(`Couldn't resolve extends clause of ${options.extends} in ${alias}`);
|
||||
throw new Error(`Couldn't resolve extends clause of ${options.extends} in ${alias}`);
|
||||
}
|
||||
delete options.extends;
|
||||
}
|
||||
@@ -157,12 +190,12 @@ class ConfigChainBuilder {
|
||||
options,
|
||||
alias,
|
||||
loc,
|
||||
dirname
|
||||
dirname,
|
||||
});
|
||||
|
||||
// env
|
||||
let envOpts;
|
||||
let envKey = process.env.BABEL_ENV || process.env.NODE_ENV || "development";
|
||||
const envKey = process.env.BABEL_ENV || process.env.NODE_ENV || "development";
|
||||
if (options.env) {
|
||||
envOpts = options.env[envKey];
|
||||
delete options.env;
|
||||
@@ -171,7 +204,7 @@ class ConfigChainBuilder {
|
||||
this.mergeConfig({
|
||||
options: envOpts,
|
||||
alias: `${alias}.env.${envKey}`,
|
||||
dirname: dirname
|
||||
dirname: dirname,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,195 +1,195 @@
|
||||
/* eslint max-len: 0 */
|
||||
/* eslint max-len: "off" */
|
||||
|
||||
module.exports = {
|
||||
export default {
|
||||
filename: {
|
||||
type: "filename",
|
||||
description: "filename to use when reading from stdin - this will be used in source-maps, errors etc",
|
||||
default: "unknown",
|
||||
shorthand: "f"
|
||||
shorthand: "f",
|
||||
},
|
||||
|
||||
filenameRelative: {
|
||||
hidden: true,
|
||||
type: "string"
|
||||
type: "string",
|
||||
},
|
||||
|
||||
inputSourceMap: {
|
||||
hidden: true
|
||||
hidden: true,
|
||||
},
|
||||
|
||||
env: {
|
||||
hidden: true,
|
||||
default: {}
|
||||
default: {},
|
||||
},
|
||||
|
||||
mode: {
|
||||
description: "",
|
||||
hidden: true
|
||||
hidden: true,
|
||||
},
|
||||
|
||||
retainLines: {
|
||||
type: "boolean",
|
||||
default: false,
|
||||
description: "retain line numbers - will result in really ugly code"
|
||||
description: "retain line numbers - will result in really ugly code",
|
||||
},
|
||||
|
||||
highlightCode: {
|
||||
description: "enable/disable ANSI syntax highlighting of code frames (on by default)",
|
||||
type: "boolean",
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
|
||||
suppressDeprecationMessages: {
|
||||
type: "boolean",
|
||||
default: false,
|
||||
hidden: true
|
||||
hidden: true,
|
||||
},
|
||||
|
||||
presets: {
|
||||
type: "list",
|
||||
description: "",
|
||||
default: []
|
||||
default: [],
|
||||
},
|
||||
|
||||
plugins: {
|
||||
type: "list",
|
||||
default: [],
|
||||
description: ""
|
||||
description: "",
|
||||
},
|
||||
|
||||
ignore: {
|
||||
type: "list",
|
||||
description: "list of glob paths to **not** compile",
|
||||
default: []
|
||||
default: [],
|
||||
},
|
||||
|
||||
only: {
|
||||
type: "list",
|
||||
description: "list of glob paths to **only** compile"
|
||||
description: "list of glob paths to **only** compile",
|
||||
},
|
||||
|
||||
code: {
|
||||
hidden: true,
|
||||
default: true,
|
||||
type: "boolean"
|
||||
type: "boolean",
|
||||
},
|
||||
|
||||
metadata: {
|
||||
hidden: true,
|
||||
default: true,
|
||||
type: "boolean"
|
||||
type: "boolean",
|
||||
},
|
||||
|
||||
ast: {
|
||||
hidden: true,
|
||||
default: true,
|
||||
type: "boolean"
|
||||
type: "boolean",
|
||||
},
|
||||
|
||||
extends: {
|
||||
type: "string",
|
||||
hidden: true
|
||||
hidden: true,
|
||||
},
|
||||
|
||||
comments: {
|
||||
type: "boolean",
|
||||
default: true,
|
||||
description: "write comments to generated output (true by default)"
|
||||
description: "write comments to generated output (true by default)",
|
||||
},
|
||||
|
||||
shouldPrintComment: {
|
||||
hidden: true,
|
||||
description: "optional callback to control whether a comment should be inserted, when this is used the comments option is ignored"
|
||||
description: "optional callback to control whether a comment should be inserted, when this is used the comments option is ignored",
|
||||
},
|
||||
|
||||
wrapPluginVisitorMethod: {
|
||||
hidden: true,
|
||||
description: "optional callback to wrap all visitor methods"
|
||||
description: "optional callback to wrap all visitor methods",
|
||||
},
|
||||
|
||||
compact: {
|
||||
type: "booleanString",
|
||||
default: "auto",
|
||||
description: "do not include superfluous whitespace characters and line terminators [true|false|auto]"
|
||||
description: "do not include superfluous whitespace characters and line terminators [true|false|auto]",
|
||||
},
|
||||
|
||||
minified: {
|
||||
type: "boolean",
|
||||
default: false,
|
||||
description: "save as much bytes when printing [true|false]"
|
||||
description: "save as much bytes when printing [true|false]",
|
||||
},
|
||||
|
||||
sourceMap: {
|
||||
alias: "sourceMaps",
|
||||
hidden: true
|
||||
hidden: true,
|
||||
},
|
||||
|
||||
sourceMaps: {
|
||||
type: "booleanString",
|
||||
description: "[true|false|inline]",
|
||||
default: false,
|
||||
shorthand: "s"
|
||||
shorthand: "s",
|
||||
},
|
||||
|
||||
sourceMapTarget: {
|
||||
type: "string",
|
||||
description: "set `file` on returned source map"
|
||||
description: "set `file` on returned source map",
|
||||
},
|
||||
|
||||
sourceFileName: {
|
||||
type: "string",
|
||||
description: "set `sources[0]` on returned source map"
|
||||
description: "set `sources[0]` on returned source map",
|
||||
},
|
||||
|
||||
sourceRoot: {
|
||||
type: "filename",
|
||||
description: "the root from which all sources are relative"
|
||||
description: "the root from which all sources are relative",
|
||||
},
|
||||
|
||||
babelrc: {
|
||||
description: "Whether or not to look up .babelrc and .babelignore files",
|
||||
type: "boolean",
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
|
||||
sourceType: {
|
||||
description: "",
|
||||
default: "module"
|
||||
default: "module",
|
||||
},
|
||||
|
||||
auxiliaryCommentBefore: {
|
||||
type: "string",
|
||||
description: "print a comment before any injected non-user code"
|
||||
description: "print a comment before any injected non-user code",
|
||||
},
|
||||
|
||||
auxiliaryCommentAfter: {
|
||||
type: "string",
|
||||
description: "print a comment after any injected non-user code"
|
||||
description: "print a comment after any injected non-user code",
|
||||
},
|
||||
|
||||
resolveModuleSource: {
|
||||
hidden: true
|
||||
hidden: true,
|
||||
},
|
||||
|
||||
getModuleId: {
|
||||
hidden: true
|
||||
hidden: true,
|
||||
},
|
||||
|
||||
moduleRoot: {
|
||||
type: "filename",
|
||||
description: "optional prefix for the AMD module formatter that will be prepend to the filename on module definitions"
|
||||
description: "optional prefix for the AMD module formatter that will be prepend to the filename on module definitions",
|
||||
},
|
||||
|
||||
moduleIds: {
|
||||
type: "boolean",
|
||||
default: false,
|
||||
shorthand: "M",
|
||||
description: "insert an explicit id for modules"
|
||||
description: "insert an explicit id for modules",
|
||||
},
|
||||
|
||||
moduleId: {
|
||||
description: "specify a custom name for module ids",
|
||||
type: "string"
|
||||
type: "string",
|
||||
},
|
||||
|
||||
passPerPreset: {
|
||||
@@ -202,12 +202,12 @@ module.exports = {
|
||||
// Deprecate top level parserOpts
|
||||
parserOpts: {
|
||||
description: "Options to pass into the parser, or to change parsers (parserOpts.parser)",
|
||||
default: false
|
||||
default: false,
|
||||
},
|
||||
|
||||
// Deprecate top level generatorOpts
|
||||
generatorOpts: {
|
||||
description: "Options to pass into the generator, or to change generators (generatorOpts.generator)",
|
||||
default: false
|
||||
}
|
||||
default: false,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@ import config from "./config";
|
||||
export { config };
|
||||
|
||||
export function normaliseOptions(options: Object = {}): Object {
|
||||
for (let key in options) {
|
||||
for (const key in options) {
|
||||
let val = options[key];
|
||||
if (val == null) continue;
|
||||
|
||||
@@ -12,7 +12,7 @@ export function normaliseOptions(options: Object = {}): Object {
|
||||
if (opt && opt.alias) opt = config[opt.alias];
|
||||
if (!opt) continue;
|
||||
|
||||
let parser = parsers[opt.type];
|
||||
const parser = parsers[opt.type];
|
||||
if (parser) val = parser(val);
|
||||
|
||||
options[key] = val;
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/* eslint max-len: 0 */
|
||||
|
||||
import * as context from "../../../api/node";
|
||||
import type Logger from "../logger";
|
||||
import * as context from "../../../index";
|
||||
import Plugin from "../../plugin";
|
||||
import * as messages from "babel-messages";
|
||||
import { normaliseOptions } from "./index";
|
||||
import resolve from "../../../helpers/resolve";
|
||||
import resolvePlugin from "../../../helpers/resolve-plugin";
|
||||
import resolvePreset from "../../../helpers/resolve-preset";
|
||||
import cloneDeepWith from "lodash/cloneDeepWith";
|
||||
import clone from "lodash/clone";
|
||||
import merge from "../../../helpers/merge";
|
||||
@@ -36,15 +34,13 @@ type MergeOptions = {
|
||||
};
|
||||
|
||||
export default class OptionManager {
|
||||
constructor(log?: Logger) {
|
||||
constructor() {
|
||||
this.resolvedConfigs = [];
|
||||
this.options = OptionManager.createBareOptions();
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
resolvedConfigs: Array<string>;
|
||||
options: Object;
|
||||
log: ?Logger;
|
||||
|
||||
static memoisedPlugins: Array<{
|
||||
container: Function;
|
||||
@@ -52,7 +48,7 @@ export default class OptionManager {
|
||||
}>;
|
||||
|
||||
static memoisePluginContainer(fn, loc, i, alias) {
|
||||
for (let cache of (OptionManager.memoisedPlugins: Array<Object>)) {
|
||||
for (const cache of (OptionManager.memoisedPlugins: Array<Object>)) {
|
||||
if (cache.container === fn) return cache.plugin;
|
||||
}
|
||||
|
||||
@@ -65,10 +61,10 @@ export default class OptionManager {
|
||||
}
|
||||
|
||||
if (typeof obj === "object") {
|
||||
let plugin = new Plugin(obj, alias);
|
||||
const plugin = new Plugin(obj, alias);
|
||||
OptionManager.memoisedPlugins.push({
|
||||
container: fn,
|
||||
plugin: plugin
|
||||
plugin: plugin,
|
||||
});
|
||||
return plugin;
|
||||
} else {
|
||||
@@ -77,10 +73,10 @@ export default class OptionManager {
|
||||
}
|
||||
|
||||
static createBareOptions() {
|
||||
let opts = {};
|
||||
const opts = {};
|
||||
|
||||
for (let key in config) {
|
||||
let opt = config[key];
|
||||
for (const key in config) {
|
||||
const opt = config[key];
|
||||
opts[key] = clone(opt.default);
|
||||
}
|
||||
|
||||
@@ -119,11 +115,11 @@ export default class OptionManager {
|
||||
plugin = val;
|
||||
}
|
||||
|
||||
let alias = typeof plugin === "string" ? plugin : `${loc}$${i}`;
|
||||
const alias = typeof plugin === "string" ? plugin : `${loc}$${i}`;
|
||||
|
||||
// allow plugins to be specified as strings
|
||||
if (typeof plugin === "string") {
|
||||
let pluginLoc = resolve(`babel-plugin-${plugin}`, dirname) || resolve(plugin, dirname);
|
||||
const pluginLoc = resolvePlugin(plugin, dirname);
|
||||
if (pluginLoc) {
|
||||
plugin = require(pluginLoc);
|
||||
} else {
|
||||
@@ -152,18 +148,18 @@ export default class OptionManager {
|
||||
extending: extendingOpts,
|
||||
alias,
|
||||
loc,
|
||||
dirname
|
||||
dirname,
|
||||
}: MergeOptions) {
|
||||
alias = alias || "foreign";
|
||||
if (!rawOpts) return;
|
||||
|
||||
//
|
||||
if (typeof rawOpts !== "object" || Array.isArray(rawOpts)) {
|
||||
this.log.error(`Invalid options type for ${alias}`, TypeError);
|
||||
throw new TypeError(`Invalid options type for ${alias}`);
|
||||
}
|
||||
|
||||
//
|
||||
let opts = cloneDeepWith(rawOpts, (val) => {
|
||||
const opts = cloneDeepWith(rawOpts, (val) => {
|
||||
if (val instanceof Plugin) {
|
||||
return val;
|
||||
}
|
||||
@@ -173,18 +169,18 @@ export default class OptionManager {
|
||||
dirname = dirname || process.cwd();
|
||||
loc = loc || alias;
|
||||
|
||||
for (let key in opts) {
|
||||
let option = config[key];
|
||||
for (const key in opts) {
|
||||
const option = config[key];
|
||||
|
||||
// check for an unknown option
|
||||
if (!option && this.log) {
|
||||
if (!option) {
|
||||
if (removed[key]) {
|
||||
this.log.error(`Using removed Babel 5 option: ${alias}.${key} - ${removed[key].message}`, ReferenceError);
|
||||
throw new ReferenceError(`Using removed Babel 5 option: ${alias}.${key} - ${removed[key].message}`);
|
||||
} else {
|
||||
let unknownOptErr = `Unknown option: ${alias}.${key}. Check out http://babeljs.io/docs/usage/options/ for more information about options.`;
|
||||
let presetConfigErr = "A common cause of this error is the presence of a configuration options object without the corresponding preset name. Example:\n\nInvalid:\n `{ presets: [{option: value}] }`\nValid:\n `{ presets: [['presetName', {option: value}]] }`\n\nFor more detailed information on preset configuration, please see http://babeljs.io/docs/plugins/#pluginpresets-options.";
|
||||
// eslint-disable-next-line max-len
|
||||
const unknownOptErr = `Unknown option: ${alias}.${key}. Check out http://babeljs.io/docs/usage/options/ for more information about options.`;
|
||||
|
||||
this.log.error(`${unknownOptErr}\n\n${presetConfigErr}`, ReferenceError);
|
||||
throw new ReferenceError(unknownOptErr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -208,7 +204,7 @@ export default class OptionManager {
|
||||
extending: preset,
|
||||
alias: presetLoc,
|
||||
loc: presetLoc,
|
||||
dirname: dirname
|
||||
dirname: dirname,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
@@ -238,7 +234,7 @@ export default class OptionManager {
|
||||
options: presetOpts,
|
||||
alias: presetLoc,
|
||||
loc: presetLoc,
|
||||
dirname: path.dirname(presetLoc || "")
|
||||
dirname: path.dirname(presetLoc || ""),
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -248,89 +244,77 @@ export default class OptionManager {
|
||||
* or a module name to require.
|
||||
*/
|
||||
resolvePresets(presets: Array<string | Object>, dirname: string, onResolve?) {
|
||||
return presets.map((val) => {
|
||||
return presets.map((preset) => {
|
||||
let options;
|
||||
if (Array.isArray(val)) {
|
||||
if (val.length > 2) {
|
||||
throw new Error(`Unexpected extra options ${JSON.stringify(val.slice(2))} passed to preset.`);
|
||||
if (Array.isArray(preset)) {
|
||||
if (preset.length > 2) {
|
||||
throw new Error(`Unexpected extra options ${JSON.stringify(preset.slice(2))} passed to preset.`);
|
||||
}
|
||||
|
||||
[val, options] = val;
|
||||
[preset, options] = preset;
|
||||
}
|
||||
|
||||
let presetLoc;
|
||||
try {
|
||||
if (typeof val === "string") {
|
||||
presetLoc = resolve(`babel-preset-${val}`, dirname) || resolve(val, dirname);
|
||||
|
||||
// trying to resolve @organization shortcat
|
||||
// @foo/es2015 -> @foo/babel-preset-es2015
|
||||
if (!presetLoc) {
|
||||
let matches = val.match(/^(@[^/]+)\/(.+)$/);
|
||||
if (matches) {
|
||||
let [, orgName, presetPath] = matches;
|
||||
val = `${orgName}/babel-preset-${presetPath}`;
|
||||
presetLoc = resolve(val, dirname);
|
||||
}
|
||||
}
|
||||
if (typeof preset === "string") {
|
||||
presetLoc = resolvePreset(preset, dirname);
|
||||
|
||||
if (!presetLoc) {
|
||||
throw new Error(`Couldn't find preset ${JSON.stringify(val)} relative to directory ` +
|
||||
throw new Error(`Couldn't find preset ${JSON.stringify(preset)} relative to directory ` +
|
||||
JSON.stringify(dirname));
|
||||
}
|
||||
|
||||
val = require(presetLoc);
|
||||
}
|
||||
const resolvedPreset = this.loadPreset(presetLoc || preset, options, { dirname });
|
||||
|
||||
// If the imported preset is a transpiled ES2015 module
|
||||
if (typeof val === "object" && val.__esModule) {
|
||||
// Try to grab the default export.
|
||||
if (val.default) {
|
||||
val = val.default;
|
||||
} else {
|
||||
// If there is no default export we treat all named exports as options
|
||||
// and just remove the __esModule. This is to support presets that have been
|
||||
// exporting named exports in the past, although we definitely want presets to
|
||||
// only use the default export (with either an object or a function)
|
||||
const { __esModule, ...rest } = val; // eslint-disable-line no-unused-vars
|
||||
val = rest;
|
||||
}
|
||||
}
|
||||
if (onResolve) onResolve(resolvedPreset, presetLoc);
|
||||
|
||||
// For compatibility with babel-core < 6.13.x, allow presets to export an object with a
|
||||
// a 'buildPreset' function that will return the preset itself, while still exporting a
|
||||
// simple object (rather than a function), for supporting old Babel versions.
|
||||
if (typeof val === "object" && val.buildPreset) val = val.buildPreset;
|
||||
|
||||
|
||||
if (typeof val !== "function" && options !== undefined) {
|
||||
throw new Error(`Options ${JSON.stringify(options)} passed to ` +
|
||||
(presetLoc || "a preset") + " which does not accept options.");
|
||||
}
|
||||
|
||||
if (typeof val === "function") val = val(context, options);
|
||||
|
||||
if (typeof val !== "object") {
|
||||
throw new Error(`Unsupported preset format: ${val}.`);
|
||||
}
|
||||
|
||||
onResolve && onResolve(val, presetLoc);
|
||||
return resolvedPreset;
|
||||
} catch (e) {
|
||||
if (presetLoc) {
|
||||
e.message += ` (While processing preset: ${JSON.stringify(presetLoc)})`;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
return val;
|
||||
});
|
||||
}
|
||||
|
||||
normaliseOptions() {
|
||||
let opts = this.options;
|
||||
/**
|
||||
* Tries to load one preset. The input is either the module name of the preset,
|
||||
* a function, or an object
|
||||
*/
|
||||
loadPreset(preset, options, meta) {
|
||||
let presetFactory = preset;
|
||||
if (typeof presetFactory === "string") {
|
||||
presetFactory = require(presetFactory);
|
||||
}
|
||||
|
||||
for (let key in config) {
|
||||
let option = config[key];
|
||||
let val = opts[key];
|
||||
if (typeof presetFactory === "object" && presetFactory.__esModule) {
|
||||
if (presetFactory.default) {
|
||||
presetFactory = presetFactory.default;
|
||||
} else {
|
||||
throw new Error("Preset must export a default export when using ES6 modules.");
|
||||
}
|
||||
}
|
||||
|
||||
// Allow simple object exports
|
||||
if (typeof presetFactory === "object") {
|
||||
return presetFactory;
|
||||
}
|
||||
|
||||
if (typeof presetFactory !== "function") {
|
||||
// eslint-disable-next-line max-len
|
||||
throw new Error(`Unsupported preset format: ${typeof presetFactory}. Expected preset to return a function.`);
|
||||
}
|
||||
|
||||
return presetFactory(context, options, meta);
|
||||
}
|
||||
|
||||
normaliseOptions() {
|
||||
const opts = this.options;
|
||||
|
||||
for (const key in config) {
|
||||
const option = config[key];
|
||||
const val = opts[key];
|
||||
|
||||
// optional
|
||||
if (!val && option.optional) continue;
|
||||
@@ -345,7 +329,7 @@ export default class OptionManager {
|
||||
}
|
||||
|
||||
init(opts: Object = {}): Object {
|
||||
for (let config of buildConfigChain(opts, this.log)) {
|
||||
for (const config of buildConfigChain(opts)) {
|
||||
this.mergeOptions(config);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import slash from "slash";
|
||||
import * as util from "../../../util";
|
||||
|
||||
export let filename = slash;
|
||||
export const filename = slash;
|
||||
|
||||
export function boolean(val: any): boolean {
|
||||
return !!val;
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
/* eslint max-len: 0 */
|
||||
/* eslint max-len: "off" */
|
||||
|
||||
module.exports = {
|
||||
export default {
|
||||
"auxiliaryComment": {
|
||||
"message": "Use `auxiliaryCommentBefore` or `auxiliaryCommentAfter`"
|
||||
"message": "Use `auxiliaryCommentBefore` or `auxiliaryCommentAfter`",
|
||||
},
|
||||
"blacklist": {
|
||||
"message": "Put the specific transforms you want in the `plugins` option"
|
||||
"message": "Put the specific transforms you want in the `plugins` option",
|
||||
},
|
||||
"breakConfig": {
|
||||
"message": "This is not a necessary option in Babel 6"
|
||||
"message": "This is not a necessary option in Babel 6",
|
||||
},
|
||||
"experimental": {
|
||||
"message": "Put the specific transforms you want in the `plugins` option"
|
||||
"message": "Put the specific transforms you want in the `plugins` option",
|
||||
},
|
||||
"externalHelpers": {
|
||||
"message": "Use the `external-helpers` plugin instead. Check out http://babeljs.io/docs/plugins/external-helpers/"
|
||||
"message": "Use the `external-helpers` plugin instead. Check out http://babeljs.io/docs/plugins/external-helpers/",
|
||||
},
|
||||
"extra": {
|
||||
"message": ""
|
||||
"message": "",
|
||||
},
|
||||
"jsxPragma": {
|
||||
"message": "use the `pragma` option in the `react-jsx` plugin . Check out http://babeljs.io/docs/plugins/transform-react-jsx/"
|
||||
"message": "use the `pragma` option in the `react-jsx` plugin . Check out http://babeljs.io/docs/plugins/transform-react-jsx/",
|
||||
},
|
||||
// "keepModuleIdExtensions": {
|
||||
// "message": ""
|
||||
// },
|
||||
"loose": {
|
||||
"message": "Specify the `loose` option for the relevant plugin you are using or use a preset that sets the option."
|
||||
"message": "Specify the `loose` option for the relevant plugin you are using or use a preset that sets the option.",
|
||||
},
|
||||
"metadataUsedHelpers": {
|
||||
"message": "Not required anymore as this is enabled by default"
|
||||
"message": "Not required anymore as this is enabled by default",
|
||||
},
|
||||
"modules": {
|
||||
"message": "Use the corresponding module transform plugin in the `plugins` option. Check out http://babeljs.io/docs/plugins/#modules",
|
||||
@@ -38,15 +38,15 @@ module.exports = {
|
||||
"message": "Use the `react-jsx` and `flow-strip-types` plugins to support JSX and Flow. Also check out the react preset http://babeljs.io/docs/plugins/preset-react/",
|
||||
},
|
||||
"optional": {
|
||||
"message": "Put the specific transforms you want in the `plugins` option"
|
||||
"message": "Put the specific transforms you want in the `plugins` option",
|
||||
},
|
||||
"sourceMapName": {
|
||||
"message": "Use the `sourceMapTarget` option"
|
||||
"message": "Use the `sourceMapTarget` option",
|
||||
},
|
||||
"stage": {
|
||||
"message": "Check out the corresponding stage-x presets http://babeljs.io/docs/plugins/#presets"
|
||||
"message": "Check out the corresponding stage-x presets http://babeljs.io/docs/plugins/#presets",
|
||||
},
|
||||
"whitelist": {
|
||||
"message": "Put the specific transforms you want in the `plugins` option"
|
||||
}
|
||||
"message": "Put the specific transforms you want in the `plugins` option",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@ export default new Plugin({
|
||||
exit({ node }) {
|
||||
let hasChange = false;
|
||||
for (let i = 0; i < node.body.length; i++) {
|
||||
let bodyNode = node.body[i];
|
||||
const bodyNode = node.body[i];
|
||||
if (bodyNode && bodyNode._blockHoist != null) {
|
||||
hasChange = true;
|
||||
break;
|
||||
@@ -36,7 +36,7 @@ export default new Plugin({
|
||||
// Higher priorities should move toward the top.
|
||||
return -1 * priority;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -7,12 +7,12 @@ const superVisitor = {
|
||||
CallExpression(path) {
|
||||
if (!path.get("callee").isSuper()) return;
|
||||
|
||||
const {node} = path;
|
||||
const { node } = path;
|
||||
if (node[SUPER_THIS_BOUND]) return;
|
||||
node[SUPER_THIS_BOUND] = true;
|
||||
|
||||
path.replaceWith(t.assignmentExpression("=", this.id, node));
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default new Plugin({
|
||||
@@ -27,8 +27,8 @@ export default new Plugin({
|
||||
if (path.node.name === "arguments") {
|
||||
remap(path, "arguments");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
function shouldShadow(path, shadowPath) {
|
||||
@@ -41,10 +41,10 @@ function shouldShadow(path, shadowPath) {
|
||||
|
||||
function remap(path, key) {
|
||||
// ensure that we're shadowed
|
||||
let shadowPath = path.inShadow(key);
|
||||
const shadowPath = path.inShadow(key);
|
||||
if (!shouldShadow(path, shadowPath)) return;
|
||||
|
||||
let shadowFunction = path.node._shadowedFunctionLiteral;
|
||||
const shadowFunction = path.node._shadowedFunctionLiteral;
|
||||
|
||||
let currentFunction;
|
||||
let passedShadowFunction = false;
|
||||
@@ -91,17 +91,17 @@ function remap(path, key) {
|
||||
// binding since arrow function syntax already does that.
|
||||
if (!passedShadowFunction) return;
|
||||
|
||||
let cached = fnPath.getData(key);
|
||||
const cached = fnPath.getData(key);
|
||||
if (cached) return path.replaceWith(cached);
|
||||
|
||||
let id = path.scope.generateUidIdentifier(key);
|
||||
const id = path.scope.generateUidIdentifier(key);
|
||||
|
||||
fnPath.setData(key, id);
|
||||
|
||||
let classPath = fnPath.findParent((p) => p.isClass());
|
||||
let hasSuperClass = !!(classPath && classPath.node && classPath.node.superClass);
|
||||
const classPath = fnPath.findParent((p) => p.isClass());
|
||||
const hasSuperClass = !!(classPath && classPath.node && classPath.node.superClass);
|
||||
|
||||
if (key === "this" && fnPath.isMethod({kind: "constructor"}) && hasSuperClass) {
|
||||
if (key === "this" && fnPath.isMethod({ kind: "constructor" }) && hasSuperClass) {
|
||||
fnPath.scope.push({ id });
|
||||
|
||||
fnPath.traverse(superVisitor, { id });
|
||||
|
||||
@@ -3,48 +3,31 @@ import normalizeAst from "../helpers/normalize-ast";
|
||||
import Plugin from "./plugin";
|
||||
import File from "./file";
|
||||
|
||||
export default class Pipeline {
|
||||
lint(code: string, opts?: Object = {}): BabelFileResult {
|
||||
opts.code = false;
|
||||
opts.mode = "lint";
|
||||
return this.transform(code, opts);
|
||||
}
|
||||
|
||||
pretransform(code: string, opts?: Object): BabelFileResult {
|
||||
let file = new File(opts, this);
|
||||
return file.wrap(code, function () {
|
||||
file.addCode(code);
|
||||
file.parseCode(code);
|
||||
return file;
|
||||
});
|
||||
}
|
||||
|
||||
transform(code: string, opts?: Object): BabelFileResult {
|
||||
let file = new File(opts, this);
|
||||
return file.wrap(code, function () {
|
||||
file.addCode(code);
|
||||
file.parseCode(code);
|
||||
return file.transform();
|
||||
});
|
||||
}
|
||||
|
||||
analyse(code: string, opts: Object = {}, visitor?: Object): ?BabelFileMetadata {
|
||||
opts.code = false;
|
||||
if (visitor) {
|
||||
opts.plugins = opts.plugins || [];
|
||||
opts.plugins.push(new Plugin({ visitor }));
|
||||
}
|
||||
return this.transform(code, opts).metadata;
|
||||
}
|
||||
|
||||
transformFromAst(ast: Object, code: string, opts: Object): BabelFileResult {
|
||||
ast = normalizeAst(ast);
|
||||
|
||||
let file = new File(opts, this);
|
||||
return file.wrap(code, function () {
|
||||
file.addCode(code);
|
||||
file.addAst(ast);
|
||||
return file.transform();
|
||||
});
|
||||
export function analyse(code: string, opts: Object = {}, visitor?: Object): ?BabelFileMetadata {
|
||||
opts.code = false;
|
||||
if (visitor) {
|
||||
opts.plugins = opts.plugins || [];
|
||||
opts.plugins.push(new Plugin({ visitor }));
|
||||
}
|
||||
return transform(code, opts).metadata;
|
||||
}
|
||||
|
||||
export function transform(code: string, opts?: Object): BabelFileResult {
|
||||
const file = new File(opts);
|
||||
return file.wrap(code, function () {
|
||||
file.addCode(code);
|
||||
file.parseCode(code);
|
||||
return file.transform();
|
||||
});
|
||||
}
|
||||
|
||||
export function transformFromAst(ast: Object, code: string, opts: Object): BabelFileResult {
|
||||
ast = normalizeAst(ast);
|
||||
|
||||
const file = new File(opts);
|
||||
return file.wrap(code, function () {
|
||||
file.addCode(code);
|
||||
file.addAst(ast);
|
||||
return file.transform();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ export default class PluginPass extends Store {
|
||||
constructor(file: File, plugin: Plugin, options: Object = {}) {
|
||||
super();
|
||||
this.plugin = plugin;
|
||||
this.key = plugin.key;
|
||||
this.file = file;
|
||||
this.opts = options;
|
||||
this.key = plugin.key;
|
||||
this.file = file;
|
||||
this.opts = options;
|
||||
}
|
||||
|
||||
key: string;
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
/* eslint max-len: 0 */
|
||||
|
||||
import OptionManager from "./file/options/option-manager";
|
||||
import * as messages from "babel-messages";
|
||||
import Store from "../store";
|
||||
import traverse from "babel-traverse";
|
||||
import assign from "lodash/assign";
|
||||
import clone from "lodash/clone";
|
||||
|
||||
const GLOBAL_VISITOR_PROPS = ["enter", "exit"];
|
||||
@@ -14,13 +11,13 @@ export default class Plugin extends Store {
|
||||
super();
|
||||
|
||||
this.initialized = false;
|
||||
this.raw = assign({}, plugin);
|
||||
this.key = this.take("name") || key;
|
||||
this.raw = Object.assign({}, plugin);
|
||||
this.key = this.take("name") || key;
|
||||
|
||||
this.manipulateOptions = this.take("manipulateOptions");
|
||||
this.post = this.take("post");
|
||||
this.pre = this.take("pre");
|
||||
this.visitor = this.normaliseVisitor(clone(this.take("visitor")) || {});
|
||||
this.post = this.take("post");
|
||||
this.pre = this.take("pre");
|
||||
this.visitor = this.normaliseVisitor(clone(this.take("visitor")) || {});
|
||||
}
|
||||
|
||||
initialized: boolean;
|
||||
@@ -31,7 +28,7 @@ export default class Plugin extends Store {
|
||||
visitor: Object;
|
||||
|
||||
take(key) {
|
||||
let val = this.raw[key];
|
||||
const val = this.raw[key];
|
||||
delete this.raw[key];
|
||||
return val;
|
||||
}
|
||||
@@ -40,13 +37,13 @@ export default class Plugin extends Store {
|
||||
if (!target[key]) return this[key];
|
||||
if (!this[key]) return target[key];
|
||||
|
||||
let fns: Array<?Function> = [target[key], this[key]];
|
||||
const fns: Array<?Function> = [target[key], this[key]];
|
||||
|
||||
return function (...args) {
|
||||
let val;
|
||||
for (let fn of fns) {
|
||||
for (const fn of fns) {
|
||||
if (fn) {
|
||||
let ret = fn.apply(this, args);
|
||||
const ret = fn.apply(this, args);
|
||||
if (ret != null) val = ret;
|
||||
}
|
||||
}
|
||||
@@ -77,15 +74,16 @@ export default class Plugin extends Store {
|
||||
|
||||
this.maybeInherit(loc);
|
||||
|
||||
for (let key in this.raw) {
|
||||
for (const key in this.raw) {
|
||||
throw new Error(messages.get("pluginInvalidProperty", loc, i, key));
|
||||
}
|
||||
}
|
||||
|
||||
normaliseVisitor(visitor: Object): Object {
|
||||
for (let key of GLOBAL_VISITOR_PROPS) {
|
||||
for (const key of GLOBAL_VISITOR_PROPS) {
|
||||
if (visitor[key]) {
|
||||
throw new Error("Plugins aren't allowed to specify catch-all enter/exit handlers. Please target individual nodes.");
|
||||
throw new Error("Plugins aren't allowed to specify catch-all enter/exit handlers. " +
|
||||
"Please target individual nodes.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import escapeRegExp from "lodash/escapeRegExp";
|
||||
import startsWith from "lodash/startsWith";
|
||||
import isBoolean from "lodash/isBoolean";
|
||||
import minimatch from "minimatch";
|
||||
import includes from "lodash/includes";
|
||||
import isString from "lodash/isString";
|
||||
import isRegExp from "lodash/isRegExp";
|
||||
import path from "path";
|
||||
import slash from "slash";
|
||||
@@ -15,8 +13,8 @@ export { inherits, inspect } from "util";
|
||||
*/
|
||||
|
||||
export function canCompile(filename: string, altExts?: Array<string>): boolean {
|
||||
let exts = altExts || canCompile.EXTENSIONS;
|
||||
let ext = path.extname(filename);
|
||||
const exts = altExts || canCompile.EXTENSIONS;
|
||||
const ext = path.extname(filename);
|
||||
return includes(exts, ext);
|
||||
}
|
||||
|
||||
@@ -63,7 +61,7 @@ export function regexify(val: any): RegExp {
|
||||
if (startsWith(val, "./") || startsWith(val, "*/")) val = val.slice(2);
|
||||
if (startsWith(val, "**/")) val = val.slice(3);
|
||||
|
||||
let regex = minimatch.makeRe(val, { nocase: true });
|
||||
const regex = minimatch.makeRe(val, { nocase: true });
|
||||
return new RegExp(regex.source.slice(1, -1), "i");
|
||||
}
|
||||
|
||||
@@ -80,8 +78,8 @@ export function regexify(val: any): RegExp {
|
||||
|
||||
export function arrayify(val: any, mapFn?: Function): Array<any> {
|
||||
if (!val) return [];
|
||||
if (isBoolean(val)) return arrayify([val], mapFn);
|
||||
if (isString(val)) return arrayify(list(val), mapFn);
|
||||
if (typeof val === "boolean") return arrayify([val], mapFn);
|
||||
if (typeof val === "string") return arrayify(list(val), mapFn);
|
||||
|
||||
if (Array.isArray(val)) {
|
||||
if (mapFn) val = val.map(mapFn);
|
||||
@@ -119,12 +117,12 @@ export function shouldIgnore(
|
||||
filename = filename.replace(/\\/g, "/");
|
||||
|
||||
if (only) {
|
||||
for (let pattern of only) {
|
||||
for (const pattern of only) {
|
||||
if (_shouldIgnore(pattern, filename)) return false;
|
||||
}
|
||||
return true;
|
||||
} else if (ignore.length) {
|
||||
for (let pattern of ignore) {
|
||||
for (const pattern of ignore) {
|
||||
if (_shouldIgnore(pattern, filename)) return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user