diff --git a/packages/babel-core/src/config/config-chain.js b/packages/babel-core/src/config/config-chain.js index 60e062d3f8..81adcdff79 100644 --- a/packages/babel-core/src/config/config-chain.js +++ b/packages/babel-core/src/config/config-chain.js @@ -12,12 +12,7 @@ import { const debug = buildDebug("babel:config:config-chain"); -import { - findBabelrc, - findBabelignore, - loadConfig, - type ConfigFile, -} from "./files"; +import { findRelativeConfig, loadConfig, type ConfigFile } from "./files"; import { makeWeakCache, makeStrongCache } from "./caching"; @@ -108,7 +103,6 @@ const loadPresetOverridesEnvDescriptors = makeWeakCache( * Build a config chain for Babel's full root configuration. */ export function buildRootChain( - cwd: string, opts: ValidatedOptions, context: ConfigContext, ): ConfigChain | null { @@ -125,22 +119,15 @@ export function buildRootChain( // resolve all .babelrc files if (opts.babelrc !== false && context.filename !== null) { const filename = context.filename; - const babelignoreFile = findBabelignore(filename); - if ( - babelignoreFile && - shouldIgnore( - context, - babelignoreFile.ignore, - null, - babelignoreFile.dirname, - ) - ) { + + const { ignore, config } = findRelativeConfig(filename, context.envName); + + if (ignore && shouldIgnore(context, ignore.ignore, null, ignore.dirname)) { return null; } - const babelrcFile = findBabelrc(filename, context.envName); - if (babelrcFile) { - const result = loadFileChain(babelrcFile, context); + if (config) { + const result = loadFileChain(config, context); if (!result) return null; mergeChain(fileChain, result); diff --git a/packages/babel-core/src/config/files/configuration.js b/packages/babel-core/src/config/files/configuration.js index 5617f3e473..73786b89fb 100644 --- a/packages/babel-core/src/config/files/configuration.js +++ b/packages/babel-core/src/config/files/configuration.js @@ -21,41 +21,58 @@ export type IgnoreFile = { ignore: Array, }; +export type RelativeConfig = { + config: ConfigFile | null, + ignore: IgnoreFile | null, +}; + const BABELRC_FILENAME = ".babelrc"; const BABELRC_JS_FILENAME = ".babelrc.js"; const PACKAGE_FILENAME = "package.json"; const BABELIGNORE_FILENAME = ".babelignore"; -export function findBabelrc( +export function findRelativeConfig( filepath: string, envName: string, -): ConfigFile | null { +): RelativeConfig { + let config = null; + let ignore = null; + const dirname = path.dirname(filepath); let loc = dirname; while (true) { - const conf = [ - BABELRC_FILENAME, - BABELRC_JS_FILENAME, - PACKAGE_FILENAME, - ].reduce((previousConfig: ConfigFile | null, name) => { - const filepath = path.join(loc, name); - const config = readConfig(filepath, envName); + if (!config) { + config = [BABELRC_FILENAME, BABELRC_JS_FILENAME, PACKAGE_FILENAME].reduce( + (previousConfig: ConfigFile | null, name) => { + const filepath = path.join(loc, name); + const config = readConfig(filepath, envName); - if (config && previousConfig) { - throw new Error( - `Multiple configuration files found. Please remove one:\n` + - ` - ${path.basename(previousConfig.filepath)}\n` + - ` - ${name}\n` + - `from ${loc}`, - ); + if (config && previousConfig) { + throw new Error( + `Multiple configuration files found. Please remove one:\n` + + ` - ${path.basename(previousConfig.filepath)}\n` + + ` - ${name}\n` + + `from ${loc}`, + ); + } + + return config || previousConfig; + }, + null, + ); + + if (config) { + debug("Found configuration %o from %o.", config.filepath, dirname); } + } - return config || previousConfig; - }, null); + if (!ignore) { + const ignoreLoc = path.join(loc, BABELIGNORE_FILENAME); + ignore = readIgnoreConfig(ignoreLoc); - if (conf) { - debug("Found configuration %o from %o.", conf.filepath, dirname); - return conf; + if (ignore) { + debug("Found ignore %o from %o.", ignore.filepath, dirname); + } } const nextLoc = path.dirname(loc); @@ -63,27 +80,7 @@ export function findBabelrc( loc = nextLoc; } - return null; -} - -export function findBabelignore(filepath: string): IgnoreFile | null { - const dirname = path.dirname(filepath); - let loc = dirname; - while (true) { - const ignoreLoc = path.join(loc, BABELIGNORE_FILENAME); - const ignore = readIgnoreConfig(ignoreLoc); - - if (ignore) { - debug("Found ignore %o from %o.", ignore.filepath, dirname); - return ignore; - } - - const nextLoc = path.dirname(loc); - if (loc === nextLoc) break; - loc = nextLoc; - } - - return null; + return { config, ignore }; } export function loadConfig( @@ -106,7 +103,7 @@ export function loadConfig( * 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, envName) { +function readConfig(filepath, envName): ConfigFile | null { return path.extname(filepath) === ".js" ? readConfigJS(filepath, { envName }) : readConfigFile(filepath); diff --git a/packages/babel-core/src/config/files/index-browser.js b/packages/babel-core/src/config/files/index-browser.js index bcd6b439a0..4e5cb5fe62 100644 --- a/packages/babel-core/src/config/files/index-browser.js +++ b/packages/babel-core/src/config/files/index-browser.js @@ -1,27 +1,14 @@ // @flow -export type ConfigFile = { - filepath: string, - dirname: string, - options: {}, -}; +import type { ConfigFile, IgnoreFile, RelativeConfig } from "./configuration"; -export type IgnoreFile = { - filepath: string, - dirname: string, - ignore: Array, -}; +export type { ConfigFile, IgnoreFile, RelativeConfig }; -export function findBabelrc( +export function findRelativeConfig( filepath: string, envName: string, // eslint-disable-line no-unused-vars -): ConfigFile | null { - return null; -} - -// eslint-disable-next-line no-unused-vars -export function findBabelignore(filepath: string): IgnoreFile | null { - return null; +): RelativeConfig { + return { config: null, ignore: null }; } export function loadConfig(name: string, dirname: string): ConfigFile { diff --git a/packages/babel-core/src/config/index.js b/packages/babel-core/src/config/index.js index 6a770e5aca..ef5d5c4a66 100644 --- a/packages/babel-core/src/config/index.js +++ b/packages/babel-core/src/config/index.js @@ -62,7 +62,7 @@ export default function loadConfig(inputOpts: mixed): ResolvedConfig | null { envName, }; - const configChain = buildRootChain(absoluteCwd, args, context); + const configChain = buildRootChain(args, context); if (!configChain) return null; const optionDefaults = {}; diff --git a/packages/babel-core/src/config/validation/option-assertions.js b/packages/babel-core/src/config/validation/option-assertions.js index c6330e7176..97b860f016 100644 --- a/packages/babel-core/src/config/validation/option-assertions.js +++ b/packages/babel-core/src/config/validation/option-assertions.js @@ -140,6 +140,8 @@ export function assertConfigApplicableTest( key: string, value: mixed, ): ConfigApplicableTest | void { + if (value === undefined) return value; + if (Array.isArray(value)) { value.forEach((item, i) => { if (!checkValidTest(item)) { diff --git a/packages/babel-core/src/parse.js b/packages/babel-core/src/parse.js index 1a7e2231a3..94e7284520 100644 --- a/packages/babel-core/src/parse.js +++ b/packages/babel-core/src/parse.js @@ -1,6 +1,6 @@ // @flow -import loadConfig, { InputOptions } from "./config"; +import loadConfig, { type InputOptions } from "./config"; import normalizeFile from "./transformation/normalize-file"; import normalizeOptions from "./transformation/normalize-opts"; diff --git a/packages/babel-node/test/index.js b/packages/babel-node/test/index.js index 6e48f0f2ab..4643475255 100644 --- a/packages/babel-node/test/index.js +++ b/packages/babel-node/test/index.js @@ -177,6 +177,16 @@ fs.readdirSync(fixtureLoc).forEach(function(binName) { const suiteLoc = path.join(fixtureLoc, binName); describe("bin/" + binName, function() { + let cwd; + + beforeEach(() => { + cwd = process.cwd(); + }); + + afterEach(() => { + process.chdir(cwd); + }); + fs.readdirSync(suiteLoc).forEach(function(testName) { if (testName[0] === ".") return; diff --git a/packages/babel-preset-env/test/debug-fixtures.js b/packages/babel-preset-env/test/debug-fixtures.js index 288407f8b3..4b4fcb2569 100644 --- a/packages/babel-preset-env/test/debug-fixtures.js +++ b/packages/babel-preset-env/test/debug-fixtures.js @@ -76,6 +76,16 @@ const buildTest = opts => { }; describe("debug output", () => { + let cwd; + + beforeEach(() => { + cwd = process.cwd(); + }); + + afterEach(() => { + process.chdir(cwd); + }); + fs.readdirSync(fixtureLoc).forEach(testName => { if (testName.slice(0, 1) === ".") return; const testLoc = path.join(fixtureLoc, testName); diff --git a/packages/babel-preset-env/test/fixtures/preset-options/browserslist-config/options.json b/packages/babel-preset-env/test/fixtures/preset-options/browserslist-config/options.json index f048ce5e36..1545c51ee9 100644 --- a/packages/babel-preset-env/test/fixtures/preset-options/browserslist-config/options.json +++ b/packages/babel-preset-env/test/fixtures/preset-options/browserslist-config/options.json @@ -1,7 +1,7 @@ { "presets": [ ["../../../../lib", { - "configPath": "../fixtures/preset-options/browserslist-config", + "configPath": "packages/babel-preset-env/test/fixtures/preset-options/browserslist-config", "modules": false }] ] diff --git a/packages/babel-preset-env/test/fixtures/preset-options/browserslist-package/options.json b/packages/babel-preset-env/test/fixtures/preset-options/browserslist-package/options.json index 04183bdbd1..c10fd049d7 100644 --- a/packages/babel-preset-env/test/fixtures/preset-options/browserslist-package/options.json +++ b/packages/babel-preset-env/test/fixtures/preset-options/browserslist-package/options.json @@ -1,7 +1,7 @@ { "presets": [ ["../../../../lib", { - "configPath": "../fixtures/preset-options/browserslist-package", + "configPath": "packages/babel-preset-env/test/fixtures/preset-options/browserslist-package", "targets": { "chrome": 55 },