Separate config/plugin loading from config processing. (#5563)
This commit is contained in:
@@ -21,6 +21,9 @@
|
||||
"babel-core",
|
||||
"compiler"
|
||||
],
|
||||
"browser": {
|
||||
"./lib/config/loading/files/index.js": "./lib/config/loading/files/index-browser.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-code-frame": "7.0.0-alpha.3",
|
||||
"babel-generator": "7.0.0-alpha.3",
|
||||
|
||||
@@ -1,26 +1,8 @@
|
||||
import * as babel from "../index";
|
||||
import resolve from "./helpers/resolve";
|
||||
import json5 from "json5";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import micromatch from "micromatch";
|
||||
|
||||
const existsCache = {};
|
||||
const jsonCache = {};
|
||||
|
||||
const BABELRC_FILENAME = ".babelrc";
|
||||
const BABELRC_JS_FILENAME = ".babelrc.js";
|
||||
const PACKAGE_FILENAME = "package.json";
|
||||
const BABELIGNORE_FILENAME = ".babelignore";
|
||||
|
||||
function exists(filename) {
|
||||
const cached = existsCache[filename];
|
||||
if (cached == null) {
|
||||
return existsCache[filename] = fs.existsSync(filename);
|
||||
} else {
|
||||
return cached;
|
||||
}
|
||||
}
|
||||
import { findConfigs, loadConfig } from "./loading/files";
|
||||
|
||||
export default function buildConfigChain(opts: Object = {}) {
|
||||
const filename = opts.filename ? path.resolve(opts.filename) : null;
|
||||
@@ -49,7 +31,6 @@ export default function buildConfigChain(opts: Object = {}) {
|
||||
|
||||
class ConfigChainBuilder {
|
||||
constructor(filename) {
|
||||
this.resolvedConfigs = [];
|
||||
this.configs = [];
|
||||
this.filename = filename;
|
||||
this.possibleDirs = null;
|
||||
@@ -124,11 +105,6 @@ class ConfigChainBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -136,110 +112,14 @@ class ConfigChainBuilder {
|
||||
loc = path.join(process.cwd(), loc);
|
||||
}
|
||||
|
||||
let foundConfig = false;
|
||||
let foundIgnore = false;
|
||||
|
||||
while (loc !== (loc = path.dirname(loc))) {
|
||||
if (!foundIgnore) {
|
||||
const ignoreLoc = path.join(loc, BABELIGNORE_FILENAME);
|
||||
if (exists(ignoreLoc)) {
|
||||
this.addIgnoreConfig(ignoreLoc);
|
||||
foundIgnore = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundConfig) {
|
||||
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);
|
||||
|
||||
if (configAdded && arr.length) {
|
||||
this.errorMultipleConfigs(arr.pop(), config);
|
||||
}
|
||||
|
||||
if (configAdded) arr.push(config);
|
||||
}
|
||||
|
||||
return arr;
|
||||
}, []);
|
||||
|
||||
foundConfig = !!foundConfigs.length;
|
||||
}
|
||||
|
||||
if (foundIgnore && foundConfig) return;
|
||||
}
|
||||
}
|
||||
|
||||
addIgnoreConfig(loc: string) {
|
||||
const file = fs.readFileSync(loc, "utf8");
|
||||
let lines = file.split("\n");
|
||||
|
||||
lines = lines
|
||||
.map((line) => line.replace(/#(.*?)$/, "").trim())
|
||||
.filter((line) => !!line);
|
||||
|
||||
if (lines.length) {
|
||||
findConfigs(path.dirname(loc)).forEach(({ filepath, dirname, options }) => {
|
||||
this.mergeConfig({
|
||||
type: "options",
|
||||
options: { ignore: lines },
|
||||
alias: loc,
|
||||
dirname: path.dirname(loc),
|
||||
options,
|
||||
alias: filepath,
|
||||
dirname,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
addConfig(loc: string, key?: string, json = json5): boolean {
|
||||
if (this.resolvedConfigs.indexOf(loc) >= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.resolvedConfigs.push(loc);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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({
|
||||
type: "options",
|
||||
options,
|
||||
alias: loc,
|
||||
dirname: path.dirname(loc),
|
||||
});
|
||||
|
||||
return !!options;
|
||||
}
|
||||
|
||||
mergeConfig({
|
||||
@@ -287,11 +167,18 @@ class ConfigChainBuilder {
|
||||
|
||||
// add extends clause
|
||||
if (options.extends) {
|
||||
const extendsLoc = resolve(options.extends, dirname);
|
||||
if (extendsLoc) {
|
||||
this.addConfig(extendsLoc);
|
||||
} else {
|
||||
throw new Error(`Couldn't resolve extends clause of ${options.extends} in ${alias}`);
|
||||
const extendsConfig = loadConfig(options.extends, dirname);
|
||||
|
||||
const existingConfig = this.configs.some((config) => {
|
||||
return config.alias === extendsConfig.filepath;
|
||||
});
|
||||
if (!existingConfig) {
|
||||
this.mergeConfig({
|
||||
type: "options",
|
||||
alias: extendsConfig.filepath,
|
||||
options: extendsConfig.options,
|
||||
dirname: extendsConfig.dirname,
|
||||
});
|
||||
}
|
||||
delete options.extends;
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export default function getPossiblePluginNames(pluginName: string): Array<string> {
|
||||
return [`babel-plugin-${pluginName}`, pluginName];
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
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;
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
import resolve from "./resolve";
|
||||
|
||||
export default function resolveFromPossibleNames(possibleNames: Array<string>, dirname: string): ?string {
|
||||
return possibleNames.reduce((accum, curr) => accum || resolve(curr, dirname), null);
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
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,9 +0,0 @@
|
||||
import resolve from "resolve";
|
||||
|
||||
export default function (loc: string, relative: string = process.cwd()): ?string {
|
||||
try {
|
||||
return resolve.sync(loc, { basedir: relative });
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
175
packages/babel-core/src/config/loading/files/configuration.js
Normal file
175
packages/babel-core/src/config/loading/files/configuration.js
Normal file
@@ -0,0 +1,175 @@
|
||||
// @flow
|
||||
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import json5 from "json5";
|
||||
import resolve from "resolve";
|
||||
|
||||
type ConfigFile = {
|
||||
filepath: string,
|
||||
dirname: string,
|
||||
options: Object,
|
||||
};
|
||||
|
||||
const existsCache = {};
|
||||
const jsonCache = {};
|
||||
|
||||
const BABELRC_FILENAME = ".babelrc";
|
||||
const BABELRC_JS_FILENAME = ".babelrc.js";
|
||||
const PACKAGE_FILENAME = "package.json";
|
||||
const BABELIGNORE_FILENAME = ".babelignore";
|
||||
|
||||
function exists(filename) {
|
||||
const cached = existsCache[filename];
|
||||
if (cached == null) {
|
||||
return existsCache[filename] = fs.existsSync(filename);
|
||||
} else {
|
||||
return cached;
|
||||
}
|
||||
}
|
||||
|
||||
export function findConfigs(dirname: string): Array<ConfigFile> {
|
||||
let foundConfig = false;
|
||||
let foundIgnore = false;
|
||||
|
||||
const confs = [];
|
||||
|
||||
let loc = dirname;
|
||||
while (true) {
|
||||
if (!foundIgnore) {
|
||||
const ignoreLoc = path.join(loc, BABELIGNORE_FILENAME);
|
||||
const ignore = readIgnoreConfig(ignoreLoc);
|
||||
|
||||
if (ignore) {
|
||||
confs.push(ignore);
|
||||
foundIgnore = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundConfig) {
|
||||
const conf = [
|
||||
BABELRC_FILENAME,
|
||||
BABELRC_JS_FILENAME,
|
||||
PACKAGE_FILENAME,
|
||||
].reduce((previousConfig: ConfigFile|null, name) => {
|
||||
const filepath = path.join(loc, name);
|
||||
const config = readConfig(filepath);
|
||||
|
||||
if (config && previousConfig) {
|
||||
throw new Error(`Multiple configuration files found. Please remove one:\n- ${
|
||||
path.basename(previousConfig.filepath)}\n- ${name}\nfrom ${loc}`);
|
||||
}
|
||||
|
||||
return config || previousConfig;
|
||||
}, null);
|
||||
|
||||
if (conf) {
|
||||
confs.push(conf);
|
||||
foundConfig = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundIgnore && foundConfig) break;
|
||||
|
||||
if (loc === path.dirname(loc)) break;
|
||||
|
||||
loc = path.dirname(loc);
|
||||
}
|
||||
|
||||
return confs;
|
||||
}
|
||||
|
||||
export function loadConfig(name: string, dirname: string): ConfigFile {
|
||||
const filepath = resolve.sync(name, { basedir: dirname });
|
||||
|
||||
const conf = readConfig(filepath);
|
||||
if (!conf) throw new Error(`Config file ${filepath} contains no configuration data`);
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the given config file, returning the result. Returns null if no config was found, but will
|
||||
* throw if there are parsing errors while loading a config.
|
||||
*/
|
||||
function readConfig(filepath) {
|
||||
return (path.extname(filepath) === ".js") ? readConfigJS(filepath) : readConfigFile(filepath);
|
||||
}
|
||||
|
||||
function readIgnoreConfig(filepath) {
|
||||
if (!exists(filepath)) return null;
|
||||
|
||||
const file = fs.readFileSync(filepath, "utf8");
|
||||
let lines = file.split("\n");
|
||||
|
||||
lines = lines
|
||||
.map((line) => line.replace(/#(.*?)$/, "").trim())
|
||||
.filter((line) => !!line);
|
||||
|
||||
return {
|
||||
filepath,
|
||||
dirname: path.dirname(filepath),
|
||||
options: { ignore: lines },
|
||||
};
|
||||
}
|
||||
|
||||
function readConfigJS(filepath) {
|
||||
if (!exists(filepath)) return null;
|
||||
|
||||
let options;
|
||||
try {
|
||||
// $FlowIssue
|
||||
const configModule = (require(filepath): mixed);
|
||||
options = configModule && configModule.__esModule ? (configModule.default || undefined) : configModule;
|
||||
} catch (err) {
|
||||
err.message = `${filepath}: Error while loading config - ${err.message}`;
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
||||
throw new Error(`${filepath}: Configuration should be an exported JavaScript object.`);
|
||||
}
|
||||
|
||||
return {
|
||||
filepath,
|
||||
dirname: path.dirname(filepath),
|
||||
options,
|
||||
};
|
||||
}
|
||||
|
||||
function readConfigFile(filepath) {
|
||||
if (!exists(filepath)) return null;
|
||||
|
||||
const content = fs.readFileSync(filepath, "utf8");
|
||||
|
||||
let options;
|
||||
if (path.basename(filepath) === PACKAGE_FILENAME) {
|
||||
try {
|
||||
const json = jsonCache[content] = jsonCache[content] || JSON.parse(content);
|
||||
|
||||
options = json.babel;
|
||||
} catch (err) {
|
||||
err.message = `${filepath}: Error while parsing JSON - ${err.message}`;
|
||||
throw err;
|
||||
}
|
||||
if (!options) return null;
|
||||
} else {
|
||||
try {
|
||||
options = jsonCache[content] = jsonCache[content] || json5.parse(content);
|
||||
} catch (err) {
|
||||
err.message = `${filepath}: Error while parsing config - ${err.message}`;
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (!options) throw new Error(`${filepath}: No config detected`);
|
||||
}
|
||||
|
||||
if (typeof options !== "object") throw new Error(`${filepath}: Config returned typeof ${typeof options}`);
|
||||
if (Array.isArray(options)) throw new Error(`${filepath}: Expected config object but found array`);
|
||||
|
||||
return {
|
||||
filepath,
|
||||
dirname: path.dirname(filepath),
|
||||
options,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// @flow
|
||||
|
||||
type ConfigFile = {
|
||||
filepath: string,
|
||||
dirname: string,
|
||||
options: Object,
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
export function findConfigs(dirname: string): Array<ConfigFile> {
|
||||
return [];
|
||||
}
|
||||
|
||||
export function loadConfig(name: string, dirname: string): ConfigFile {
|
||||
throw new Error(`Cannot load ${name} relative to ${dirname} in a browser`);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
export function resolvePlugin(name: string, dirname: string): string|null {
|
||||
return null;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
export function resolvePreset(name: string, dirname: string): string|null {
|
||||
return null;
|
||||
}
|
||||
|
||||
export function loadPlugin(name: string, dirname: string): { filepath: string, plugin: mixed } {
|
||||
throw new Error(`Cannot load plugin ${name} relative to ${dirname} in a browser`);
|
||||
}
|
||||
|
||||
export function loadPreset(name: string, dirname: string): { filepath: string, preset: mixed } {
|
||||
throw new Error(`Cannot load preset ${name} relative to ${dirname} in a browser`);
|
||||
}
|
||||
|
||||
export function loadParser(name: string, dirname: string): { filepath: string, parser: Function } {
|
||||
throw new Error(`Cannot load parser ${name} relative to ${dirname} in a browser`);
|
||||
}
|
||||
|
||||
export function loadGenerator(name: string, dirname: string): { filepath: string, generator: Function } {
|
||||
throw new Error(`Cannot load generator ${name} relative to ${dirname} in a browser`);
|
||||
}
|
||||
11
packages/babel-core/src/config/loading/files/index.js
Normal file
11
packages/babel-core/src/config/loading/files/index.js
Normal file
@@ -0,0 +1,11 @@
|
||||
// @flow
|
||||
|
||||
import typeof * as indexBrowserType from "./index-browser";
|
||||
import typeof * as indexType from "./index";
|
||||
|
||||
// Kind of gross, but essentially asserting that the exports of this module are the same as the
|
||||
// exports of index-browser, since this file may be replaced at bundle time with index-browser.
|
||||
((({}: any) : $Exact<indexBrowserType>): $Exact<indexType>);
|
||||
|
||||
export * from "./configuration";
|
||||
export * from "./plugins";
|
||||
111
packages/babel-core/src/config/loading/files/plugins.js
Normal file
111
packages/babel-core/src/config/loading/files/plugins.js
Normal file
@@ -0,0 +1,111 @@
|
||||
// @flow
|
||||
|
||||
/**
|
||||
* This file handles all logic for converting string-based configuration references into loaded objects.
|
||||
*/
|
||||
|
||||
import resolve from "resolve";
|
||||
|
||||
export function resolvePlugin(pluginName: string, dirname: string): string|null {
|
||||
const possibleNames = [`babel-plugin-${pluginName}`, pluginName];
|
||||
|
||||
return resolveFromPossibleNames(possibleNames, dirname);
|
||||
}
|
||||
|
||||
export function resolvePreset(presetName: string, dirname: string): string|null {
|
||||
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 resolveFromPossibleNames(possibleNames, dirname);
|
||||
}
|
||||
|
||||
export function loadPlugin(name: string, dirname: string): { filepath: string, plugin: mixed } {
|
||||
const filepath = resolvePlugin(name, dirname);
|
||||
if (!filepath) throw new Error(`Plugin ${name} not found relative to ${dirname}`);
|
||||
|
||||
return {
|
||||
filepath,
|
||||
plugin: requireModule(filepath),
|
||||
};
|
||||
}
|
||||
|
||||
export function loadPreset(name: string, dirname: string): { filepath: string, preset: mixed } {
|
||||
const filepath = resolvePreset(name, dirname);
|
||||
if (!filepath) throw new Error(`Preset ${name} not found relative to ${dirname}`);
|
||||
|
||||
return {
|
||||
filepath,
|
||||
preset: requireModule(filepath),
|
||||
};
|
||||
}
|
||||
|
||||
export function loadParser(name: string, dirname: string): { filepath: string, parser: Function } {
|
||||
const filepath = resolveQuiet(name, dirname);
|
||||
if (!filepath) throw new Error(`Parser ${name} not found relative to ${dirname}`);
|
||||
|
||||
const mod = requireModule(filepath);
|
||||
|
||||
if (!mod) {
|
||||
throw new Error(`Parser ${name} relative to ${dirname} does not export an object`);
|
||||
}
|
||||
if (typeof mod.parse !== "function") {
|
||||
throw new Error(`Parser ${name} relative to ${dirname} does not export a .parse function`);
|
||||
}
|
||||
|
||||
return {
|
||||
filepath,
|
||||
parser: mod.parse,
|
||||
};
|
||||
}
|
||||
|
||||
export function loadGenerator(name: string, dirname: string): { filepath: string, generator: Function } {
|
||||
const filepath = resolveQuiet(name, dirname);
|
||||
if (!filepath) throw new Error(`Generator ${name} not found relative to ${dirname}`);
|
||||
|
||||
const mod = requireModule(filepath);
|
||||
|
||||
if (!mod) {
|
||||
throw new Error(`Generator ${name} relative to ${dirname} does not export an object`);
|
||||
}
|
||||
if (typeof mod.print !== "function") {
|
||||
throw new Error(`Generator ${name} relative to ${dirname} does not export a .print function`);
|
||||
}
|
||||
|
||||
return {
|
||||
filepath,
|
||||
generator: mod.print,
|
||||
};
|
||||
}
|
||||
|
||||
function resolveQuiet(name: string, dirname: string): string|null {
|
||||
try {
|
||||
return resolve.sync(name, { basedir: dirname });
|
||||
} catch (e) {
|
||||
// The 'resolve' module can currently throw ENOTDIR
|
||||
// https://github.com/substack/node-resolve/issues/121
|
||||
if (e.code !== "MODULE_NOT_FOUND" && e.code !== "ENOTDIR") throw e;
|
||||
|
||||
// Silently fail and move to the next item.
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function resolveFromPossibleNames(possibleNames: Array<string>, dirname: string): string|null {
|
||||
for (const name of possibleNames) {
|
||||
const result = resolveQuiet(name, dirname);
|
||||
if (result !== null) return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function requireModule(name: string): mixed {
|
||||
// $FlowIssue
|
||||
return require(name);
|
||||
}
|
||||
@@ -1,9 +1,6 @@
|
||||
import * as context from "../index";
|
||||
import Plugin from "./plugin";
|
||||
import * as messages from "babel-messages";
|
||||
import resolve from "./helpers/resolve";
|
||||
import resolvePlugin from "./helpers/resolve-plugin";
|
||||
import resolvePreset from "./helpers/resolve-preset";
|
||||
import defaults from "lodash/defaults";
|
||||
import cloneDeepWith from "lodash/cloneDeepWith";
|
||||
import merge from "./helpers/merge";
|
||||
@@ -11,6 +8,8 @@ import removed from "./removed";
|
||||
import buildConfigChain from "./build-config-chain";
|
||||
import path from "path";
|
||||
|
||||
import { loadPlugin, loadPreset, loadParser, loadGenerator } from "./loading/files";
|
||||
|
||||
type PluginObject = {
|
||||
pre?: Function;
|
||||
post?: Function;
|
||||
@@ -77,11 +76,9 @@ const optionNames = new Set([
|
||||
|
||||
export default class OptionManager {
|
||||
constructor() {
|
||||
this.resolvedConfigs = [];
|
||||
this.options = OptionManager.createBareOptions();
|
||||
}
|
||||
|
||||
resolvedConfigs: Array<string>;
|
||||
options: Object;
|
||||
|
||||
static memoisedPlugins: Array<{
|
||||
@@ -164,12 +161,7 @@ export default class OptionManager {
|
||||
|
||||
// allow plugins to be specified as strings
|
||||
if (typeof plugin === "string") {
|
||||
const pluginLoc = resolvePlugin(plugin, dirname);
|
||||
if (pluginLoc) {
|
||||
plugin = require(pluginLoc);
|
||||
} else {
|
||||
throw new ReferenceError(messages.get("pluginUnknown", plugin, loc, i, dirname));
|
||||
}
|
||||
plugin = loadPlugin(plugin, dirname).plugin;
|
||||
}
|
||||
|
||||
plugin = OptionManager.normalisePlugin(plugin, loc, i, alias);
|
||||
@@ -256,23 +248,11 @@ export default class OptionManager {
|
||||
}
|
||||
|
||||
if (opts.parserOpts && typeof opts.parserOpts.parser === "string") {
|
||||
const parser = resolve(opts.parserOpts.parser, dirname);
|
||||
if (parser) {
|
||||
opts.parserOpts.parser = require(parser).parse;
|
||||
} else {
|
||||
throw new Error(`Couldn't find parser ${opts.parserOpts.parser} with "parse" method ` +
|
||||
`relative to directory ${dirname}`);
|
||||
}
|
||||
opts.parserOpts.parser = loadParser(opts.parserOpts.parser, dirname).parser;
|
||||
}
|
||||
|
||||
if (opts.generatorOpts && typeof opts.generatorOpts.generator === "string") {
|
||||
const generator = resolve(opts.generatorOpts.generator, dirname);
|
||||
if (generator) {
|
||||
opts.generatorOpts.generator = require(generator).print;
|
||||
} else {
|
||||
throw new Error(`Couldn't find generator ${opts.generatorOpts.generator} with "print" method ` +
|
||||
`relative to directory ${dirname}`);
|
||||
}
|
||||
opts.generatorOpts.generator = loadGenerator(opts.generatorOpts.generator, dirname).generator;
|
||||
}
|
||||
|
||||
// resolve plugins
|
||||
@@ -332,14 +312,12 @@ export default class OptionManager {
|
||||
let presetLoc;
|
||||
try {
|
||||
if (typeof preset === "string") {
|
||||
presetLoc = resolvePreset(preset, dirname);
|
||||
|
||||
if (!presetLoc) {
|
||||
throw new Error(`Couldn't find preset ${JSON.stringify(preset)} relative to directory ` +
|
||||
JSON.stringify(dirname));
|
||||
}
|
||||
({
|
||||
filepath: presetLoc,
|
||||
preset,
|
||||
} = loadPreset(preset, dirname));
|
||||
}
|
||||
const resolvedPreset = this.loadPreset(presetLoc || preset, options, { dirname });
|
||||
const resolvedPreset = this.loadPreset(preset, options, { dirname });
|
||||
|
||||
if (onResolve) onResolve(resolvedPreset, presetLoc);
|
||||
|
||||
@@ -359,9 +337,6 @@ export default class OptionManager {
|
||||
*/
|
||||
loadPreset(preset, options, meta) {
|
||||
let presetFactory = preset;
|
||||
if (typeof presetFactory === "string") {
|
||||
presetFactory = require(presetFactory);
|
||||
}
|
||||
|
||||
if (typeof presetFactory === "object" && presetFactory.__esModule) {
|
||||
if (presetFactory.default) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
export File from "./transformation/file";
|
||||
export buildExternalHelpers from "./tools/build-external-helpers";
|
||||
export resolvePlugin from "./config/helpers/resolve-plugin";
|
||||
export resolvePreset from "./config/helpers/resolve-preset";
|
||||
export { resolvePlugin, resolvePreset } from "./config/loading/files";
|
||||
|
||||
export { version } from "../package";
|
||||
export { getEnv } from "./config/helpers/environment";
|
||||
|
||||
@@ -27,10 +27,7 @@ export function debug(opts: Object, msg: string) {
|
||||
|
||||
const shebangRegex = /^#!.*/;
|
||||
|
||||
const INTERNAL_PLUGINS = loadConfig({
|
||||
babelrc: false,
|
||||
plugins: [ blockHoistPlugin, shadowFunctionsPlugin ],
|
||||
}).passes[0];
|
||||
let INTERNAL_PLUGINS;
|
||||
|
||||
const errorVisitor = {
|
||||
enter(path, state) {
|
||||
@@ -44,6 +41,15 @@ const errorVisitor = {
|
||||
|
||||
export default class File extends Store {
|
||||
constructor({ options, passes }: ResolvedConfig) {
|
||||
if (!INTERNAL_PLUGINS) {
|
||||
// Lazy-init the internal plugins to remove the init-time circular dependency between plugins being
|
||||
// passed babel-core's export object, which loads this file, and this 'loadConfig' loading plugins.
|
||||
INTERNAL_PLUGINS = loadConfig({
|
||||
babelrc: false,
|
||||
plugins: [ blockHoistPlugin, shadowFunctionsPlugin ],
|
||||
}).passes[0];
|
||||
}
|
||||
|
||||
super();
|
||||
|
||||
this.pluginPasses = passes;
|
||||
|
||||
@@ -633,7 +633,7 @@ describe("buildConfigChain", function () {
|
||||
filename: fixture("json-config-error", "src.js"),
|
||||
});
|
||||
},
|
||||
/Error while parsing JSON/
|
||||
/Error while parsing config/
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
import assert from "assert";
|
||||
import getPossiblePluginNames from "../lib/config/helpers/get-possible-plugin-names";
|
||||
|
||||
describe("getPossiblePluginNames", function () {
|
||||
it("adds the babel-plugin prefix", function() {
|
||||
assert.deepEqual(getPossiblePluginNames("foobar"), ["babel-plugin-foobar", "foobar"]);
|
||||
});
|
||||
});
|
||||
@@ -1,22 +0,0 @@
|
||||
import assert from "assert";
|
||||
import getPossiblePresetNames from "../lib/config/helpers/get-possible-preset-names";
|
||||
|
||||
describe("getPossiblePresetNames", function () {
|
||||
it("adds the babel-preset prefix", function() {
|
||||
assert.deepEqual(getPossiblePresetNames("foobar"), ["babel-preset-foobar", "foobar"]);
|
||||
});
|
||||
|
||||
it("inserts babel-preset after @org/", function() {
|
||||
assert.deepEqual(getPossiblePresetNames("@babel/es2015"), [
|
||||
"babel-preset-@babel/es2015",
|
||||
"@babel/es2015",
|
||||
"@babel/babel-preset-es2015",
|
||||
]);
|
||||
|
||||
assert.deepEqual(getPossiblePresetNames("@babel/react/optimizations"), [
|
||||
"babel-preset-@babel/react/optimizations",
|
||||
"@babel/react/optimizations",
|
||||
"@babel/babel-preset-react/optimizations",
|
||||
]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user