rewrite options handling to be MUCH more maintainable and less like spaghetti
This commit is contained in:
parent
9805c0387f
commit
9efb02f60f
@ -3,8 +3,8 @@ import merge from "lodash/object/merge";
|
||||
export default function (dest, src) {
|
||||
if (!dest || !src) return;
|
||||
|
||||
return merge(dest, src, function(a, b) {
|
||||
if (Array.isArray(a)) {
|
||||
return merge(dest, src, function (a, b) {
|
||||
if (b && Array.isArray(a)) {
|
||||
var c = a.slice(0);
|
||||
for (var v of b) {
|
||||
if (a.indexOf(v) < 0) {
|
||||
|
||||
@ -1,25 +1,20 @@
|
||||
import { validateOption, normaliseOptions, config as optionsConfig } from "./options";
|
||||
import convertSourceMap from "convert-source-map";
|
||||
import moduleFormatters from "../modules";
|
||||
import OptionManager from "./options/option-manager";
|
||||
import PluginManager from "./plugin-manager";
|
||||
import shebangRegex from "shebang-regex";
|
||||
import NodePath from "../../traversal/path";
|
||||
import isFunction from "lodash/lang/isFunction";
|
||||
import isAbsolute from "path-is-absolute";
|
||||
import resolveRc from "./options/resolve-rc";
|
||||
import sourceMap from "source-map";
|
||||
import generate from "../../generation";
|
||||
import codeFrame from "../../helpers/code-frame";
|
||||
import defaults from "lodash/object/defaults";
|
||||
import includes from "lodash/collection/includes";
|
||||
import traverse from "../../traversal";
|
||||
import assign from "lodash/object/assign";
|
||||
import Logger from "./logger";
|
||||
import Plugin from "../plugin";
|
||||
import parse from "../../helpers/parse";
|
||||
import merge from "../../helpers/merge";
|
||||
import slash from "slash";
|
||||
import clone from "lodash/lang/clone";
|
||||
import Hub from "../../traversal/hub";
|
||||
import * as util from "../../util";
|
||||
import path from "path";
|
||||
@ -50,10 +45,9 @@ export default class File {
|
||||
|
||||
this.pipeline = pipeline;
|
||||
this.log = new Logger(this, opts.filename || "unknown");
|
||||
this.opts = this.initOptions(opts);
|
||||
this.ast = {};
|
||||
|
||||
this.normaliseOptions(opts);
|
||||
|
||||
this.buildTransformers();
|
||||
|
||||
this.hub = new Hub(this);
|
||||
@ -98,56 +92,8 @@ export default class File {
|
||||
|
||||
static soloHelpers = [];
|
||||
|
||||
static options = optionsConfig;
|
||||
|
||||
normaliseOptions(opts: Object) {
|
||||
opts = this.opts = normaliseOptions(assign({}, opts));
|
||||
|
||||
// resolve babelrc
|
||||
if (opts.filename) {
|
||||
var rcFilename = opts.filename;
|
||||
if (!isAbsolute(rcFilename)) rcFilename = path.join(process.cwd(), rcFilename);
|
||||
opts = resolveRc(rcFilename, opts);
|
||||
}
|
||||
|
||||
// check for unknown options
|
||||
for (let key in opts) {
|
||||
if (key[0] === "_") continue;
|
||||
|
||||
let option = File.options[key];
|
||||
if (!option) this.log.error(`Unknown option: ${key}`, ReferenceError);
|
||||
}
|
||||
|
||||
// merge in environment options
|
||||
var envKey = process.env.BABEL_ENV || process.env.NODE_ENV || "development";
|
||||
if (opts.env) merge(opts, normaliseOptions(opts.env[envKey]));
|
||||
|
||||
// normalise options
|
||||
for (let key in File.options) {
|
||||
let option = File.options[key];
|
||||
var val = opts[key];
|
||||
|
||||
// optional
|
||||
if (!val && option.optional) continue;
|
||||
|
||||
// deprecated
|
||||
if (val && option.deprecated) {
|
||||
this.log.deprecate("Deprecated option " + key + ": " + option.deprecated);
|
||||
}
|
||||
|
||||
// default
|
||||
if (val == null) val = clone(option.default);
|
||||
|
||||
// validate
|
||||
if (val) val = validateOption(key, val, this.pipeline);
|
||||
|
||||
// aaliases
|
||||
if (option.alias) {
|
||||
opts[option.alias] = opts[option.alias] || val;
|
||||
} else {
|
||||
opts[key] = val;
|
||||
}
|
||||
}
|
||||
initOptions(opts) {
|
||||
opts = new OptionManager(this.log, this.pipeline).init(opts);
|
||||
|
||||
if (opts.inputSourceMap) {
|
||||
opts.sourceMaps = true;
|
||||
@ -195,7 +141,7 @@ export default class File {
|
||||
}
|
||||
|
||||
return opts;
|
||||
};
|
||||
}
|
||||
|
||||
isLoose(key: string) {
|
||||
return includes(this.opts.loose, key);
|
||||
|
||||
@ -253,7 +253,7 @@
|
||||
},
|
||||
|
||||
"babelrc": {
|
||||
"hidden": true,
|
||||
"description": "do not load the same .babelrc file twice"
|
||||
"description": "Specify a custom list of babelrc files to use",
|
||||
"type": "list"
|
||||
}
|
||||
}
|
||||
|
||||
168
src/babel/transformation/file/options/option-manager.js
Normal file
168
src/babel/transformation/file/options/option-manager.js
Normal file
@ -0,0 +1,168 @@
|
||||
import stripJsonComments from "strip-json-comments";
|
||||
import { validateOption, normaliseOptions } from "./index";
|
||||
import isAbsolute from "path-is-absolute";
|
||||
import clone from "lodash/lang/clone";
|
||||
import merge from "../../../helpers/merge";
|
||||
import config from "./config";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import pathExists from "path-exists";
|
||||
|
||||
var existsCache = {};
|
||||
var jsonCache = {};
|
||||
|
||||
const CONFIG_FILENAME = ".babelrc";
|
||||
|
||||
function exists(filename) {
|
||||
var cached = existsCache[filename];
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
} else {
|
||||
return existsCache[filename] = pathExists.sync(filename);
|
||||
}
|
||||
}
|
||||
|
||||
export default class OptionManager {
|
||||
constructor(log, pipeline) {
|
||||
this.resolvedConfigs = [];
|
||||
this.options = OptionManager.createBareOptions();
|
||||
this.pipeline = pipeline;
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
static createBareOptions() {
|
||||
var opts = {};
|
||||
|
||||
for (var key in config) {
|
||||
var opt = config[key];
|
||||
opts[key] = clone(opt.default);
|
||||
}
|
||||
|
||||
return opts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
addConfig(loc) {
|
||||
if (this.resolvedConfigs.indexOf(loc) >= 0) return;
|
||||
|
||||
var content = fs.readFileSync(loc, "utf8");
|
||||
var opts;
|
||||
|
||||
try {
|
||||
opts = jsonCache[content] = jsonCache[content] || JSON.parse(stripJsonComments(content));
|
||||
} catch (err) {
|
||||
err.message = `${loc}: ${err.message}`;
|
||||
throw err;
|
||||
}
|
||||
|
||||
this.mergeOptions(opts, loc);
|
||||
this.resolvedConfigs.push(loc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
mergeOptions(opts, alias) {
|
||||
if (!opts) return;
|
||||
|
||||
for (let key in opts) {
|
||||
if (key[0] === "_") continue;
|
||||
|
||||
let option = config[key];
|
||||
|
||||
// check for an unknown option
|
||||
if (!option) this.log.error(`Unknown option: ${alias}.${key}`, ReferenceError);
|
||||
}
|
||||
|
||||
// normalise options
|
||||
normaliseOptions(opts);
|
||||
|
||||
// merge them into this current files options
|
||||
merge(this.options, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
findConfigs(loc) {
|
||||
if (!loc) return;
|
||||
|
||||
if (!isAbsolute(loc)) {
|
||||
loc = path.join(process.cwd(), loc);
|
||||
}
|
||||
|
||||
while (loc !== (loc = path.dirname(loc))) {
|
||||
if (this.options.breakConfig) return;
|
||||
|
||||
var configLoc = path.join(loc, CONFIG_FILENAME);
|
||||
if (exists(configLoc)) this.addConfig(configLoc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
normaliseOptions() {
|
||||
var opts = this.options;
|
||||
|
||||
for (let key in config) {
|
||||
var option = config[key];
|
||||
var val = opts[key];
|
||||
|
||||
// optional
|
||||
if (!val && option.optional) continue;
|
||||
|
||||
// deprecated
|
||||
if (val && option.deprecated) {
|
||||
this.log.deprecate(`Deprecated option ${key}: ${option.deprecated}`);
|
||||
}
|
||||
|
||||
// validate
|
||||
if (val) val = validateOption(key, val, this.pipeline);
|
||||
|
||||
// aaliases
|
||||
if (option.alias) {
|
||||
opts[option.alias] = opts[option.alias] || val;
|
||||
} else {
|
||||
opts[key] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
init(opts) {
|
||||
this.mergeOptions(opts, "direct");
|
||||
|
||||
// babelrc option
|
||||
if (opts.babelrc) {
|
||||
for (var loc of (opts.babelrc: Array)) this.addConfig(loc);
|
||||
}
|
||||
|
||||
// resolve all .babelrc files
|
||||
this.findConfigs(opts.filename);
|
||||
|
||||
// merge in env
|
||||
var envKey = process.env.BABEL_ENV || process.env.NODE_ENV || "development";
|
||||
if (this.options.env) {
|
||||
this.mergeOptions(this.options.env[envKey], `direct.env.${envKey}`);
|
||||
}
|
||||
|
||||
// normalise
|
||||
this.normaliseOptions(opts);
|
||||
|
||||
return this.options;
|
||||
}
|
||||
}
|
||||
@ -1,61 +0,0 @@
|
||||
import stripJsonComments from "strip-json-comments";
|
||||
import { normaliseOptions } from "./index";
|
||||
import merge from "../../../helpers/merge";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import pathExists from "path-exists";
|
||||
|
||||
var cache = {};
|
||||
var jsons = {};
|
||||
|
||||
function exists(filename) {
|
||||
var cached = cache[filename];
|
||||
if (cached != null) return cached;
|
||||
return cache[filename] = pathExists.sync(filename);
|
||||
}
|
||||
|
||||
export default function (loc, opts = {}) {
|
||||
var rel = ".babelrc";
|
||||
|
||||
if (!opts.babelrc) {
|
||||
opts.babelrc = [];
|
||||
}
|
||||
|
||||
function find(start, rel) {
|
||||
var file = path.join(start, rel);
|
||||
|
||||
if (opts.babelrc.indexOf(file) >= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (exists(file)) {
|
||||
var content = fs.readFileSync(file, "utf8");
|
||||
var json;
|
||||
|
||||
try {
|
||||
json = jsons[content] = jsons[content] || JSON.parse(stripJsonComments(content));
|
||||
normaliseOptions(json);
|
||||
} catch (err) {
|
||||
err.message = `${file}: ${err.message}`;
|
||||
throw err;
|
||||
}
|
||||
|
||||
opts.babelrc.push(file);
|
||||
|
||||
if (json.breakConfig) return;
|
||||
|
||||
merge(opts, json);
|
||||
}
|
||||
|
||||
var up = path.dirname(start);
|
||||
if (up !== start) { // root
|
||||
find(up, rel);
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.babelrc.indexOf(loc) < 0 && opts.breakConfig !== true) {
|
||||
find(loc, rel);
|
||||
}
|
||||
|
||||
return opts;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user