Centralize envName lookup using caching sidechannel.
This commit is contained in:
parent
74ea70718e
commit
74439889d8
@ -1,6 +1,5 @@
|
||||
// @flow
|
||||
|
||||
import { getEnv } from "./helpers/environment";
|
||||
import path from "path";
|
||||
import micromatch from "micromatch";
|
||||
import buildDebug from "debug";
|
||||
@ -41,20 +40,20 @@ type ConfigPart =
|
||||
|
||||
export default function buildConfigChain(
|
||||
opts: ValidatedOptions,
|
||||
envName: string,
|
||||
): Array<ConfigItem> | null {
|
||||
const filename = opts.filename ? path.resolve(opts.filename) : null;
|
||||
const builder = new ConfigChainBuilder(
|
||||
filename ? new LoadedFile(filename) : null,
|
||||
);
|
||||
|
||||
const envKey = getEnv();
|
||||
try {
|
||||
builder.mergeConfigArguments(opts, process.cwd(), envKey);
|
||||
builder.mergeConfigArguments(opts, process.cwd(), envName);
|
||||
|
||||
// resolve all .babelrc files
|
||||
if (opts.babelrc !== false && filename) {
|
||||
findConfigs(path.dirname(filename)).forEach(configFile =>
|
||||
builder.mergeConfigFile(configFile, envKey),
|
||||
findConfigs(path.dirname(filename), envName).forEach(configFile =>
|
||||
builder.mergeConfigFile(configFile, envName),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
@ -85,21 +84,21 @@ class ConfigChainBuilder {
|
||||
);
|
||||
}
|
||||
|
||||
mergeConfigFile(file: ConfigFile, envKey: string) {
|
||||
mergeConfigFile(file: ConfigFile, envName: string) {
|
||||
if (this.seenFiles.has(file)) {
|
||||
throw new Error(
|
||||
`Cycle detected in Babel configuration file through "${file.filepath}".`,
|
||||
);
|
||||
}
|
||||
|
||||
const parts = flattenFileOptionsParts(file)(envKey);
|
||||
const parts = flattenFileOptionsParts(file)(envName);
|
||||
|
||||
this.seenFiles.add(file);
|
||||
parts.forEach(part => this._processConfigPart(part, envKey));
|
||||
parts.forEach(part => this._processConfigPart(part, envName));
|
||||
this.seenFiles.delete(file);
|
||||
}
|
||||
|
||||
_processConfigPart(part: ConfigPart, envKey: string) {
|
||||
_processConfigPart(part: ConfigPart, envName: string) {
|
||||
if (part.part === "config") {
|
||||
const { ignore, only } = part;
|
||||
|
||||
@ -116,7 +115,10 @@ class ConfigChainBuilder {
|
||||
|
||||
this.configs.push(part.config);
|
||||
} else {
|
||||
this.mergeConfigFile(loadConfig(part.path, part.dirname), envKey);
|
||||
this.mergeConfigFile(
|
||||
loadConfig(part.path, part.dirname, envName),
|
||||
envName,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -129,7 +131,7 @@ class ConfigChainBuilder {
|
||||
function flattenArgumentsOptionsParts(
|
||||
opts: ValidatedOptions,
|
||||
dirname: string,
|
||||
envKey: string,
|
||||
envName: string,
|
||||
): Array<ConfigPart> {
|
||||
const {
|
||||
env,
|
||||
@ -142,7 +144,7 @@ function flattenArgumentsOptionsParts(
|
||||
|
||||
const raw = [];
|
||||
if (env) {
|
||||
raw.push(...flattenArgumentsEnvOptionsParts(env)(dirname)(envKey));
|
||||
raw.push(...flattenArgumentsEnvOptionsParts(env)(dirname)(envName));
|
||||
}
|
||||
|
||||
if (Object.keys(options).length > 0) {
|
||||
@ -263,7 +265,7 @@ function flattenOptionsPartsLookup(
|
||||
});
|
||||
}
|
||||
|
||||
return envKey => lookup.get(envKey) || def;
|
||||
return envName => lookup.get(envName) || def;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -5,8 +5,7 @@ import path from "path";
|
||||
import fs from "fs";
|
||||
import json5 from "json5";
|
||||
import resolve from "resolve";
|
||||
import { getEnv } from "../../helpers/environment";
|
||||
import { makeStrongCache } from "../../caching";
|
||||
import { makeStrongCache, type CacheConfigurator } from "../../caching";
|
||||
|
||||
const debug = buildDebug("babel:config:loading:files:configuration");
|
||||
|
||||
@ -21,7 +20,10 @@ const BABELRC_JS_FILENAME = ".babelrc.js";
|
||||
const PACKAGE_FILENAME = "package.json";
|
||||
const BABELIGNORE_FILENAME = ".babelignore";
|
||||
|
||||
export function findConfigs(dirname: string): Array<ConfigFile> {
|
||||
export function findConfigs(
|
||||
dirname: string,
|
||||
envName: string,
|
||||
): Array<ConfigFile> {
|
||||
let foundConfig = false;
|
||||
let foundIgnore = false;
|
||||
|
||||
@ -47,7 +49,7 @@ export function findConfigs(dirname: string): Array<ConfigFile> {
|
||||
PACKAGE_FILENAME,
|
||||
].reduce((previousConfig: ConfigFile | null, name) => {
|
||||
const filepath = path.join(loc, name);
|
||||
const config = readConfig(filepath);
|
||||
const config = readConfig(filepath, envName);
|
||||
|
||||
if (config && previousConfig) {
|
||||
throw new Error(
|
||||
@ -77,10 +79,14 @@ export function findConfigs(dirname: string): Array<ConfigFile> {
|
||||
return confs;
|
||||
}
|
||||
|
||||
export function loadConfig(name: string, dirname: string): ConfigFile {
|
||||
export function loadConfig(
|
||||
name: string,
|
||||
dirname: string,
|
||||
envName: string,
|
||||
): ConfigFile {
|
||||
const filepath = resolve.sync(name, { basedir: dirname });
|
||||
|
||||
const conf = readConfig(filepath);
|
||||
const conf = readConfig(filepath, envName);
|
||||
if (!conf) {
|
||||
throw new Error(`Config file ${filepath} contains no configuration data`);
|
||||
}
|
||||
@ -93,83 +99,86 @@ export function loadConfig(name: string, dirname: string): ConfigFile {
|
||||
* 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) {
|
||||
function readConfig(filepath, envName) {
|
||||
return path.extname(filepath) === ".js"
|
||||
? readConfigJS(filepath)
|
||||
? readConfigJS(filepath, { envName })
|
||||
: readConfigFile(filepath);
|
||||
}
|
||||
|
||||
const LOADING_CONFIGS = new Set();
|
||||
const readConfigJS = makeStrongCache((filepath, cache) => {
|
||||
if (!fs.existsSync(filepath)) {
|
||||
cache.forever();
|
||||
return null;
|
||||
}
|
||||
|
||||
// The `require()` call below can make this code reentrant if a require hook like @babel/register has been
|
||||
// loaded into the system. That would cause Babel to attempt to compile the `.babelrc.js` file as it loads
|
||||
// below. To cover this case, we auto-ignore re-entrant config processing.
|
||||
if (LOADING_CONFIGS.has(filepath)) {
|
||||
cache.never();
|
||||
const readConfigJS = makeStrongCache(
|
||||
(filepath, cache: CacheConfigurator<{ envName: string }>) => {
|
||||
if (!fs.existsSync(filepath)) {
|
||||
cache.forever();
|
||||
return null;
|
||||
}
|
||||
|
||||
// The `require()` call below can make this code reentrant if a require hook like @babel/register has been
|
||||
// loaded into the system. That would cause Babel to attempt to compile the `.babelrc.js` file as it loads
|
||||
// below. To cover this case, we auto-ignore re-entrant config processing.
|
||||
if (LOADING_CONFIGS.has(filepath)) {
|
||||
cache.never();
|
||||
|
||||
debug("Auto-ignoring usage of config %o.", filepath);
|
||||
return {
|
||||
filepath,
|
||||
dirname: path.dirname(filepath),
|
||||
options: {},
|
||||
};
|
||||
}
|
||||
|
||||
let options;
|
||||
try {
|
||||
LOADING_CONFIGS.add(filepath);
|
||||
|
||||
// $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;
|
||||
} finally {
|
||||
LOADING_CONFIGS.delete(filepath);
|
||||
}
|
||||
|
||||
if (typeof options === "function") {
|
||||
options = options({
|
||||
cache: cache.simple(),
|
||||
// Expose ".env()" so people can easily get the same env that we expose using the "env" key.
|
||||
env: () => cache.using(data => data.envName),
|
||||
async: () => false,
|
||||
});
|
||||
|
||||
if (!cache.configured()) throwConfigError();
|
||||
}
|
||||
|
||||
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
||||
throw new Error(
|
||||
`${filepath}: Configuration should be an exported JavaScript object.`,
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof options.then === "function") {
|
||||
throw new Error(
|
||||
`You appear to be using an async configuration, ` +
|
||||
`which your current version of Babel does not support. ` +
|
||||
`We may add support for this in the future, ` +
|
||||
`but if you're on the most recent version of @babel/core and still ` +
|
||||
`seeing this error, then you'll need to synchronously return your config.`,
|
||||
);
|
||||
}
|
||||
|
||||
debug("Auto-ignoring usage of config %o.", filepath);
|
||||
return {
|
||||
filepath,
|
||||
dirname: path.dirname(filepath),
|
||||
options: {},
|
||||
options,
|
||||
};
|
||||
}
|
||||
|
||||
let options;
|
||||
try {
|
||||
LOADING_CONFIGS.add(filepath);
|
||||
|
||||
// $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;
|
||||
} finally {
|
||||
LOADING_CONFIGS.delete(filepath);
|
||||
}
|
||||
|
||||
if (typeof options === "function") {
|
||||
options = options({
|
||||
cache: cache.simple(),
|
||||
// Expose ".env()" so people can easily get the same env that we expose using the "env" key.
|
||||
env: () => cache.using(() => getEnv()),
|
||||
async: () => false,
|
||||
});
|
||||
|
||||
if (!cache.configured()) throwConfigError();
|
||||
}
|
||||
|
||||
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
||||
throw new Error(
|
||||
`${filepath}: Configuration should be an exported JavaScript object.`,
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof options.then === "function") {
|
||||
throw new Error(
|
||||
`You appear to be using an async configuration, ` +
|
||||
`which your current version of Babel does not support. ` +
|
||||
`We may add support for this in the future, ` +
|
||||
`but if you're on the most recent version of @babel/core and still ` +
|
||||
`seeing this error, then you'll need to synchronously return your config.`,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
filepath,
|
||||
dirname: path.dirname(filepath),
|
||||
options,
|
||||
};
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
const readConfigFile = makeStaticFileCache((filepath, content) => {
|
||||
let options;
|
||||
|
||||
@ -6,7 +6,7 @@ import merge from "lodash/merge";
|
||||
import buildConfigChain, { type ConfigItem } from "./build-config-chain";
|
||||
import traverse from "@babel/traverse";
|
||||
import clone from "lodash/clone";
|
||||
import { makeWeakCache } from "./caching";
|
||||
import { makeWeakCache, type CacheConfigurator } from "./caching";
|
||||
import { getEnv } from "./helpers/environment";
|
||||
import { validate, type ValidatedOptions, type PluginItem } from "./options";
|
||||
|
||||
@ -46,14 +46,14 @@ class OptionManager {
|
||||
* - `dirname` is used to resolve plugins relative to it.
|
||||
*/
|
||||
|
||||
mergeOptions(config: MergeOptions, pass?: Array<Plugin>) {
|
||||
mergeOptions(config: MergeOptions, pass?: Array<Plugin>, envName: string) {
|
||||
const result = loadConfig(config);
|
||||
|
||||
const plugins = result.plugins.map(descriptor =>
|
||||
loadPluginDescriptor(descriptor),
|
||||
loadPluginDescriptor(descriptor, envName),
|
||||
);
|
||||
const presets = result.presets.map(descriptor =>
|
||||
loadPresetDescriptor(descriptor),
|
||||
loadPresetDescriptor(descriptor, envName),
|
||||
);
|
||||
|
||||
const passPerPreset = config.options.passPerPreset;
|
||||
@ -70,7 +70,11 @@ class OptionManager {
|
||||
}
|
||||
|
||||
presets.forEach((presetConfig, i) => {
|
||||
this.mergeOptions(presetConfig, presetPasses ? presetPasses[i] : pass);
|
||||
this.mergeOptions(
|
||||
presetConfig,
|
||||
presetPasses ? presetPasses[i] : pass,
|
||||
envName,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@ -99,12 +103,14 @@ class OptionManager {
|
||||
init(inputOpts: {}) {
|
||||
const args = validate("arguments", inputOpts);
|
||||
|
||||
const configChain = buildConfigChain(args);
|
||||
const envName = getEnv();
|
||||
|
||||
const configChain = buildConfigChain(args, envName);
|
||||
if (!configChain) return null;
|
||||
|
||||
try {
|
||||
for (const config of configChain) {
|
||||
this.mergeOptions(config);
|
||||
this.mergeOptions(config, undefined, envName);
|
||||
}
|
||||
} catch (e) {
|
||||
// There are a few case where thrown errors will try to annotate themselves multiple times, so
|
||||
@ -182,13 +188,13 @@ const loadConfig = makeWeakCache((config: MergeOptions): {
|
||||
const loadDescriptor = makeWeakCache(
|
||||
(
|
||||
{ value, options = {}, dirname, alias }: BasicDescriptor,
|
||||
cache,
|
||||
cache: CacheConfigurator<{ envName: string }>,
|
||||
): LoadedDescriptor => {
|
||||
let item = value;
|
||||
if (typeof value === "function") {
|
||||
const api = Object.assign(Object.create(context), {
|
||||
cache: cache.simple(),
|
||||
env: () => cache.using(() => getEnv()),
|
||||
env: () => cache.using(data => data.envName),
|
||||
async: () => false,
|
||||
});
|
||||
|
||||
@ -222,7 +228,10 @@ const loadDescriptor = makeWeakCache(
|
||||
/**
|
||||
* Instantiate a plugin for the given descriptor, returning the plugin/options pair.
|
||||
*/
|
||||
function loadPluginDescriptor(descriptor: BasicDescriptor): Plugin {
|
||||
function loadPluginDescriptor(
|
||||
descriptor: BasicDescriptor,
|
||||
envName: string,
|
||||
): Plugin {
|
||||
if (descriptor.value instanceof Plugin) {
|
||||
if (descriptor.options) {
|
||||
throw new Error(
|
||||
@ -233,11 +242,16 @@ function loadPluginDescriptor(descriptor: BasicDescriptor): Plugin {
|
||||
return descriptor.value;
|
||||
}
|
||||
|
||||
return instantiatePlugin(loadDescriptor(descriptor));
|
||||
return instantiatePlugin(loadDescriptor(descriptor, { envName }), {
|
||||
envName,
|
||||
});
|
||||
}
|
||||
|
||||
const instantiatePlugin = makeWeakCache(
|
||||
({ value, options, dirname, alias }: LoadedDescriptor, cache): Plugin => {
|
||||
(
|
||||
{ value, options, dirname, alias }: LoadedDescriptor,
|
||||
cache: CacheConfigurator<{ envName: string }>,
|
||||
): Plugin => {
|
||||
const pluginObj = validatePluginObject(value);
|
||||
|
||||
const plugin = Object.assign({}, pluginObj);
|
||||
@ -254,8 +268,8 @@ const instantiatePlugin = makeWeakCache(
|
||||
};
|
||||
|
||||
// If the inherited plugin changes, reinstantiate this plugin.
|
||||
const inherits = cache.invalidate(() =>
|
||||
loadPluginDescriptor(inheritsDescriptor),
|
||||
const inherits = cache.invalidate(data =>
|
||||
loadPluginDescriptor(inheritsDescriptor, data.envName),
|
||||
);
|
||||
|
||||
plugin.pre = chain(inherits.pre, plugin.pre);
|
||||
@ -277,8 +291,11 @@ const instantiatePlugin = makeWeakCache(
|
||||
/**
|
||||
* Generate a config object that will act as the root of a new nested config.
|
||||
*/
|
||||
const loadPresetDescriptor = (descriptor: BasicDescriptor): MergeOptions => {
|
||||
return instantiatePreset(loadDescriptor(descriptor));
|
||||
const loadPresetDescriptor = (
|
||||
descriptor: BasicDescriptor,
|
||||
envName: string,
|
||||
): MergeOptions => {
|
||||
return instantiatePreset(loadDescriptor(descriptor, { envName }));
|
||||
};
|
||||
|
||||
const instantiatePreset = makeWeakCache(
|
||||
|
||||
@ -3,6 +3,8 @@ import fs from "fs";
|
||||
import path from "path";
|
||||
import buildConfigChain from "../lib/config/build-config-chain";
|
||||
|
||||
const DEFAULT_ENV = "development";
|
||||
|
||||
function fixture() {
|
||||
const args = [__dirname, "fixtures", "config"];
|
||||
for (let i = 0; i < arguments.length; i++) {
|
||||
@ -16,49 +18,39 @@ function base() {
|
||||
}
|
||||
|
||||
describe("buildConfigChain", function() {
|
||||
let oldBabelEnv;
|
||||
let oldNodeEnv;
|
||||
|
||||
beforeEach(function() {
|
||||
oldBabelEnv = process.env.BABEL_ENV;
|
||||
oldNodeEnv = process.env.NODE_ENV;
|
||||
|
||||
delete process.env.BABEL_ENV;
|
||||
delete process.env.NODE_ENV;
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
process.env.BABEL_ENV = oldBabelEnv;
|
||||
process.env.NODE_ENV = oldNodeEnv;
|
||||
});
|
||||
|
||||
describe("ignore", () => {
|
||||
it("should ignore files that match", () => {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
ignore: [
|
||||
fixture("nonexistant-fake", "src.js"),
|
||||
const chain = buildConfigChain(
|
||||
{
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
ignore: [
|
||||
fixture("nonexistant-fake", "src.js"),
|
||||
|
||||
// We had a regression where multiple ignore patterns broke things, so
|
||||
// we keep some extra random items in here.
|
||||
fixture("nonexistant-fake", "other.js"),
|
||||
fixture("nonexistant-fake", "misc.js"),
|
||||
],
|
||||
});
|
||||
// We had a regression where multiple ignore patterns broke things, so
|
||||
// we keep some extra random items in here.
|
||||
fixture("nonexistant-fake", "other.js"),
|
||||
fixture("nonexistant-fake", "misc.js"),
|
||||
],
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
|
||||
assert.equal(chain, null);
|
||||
});
|
||||
|
||||
it("should not ignore files that don't match", () => {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
ignore: [
|
||||
fixture("nonexistant-fake", "other.js"),
|
||||
fixture("nonexistant-fake", "misc.js"),
|
||||
],
|
||||
});
|
||||
const chain = buildConfigChain(
|
||||
{
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
ignore: [
|
||||
fixture("nonexistant-fake", "other.js"),
|
||||
fixture("nonexistant-fake", "misc.js"),
|
||||
],
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
|
||||
const expected = [
|
||||
{
|
||||
@ -82,27 +74,33 @@ describe("buildConfigChain", function() {
|
||||
|
||||
describe("only", () => {
|
||||
it("should ignore files that don't match", () => {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
only: [
|
||||
fixture("nonexistant-fake", "other.js"),
|
||||
fixture("nonexistant-fake", "misc.js"),
|
||||
],
|
||||
});
|
||||
const chain = buildConfigChain(
|
||||
{
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
only: [
|
||||
fixture("nonexistant-fake", "other.js"),
|
||||
fixture("nonexistant-fake", "misc.js"),
|
||||
],
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
|
||||
assert.equal(chain, null);
|
||||
});
|
||||
|
||||
it("should not ignore files that match", () => {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
only: [
|
||||
fixture("nonexistant-fake", "src.js"),
|
||||
fixture("nonexistant-fake", "misc.js"),
|
||||
],
|
||||
});
|
||||
const chain = buildConfigChain(
|
||||
{
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
only: [
|
||||
fixture("nonexistant-fake", "src.js"),
|
||||
fixture("nonexistant-fake", "misc.js"),
|
||||
],
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
|
||||
const expected = [
|
||||
{
|
||||
@ -126,12 +124,15 @@ describe("buildConfigChain", function() {
|
||||
|
||||
describe("ignore/only", () => {
|
||||
it("should ignore files that match ignore and don't match only", () => {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
ignore: [fixture("nonexistant-fake", "src.js")],
|
||||
only: [fixture("nonexistant-fake", "src.js")],
|
||||
});
|
||||
const chain = buildConfigChain(
|
||||
{
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
ignore: [fixture("nonexistant-fake", "src.js")],
|
||||
only: [fixture("nonexistant-fake", "src.js")],
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
|
||||
assert.equal(chain, null);
|
||||
});
|
||||
@ -142,8 +143,8 @@ describe("buildConfigChain", function() {
|
||||
it("should not cache the input options by identity", () => {
|
||||
const comments = false;
|
||||
|
||||
const chain1 = buildConfigChain({ comments });
|
||||
const chain2 = buildConfigChain({ comments });
|
||||
const chain1 = buildConfigChain({ comments }, DEFAULT_ENV);
|
||||
const chain2 = buildConfigChain({ comments }, DEFAULT_ENV);
|
||||
|
||||
assert.equal(chain1.length, 1);
|
||||
assert.equal(chain2.length, 1);
|
||||
@ -151,15 +152,14 @@ describe("buildConfigChain", function() {
|
||||
});
|
||||
|
||||
it("should cache the env options by identity", () => {
|
||||
process.env.NODE_ENV = "foo";
|
||||
const env = {
|
||||
foo: {
|
||||
comments: false,
|
||||
},
|
||||
};
|
||||
|
||||
const chain1 = buildConfigChain({ env });
|
||||
const chain2 = buildConfigChain({ env });
|
||||
const chain1 = buildConfigChain({ env }, "foo");
|
||||
const chain2 = buildConfigChain({ env }, "foo");
|
||||
|
||||
assert.equal(chain1.length, 2);
|
||||
assert.equal(chain2.length, 2);
|
||||
@ -170,8 +170,8 @@ describe("buildConfigChain", function() {
|
||||
it("should cache the plugin options by identity", () => {
|
||||
const plugins = [];
|
||||
|
||||
const chain1 = buildConfigChain({ plugins });
|
||||
const chain2 = buildConfigChain({ plugins });
|
||||
const chain1 = buildConfigChain({ plugins }, DEFAULT_ENV);
|
||||
const chain2 = buildConfigChain({ plugins }, DEFAULT_ENV);
|
||||
|
||||
assert.equal(chain1.length, 1);
|
||||
assert.equal(chain2.length, 1);
|
||||
@ -181,8 +181,8 @@ describe("buildConfigChain", function() {
|
||||
it("should cache the presets options by identity", () => {
|
||||
const presets = [];
|
||||
|
||||
const chain1 = buildConfigChain({ presets });
|
||||
const chain2 = buildConfigChain({ presets });
|
||||
const chain1 = buildConfigChain({ presets }, DEFAULT_ENV);
|
||||
const chain2 = buildConfigChain({ presets }, DEFAULT_ENV);
|
||||
|
||||
assert.equal(chain1.length, 1);
|
||||
assert.equal(chain2.length, 1);
|
||||
@ -192,9 +192,15 @@ describe("buildConfigChain", function() {
|
||||
it("should not cache the presets options with passPerPreset", () => {
|
||||
const presets = [];
|
||||
|
||||
const chain1 = buildConfigChain({ presets });
|
||||
const chain2 = buildConfigChain({ presets, passPerPreset: true });
|
||||
const chain3 = buildConfigChain({ presets, passPerPreset: false });
|
||||
const chain1 = buildConfigChain({ presets }, DEFAULT_ENV);
|
||||
const chain2 = buildConfigChain(
|
||||
{ presets, passPerPreset: true },
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
const chain3 = buildConfigChain(
|
||||
{ presets, passPerPreset: false },
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
|
||||
assert.equal(chain1.length, 1);
|
||||
assert.equal(chain2.length, 1);
|
||||
@ -229,13 +235,13 @@ describe("buildConfigChain", function() {
|
||||
"package.json",
|
||||
);
|
||||
|
||||
const chain1 = buildConfigChain({ filename });
|
||||
const chain2 = buildConfigChain({ filename });
|
||||
const chain1 = buildConfigChain({ filename }, DEFAULT_ENV);
|
||||
const chain2 = buildConfigChain({ filename }, DEFAULT_ENV);
|
||||
|
||||
touch(pkgJSON);
|
||||
|
||||
const chain3 = buildConfigChain({ filename });
|
||||
const chain4 = buildConfigChain({ filename });
|
||||
const chain3 = buildConfigChain({ filename }, DEFAULT_ENV);
|
||||
const chain4 = buildConfigChain({ filename }, DEFAULT_ENV);
|
||||
|
||||
assert.equal(chain1.length, 3);
|
||||
assert.equal(chain2.length, 3);
|
||||
@ -266,13 +272,13 @@ describe("buildConfigChain", function() {
|
||||
".babelrc",
|
||||
);
|
||||
|
||||
const chain1 = buildConfigChain({ filename });
|
||||
const chain2 = buildConfigChain({ filename });
|
||||
const chain1 = buildConfigChain({ filename }, DEFAULT_ENV);
|
||||
const chain2 = buildConfigChain({ filename }, DEFAULT_ENV);
|
||||
|
||||
touch(babelrcFile);
|
||||
|
||||
const chain3 = buildConfigChain({ filename });
|
||||
const chain4 = buildConfigChain({ filename });
|
||||
const chain3 = buildConfigChain({ filename }, DEFAULT_ENV);
|
||||
const chain4 = buildConfigChain({ filename }, DEFAULT_ENV);
|
||||
|
||||
assert.equal(chain1.length, 3);
|
||||
assert.equal(chain2.length, 3);
|
||||
@ -303,13 +309,13 @@ describe("buildConfigChain", function() {
|
||||
".babelignore",
|
||||
);
|
||||
|
||||
const chain1 = buildConfigChain({ filename });
|
||||
const chain2 = buildConfigChain({ filename });
|
||||
const chain1 = buildConfigChain({ filename }, DEFAULT_ENV);
|
||||
const chain2 = buildConfigChain({ filename }, DEFAULT_ENV);
|
||||
|
||||
touch(babelignoreFile);
|
||||
|
||||
const chain3 = buildConfigChain({ filename });
|
||||
const chain4 = buildConfigChain({ filename });
|
||||
const chain3 = buildConfigChain({ filename }, DEFAULT_ENV);
|
||||
const chain4 = buildConfigChain({ filename }, DEFAULT_ENV);
|
||||
|
||||
assert.equal(chain1.length, 6);
|
||||
assert.equal(chain2.length, 6);
|
||||
@ -340,13 +346,11 @@ describe("buildConfigChain", function() {
|
||||
".babelrc.js",
|
||||
);
|
||||
|
||||
const chain1 = buildConfigChain({ filename });
|
||||
const chain2 = buildConfigChain({ filename });
|
||||
const chain1 = buildConfigChain({ filename }, DEFAULT_ENV);
|
||||
const chain2 = buildConfigChain({ filename }, DEFAULT_ENV);
|
||||
|
||||
process.env.NODE_ENV = "new-env";
|
||||
|
||||
const chain3 = buildConfigChain({ filename });
|
||||
const chain4 = buildConfigChain({ filename });
|
||||
const chain3 = buildConfigChain({ filename }, "new-env");
|
||||
const chain4 = buildConfigChain({ filename }, "new-env");
|
||||
|
||||
assert.equal(chain1.length, 3);
|
||||
assert.equal(chain2.length, 3);
|
||||
@ -358,7 +362,7 @@ describe("buildConfigChain", function() {
|
||||
assert.equal(chain4[1].alias, babelrcFile);
|
||||
assert.strictEqual(chain1[1], chain2[1]);
|
||||
|
||||
// Identity changed after changing the NODE_ENV.
|
||||
// Identity changed after changing the envName.
|
||||
assert.notStrictEqual(chain3[1], chain1[1]);
|
||||
assert.strictEqual(chain3[1], chain4[1]);
|
||||
});
|
||||
@ -366,9 +370,12 @@ describe("buildConfigChain", function() {
|
||||
});
|
||||
|
||||
it("dir1", function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("dir1", "src.js"),
|
||||
});
|
||||
const chain = buildConfigChain(
|
||||
{
|
||||
filename: fixture("dir1", "src.js"),
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
|
||||
const expected = [
|
||||
{
|
||||
@ -410,9 +417,12 @@ describe("buildConfigChain", function() {
|
||||
});
|
||||
|
||||
it("dir2", function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("dir2", "src.js"),
|
||||
});
|
||||
const chain = buildConfigChain(
|
||||
{
|
||||
filename: fixture("dir2", "src.js"),
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
|
||||
const expected = [
|
||||
{
|
||||
@ -445,9 +455,12 @@ describe("buildConfigChain", function() {
|
||||
});
|
||||
|
||||
it("dir3", function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("dir3", "src.js"),
|
||||
});
|
||||
const chain = buildConfigChain(
|
||||
{
|
||||
filename: fixture("dir3", "src.js"),
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
|
||||
const expected = [
|
||||
{
|
||||
@ -489,9 +502,12 @@ describe("buildConfigChain", function() {
|
||||
});
|
||||
|
||||
it("env - base", function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("env", "src.js"),
|
||||
});
|
||||
const chain = buildConfigChain(
|
||||
{
|
||||
filename: fixture("env", "src.js"),
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
|
||||
const expected = [
|
||||
{
|
||||
@ -532,11 +548,12 @@ describe("buildConfigChain", function() {
|
||||
});
|
||||
|
||||
it("env - foo", function() {
|
||||
process.env.NODE_ENV = "foo";
|
||||
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("env", "src.js"),
|
||||
});
|
||||
const chain = buildConfigChain(
|
||||
{
|
||||
filename: fixture("env", "src.js"),
|
||||
},
|
||||
"foo",
|
||||
);
|
||||
|
||||
const expected = [
|
||||
{
|
||||
@ -585,12 +602,12 @@ describe("buildConfigChain", function() {
|
||||
});
|
||||
|
||||
it("env - bar", function() {
|
||||
process.env.NODE_ENV = "foo"; // overridden
|
||||
process.env.NODE_ENV = "bar";
|
||||
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("env", "src.js"),
|
||||
});
|
||||
const chain = buildConfigChain(
|
||||
{
|
||||
filename: fixture("env", "src.js"),
|
||||
},
|
||||
"bar",
|
||||
);
|
||||
|
||||
const expected = [
|
||||
{
|
||||
@ -639,11 +656,12 @@ describe("buildConfigChain", function() {
|
||||
});
|
||||
|
||||
it("env - foo", function() {
|
||||
process.env.NODE_ENV = "foo";
|
||||
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("pkg", "src.js"),
|
||||
});
|
||||
const chain = buildConfigChain(
|
||||
{
|
||||
filename: fixture("pkg", "src.js"),
|
||||
},
|
||||
"foo",
|
||||
);
|
||||
|
||||
const expected = [
|
||||
{
|
||||
@ -676,9 +694,12 @@ describe("buildConfigChain", function() {
|
||||
});
|
||||
|
||||
it("js-config", function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("js-config", "src.js"),
|
||||
});
|
||||
const chain = buildConfigChain(
|
||||
{
|
||||
filename: fixture("js-config", "src.js"),
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
|
||||
const expected = [
|
||||
{
|
||||
@ -711,9 +732,12 @@ describe("buildConfigChain", function() {
|
||||
});
|
||||
|
||||
it("js-config-function", function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("js-config-function", "src.js"),
|
||||
});
|
||||
const chain = buildConfigChain(
|
||||
{
|
||||
filename: fixture("js-config-function", "src.js"),
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
|
||||
const expected = [
|
||||
{
|
||||
@ -746,9 +770,12 @@ describe("buildConfigChain", function() {
|
||||
});
|
||||
|
||||
it("js-config-default - should read transpiled export default", function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("js-config-default", "src.js"),
|
||||
});
|
||||
const chain = buildConfigChain(
|
||||
{
|
||||
filename: fixture("js-config-default", "src.js"),
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
|
||||
const expected = [
|
||||
{
|
||||
@ -780,9 +807,12 @@ describe("buildConfigChain", function() {
|
||||
assert.deepEqual(chain, expected);
|
||||
});
|
||||
it("js-config-extended", function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("js-config-extended", "src.js"),
|
||||
});
|
||||
const chain = buildConfigChain(
|
||||
{
|
||||
filename: fixture("js-config-extended", "src.js"),
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
|
||||
const expected = [
|
||||
{
|
||||
@ -827,9 +857,12 @@ describe("buildConfigChain", function() {
|
||||
"json-pkg-config-no-babel - should not throw if" +
|
||||
" package.json doesn't contain a `babel` field",
|
||||
function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("json-pkg-config-no-babel", "src.js"),
|
||||
});
|
||||
const chain = buildConfigChain(
|
||||
{
|
||||
filename: fixture("json-pkg-config-no-babel", "src.js"),
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
|
||||
const expected = [
|
||||
{
|
||||
@ -863,9 +896,12 @@ describe("buildConfigChain", function() {
|
||||
);
|
||||
|
||||
it("should not ignore file matching negated file pattern", function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("ignore-negate", "src.js"),
|
||||
});
|
||||
const chain = buildConfigChain(
|
||||
{
|
||||
filename: fixture("ignore-negate", "src.js"),
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
|
||||
const expected = [
|
||||
{
|
||||
@ -896,17 +932,23 @@ describe("buildConfigChain", function() {
|
||||
|
||||
assert.deepEqual(chain, expected);
|
||||
|
||||
const chain2 = buildConfigChain({
|
||||
filename: fixture("ignore-negate", "src2.js"),
|
||||
});
|
||||
const chain2 = buildConfigChain(
|
||||
{
|
||||
filename: fixture("ignore-negate", "src2.js"),
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
|
||||
assert.equal(chain2, null);
|
||||
});
|
||||
|
||||
it("should not ignore file matching negated folder pattern", function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("ignore-negate-folder", "folder", "src.js"),
|
||||
});
|
||||
const chain = buildConfigChain(
|
||||
{
|
||||
filename: fixture("ignore-negate-folder", "folder", "src.js"),
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
|
||||
const expected = [
|
||||
{
|
||||
@ -937,9 +979,12 @@ describe("buildConfigChain", function() {
|
||||
|
||||
assert.deepEqual(chain, expected);
|
||||
|
||||
const chain2 = buildConfigChain({
|
||||
filename: fixture("ignore-negate-folder", "src2.js"),
|
||||
});
|
||||
const chain2 = buildConfigChain(
|
||||
{
|
||||
filename: fixture("ignore-negate-folder", "src2.js"),
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
|
||||
assert.equal(chain2, null);
|
||||
});
|
||||
@ -949,9 +994,12 @@ describe("buildConfigChain", function() {
|
||||
" and a .babelrc.js are present",
|
||||
function() {
|
||||
assert.throws(function() {
|
||||
buildConfigChain({
|
||||
filename: fixture("js-json-config", "src.js"),
|
||||
});
|
||||
buildConfigChain(
|
||||
{
|
||||
filename: fixture("js-json-config", "src.js"),
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
}, /Multiple configuration files found\.(.|\n)*\.babelrc(.|\n)*\.babelrc\.js/);
|
||||
},
|
||||
);
|
||||
@ -961,9 +1009,12 @@ describe("buildConfigChain", function() {
|
||||
" and a package.json with a babel field are present",
|
||||
function() {
|
||||
assert.throws(function() {
|
||||
buildConfigChain({
|
||||
filename: fixture("js-pkg-config", "src.js"),
|
||||
});
|
||||
buildConfigChain(
|
||||
{
|
||||
filename: fixture("js-pkg-config", "src.js"),
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
}, /Multiple configuration files found\.(.|\n)*\.babelrc\.js(.|\n)*package\.json/);
|
||||
},
|
||||
);
|
||||
@ -973,42 +1024,57 @@ describe("buildConfigChain", function() {
|
||||
" and a package.json with a babel field are present",
|
||||
function() {
|
||||
assert.throws(function() {
|
||||
buildConfigChain({
|
||||
filename: fixture("json-pkg-config", "src.js"),
|
||||
});
|
||||
buildConfigChain(
|
||||
{
|
||||
filename: fixture("json-pkg-config", "src.js"),
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
}, /Multiple configuration files found\.(.|\n)*\.babelrc(.|\n)*package\.json/);
|
||||
},
|
||||
);
|
||||
|
||||
it("js-config-error", function() {
|
||||
assert.throws(function() {
|
||||
buildConfigChain({
|
||||
filename: fixture("js-config-error", "src.js"),
|
||||
});
|
||||
buildConfigChain(
|
||||
{
|
||||
filename: fixture("js-config-error", "src.js"),
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
}, /Error while loading config/);
|
||||
});
|
||||
|
||||
it("js-config-error2", function() {
|
||||
assert.throws(function() {
|
||||
buildConfigChain({
|
||||
filename: fixture("js-config-error2", "src.js"),
|
||||
});
|
||||
buildConfigChain(
|
||||
{
|
||||
filename: fixture("js-config-error2", "src.js"),
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
}, /Configuration should be an exported JavaScript object/);
|
||||
});
|
||||
|
||||
it("js-config-error3", function() {
|
||||
assert.throws(function() {
|
||||
buildConfigChain({
|
||||
filename: fixture("js-config-error3", "src.js"),
|
||||
});
|
||||
buildConfigChain(
|
||||
{
|
||||
filename: fixture("js-config-error3", "src.js"),
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
}, /Configuration should be an exported JavaScript object/);
|
||||
});
|
||||
|
||||
it("json-config-error", function() {
|
||||
assert.throws(function() {
|
||||
buildConfigChain({
|
||||
filename: fixture("json-config-error", "src.js"),
|
||||
});
|
||||
buildConfigChain(
|
||||
{
|
||||
filename: fixture("json-config-error", "src.js"),
|
||||
},
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
}, /Error while parsing config/);
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user