Merge branch 'master' into feat-use-charcode-constants
This commit is contained in:
commit
233e60c765
@ -242,6 +242,7 @@ delete opts.quiet;
|
||||
delete opts.configFile;
|
||||
delete opts.deleteDirOnStart;
|
||||
delete opts.keepFileExtension;
|
||||
delete opts.relative;
|
||||
|
||||
// Commander will default the "--no-" arguments to true, but we want to leave them undefined so that
|
||||
// @babel/core can handle the default-assignment logic on its own.
|
||||
|
||||
@ -4,6 +4,12 @@ import { getEnv } from "./helpers/environment";
|
||||
import path from "path";
|
||||
import micromatch from "micromatch";
|
||||
import buildDebug from "debug";
|
||||
import {
|
||||
validate,
|
||||
type ValidatedOptions,
|
||||
type PluginList,
|
||||
type IgnoreList,
|
||||
} from "./options";
|
||||
|
||||
const debug = buildDebug("babel:config:config-chain");
|
||||
|
||||
@ -11,26 +17,31 @@ import { findConfigs, loadConfig, type ConfigFile } from "./loading/files";
|
||||
|
||||
import { makeWeakCache, makeStrongCache } from "./caching";
|
||||
|
||||
type ConfigItem = {
|
||||
type: "options" | "arguments",
|
||||
options: {},
|
||||
dirname: string,
|
||||
alias: string,
|
||||
loc: string,
|
||||
};
|
||||
|
||||
type ConfigRaw = {
|
||||
type: "options" | "arguments",
|
||||
options: {},
|
||||
export type ConfigItem = {
|
||||
type: "arguments" | "env" | "file",
|
||||
options: ValidatedOptions,
|
||||
alias: string,
|
||||
dirname: string,
|
||||
};
|
||||
|
||||
export default function buildConfigChain(opts: {}): Array<ConfigItem> | null {
|
||||
if (typeof opts.filename !== "string" && opts.filename != null) {
|
||||
throw new Error(".filename must be a string, null, or undefined");
|
||||
}
|
||||
type ConfigPart =
|
||||
| {
|
||||
part: "config",
|
||||
config: ConfigItem,
|
||||
ignore: ?IgnoreList,
|
||||
only: ?IgnoreList,
|
||||
activeEnv: string | null,
|
||||
}
|
||||
| {
|
||||
part: "extends",
|
||||
path: string,
|
||||
dirname: string,
|
||||
activeEnv: string | null,
|
||||
};
|
||||
|
||||
export default function buildConfigChain(
|
||||
opts: ValidatedOptions,
|
||||
): Array<ConfigItem> | null {
|
||||
const filename = opts.filename ? path.resolve(opts.filename) : null;
|
||||
const builder = new ConfigChainBuilder(
|
||||
filename ? new LoadedFile(filename) : null,
|
||||
@ -58,21 +69,34 @@ export default function buildConfigChain(opts: {}): Array<ConfigItem> | null {
|
||||
class ConfigChainBuilder {
|
||||
file: LoadedFile | null;
|
||||
configs: Array<ConfigItem> = [];
|
||||
seenFiles: Set<ConfigFile> = new Set();
|
||||
|
||||
constructor(file: LoadedFile | null) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
mergeConfigArguments(opts: {}, dirname: string, envKey: string) {
|
||||
mergeConfigArguments(
|
||||
opts: ValidatedOptions,
|
||||
dirname: string,
|
||||
envKey: string,
|
||||
) {
|
||||
flattenArgumentsOptionsParts(opts, dirname, envKey).forEach(part =>
|
||||
this._processConfigPart(part, envKey),
|
||||
);
|
||||
}
|
||||
|
||||
mergeConfigFile(file: ConfigFile, envKey: string) {
|
||||
flattenFileOptionsParts(file)(envKey).forEach(part =>
|
||||
this._processConfigPart(part, envKey),
|
||||
);
|
||||
if (this.seenFiles.has(file)) {
|
||||
throw new Error(
|
||||
`Cycle detected in Babel configuration file through "${file.filepath}".`,
|
||||
);
|
||||
}
|
||||
|
||||
const parts = flattenFileOptionsParts(file)(envKey);
|
||||
|
||||
this.seenFiles.add(file);
|
||||
parts.forEach(part => this._processConfigPart(part, envKey));
|
||||
this.seenFiles.delete(file);
|
||||
}
|
||||
|
||||
_processConfigPart(part: ConfigPart, envKey: string) {
|
||||
@ -92,14 +116,7 @@ class ConfigChainBuilder {
|
||||
|
||||
this.configs.push(part.config);
|
||||
} else {
|
||||
const extendsConfig = loadConfig(part.path, part.dirname);
|
||||
|
||||
const existingConfig = this.configs.some(config => {
|
||||
return config.alias === extendsConfig.filepath;
|
||||
});
|
||||
if (!existingConfig) {
|
||||
this.mergeConfigFile(extendsConfig, envKey);
|
||||
}
|
||||
this.mergeConfigFile(loadConfig(part.path, part.dirname), envKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -110,43 +127,26 @@ class ConfigChainBuilder {
|
||||
* object identity preserved between calls so that they can be used for caching.
|
||||
*/
|
||||
function flattenArgumentsOptionsParts(
|
||||
opts: {},
|
||||
opts: ValidatedOptions,
|
||||
dirname: string,
|
||||
envKey: string,
|
||||
): Array<ConfigPart> {
|
||||
const {
|
||||
env,
|
||||
plugins,
|
||||
presets,
|
||||
passPerPreset,
|
||||
extends: extendsPath,
|
||||
...options
|
||||
} = opts;
|
||||
|
||||
const raw = [];
|
||||
|
||||
const env = typeof opts.env === "object" ? opts.env : null;
|
||||
const plugins = Array.isArray(opts.plugins) ? opts.plugins : null;
|
||||
const presets = Array.isArray(opts.presets) ? opts.presets : null;
|
||||
const passPerPreset =
|
||||
typeof opts.passPerPreset === "boolean" ? opts.passPerPreset : false;
|
||||
|
||||
if (env) {
|
||||
raw.push(...flattenArgumentsEnvOptionsParts(env)(dirname)(envKey));
|
||||
}
|
||||
|
||||
const innerOpts = Object.assign({}, opts);
|
||||
// If the env, plugins, and presets values on the object aren't arrays or
|
||||
// objects, leave them in the base opts so that normal options validation
|
||||
// will throw errors on them later.
|
||||
if (env) delete innerOpts.env;
|
||||
if (plugins) delete innerOpts.plugins;
|
||||
if (presets) {
|
||||
delete innerOpts.presets;
|
||||
delete innerOpts.passPerPreset;
|
||||
}
|
||||
delete innerOpts.extends;
|
||||
|
||||
if (Object.keys(innerOpts).length > 0) {
|
||||
raw.push(
|
||||
...flattenOptionsParts({
|
||||
type: "arguments",
|
||||
options: innerOpts,
|
||||
alias: "base",
|
||||
dirname,
|
||||
}),
|
||||
);
|
||||
if (Object.keys(options).length > 0) {
|
||||
raw.push(...flattenOptionsParts(buildArgumentsItem(options, dirname)));
|
||||
}
|
||||
|
||||
if (plugins) {
|
||||
@ -154,14 +154,14 @@ function flattenArgumentsOptionsParts(
|
||||
}
|
||||
if (presets) {
|
||||
raw.push(
|
||||
...flattenArgumentsPresetsOptionsParts(presets)(passPerPreset)(dirname),
|
||||
...flattenArgumentsPresetsOptionsParts(presets)(!!passPerPreset)(dirname),
|
||||
);
|
||||
}
|
||||
|
||||
if (opts.extends != null) {
|
||||
if (extendsPath != null) {
|
||||
raw.push(
|
||||
...flattenOptionsParts(
|
||||
buildArgumentsRawConfig({ extends: opts.extends }, dirname),
|
||||
buildArgumentsItem({ extends: extendsPath }, dirname),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -174,10 +174,10 @@ function flattenArgumentsOptionsParts(
|
||||
* the object identity of the 'env' object.
|
||||
*/
|
||||
const flattenArgumentsEnvOptionsParts = makeWeakCache((env: {}) => {
|
||||
const options = { env };
|
||||
const options: ValidatedOptions = { env };
|
||||
|
||||
return makeStrongCache((dirname: string) =>
|
||||
flattenOptionsPartsLookup(buildArgumentsRawConfig(options, dirname)),
|
||||
flattenOptionsPartsLookup(buildArgumentsItem(options, dirname)),
|
||||
);
|
||||
});
|
||||
|
||||
@ -186,11 +186,11 @@ const flattenArgumentsEnvOptionsParts = makeWeakCache((env: {}) => {
|
||||
* the object identity of the 'plugins' object.
|
||||
*/
|
||||
const flattenArgumentsPluginsOptionsParts = makeWeakCache(
|
||||
(plugins: Array<mixed>) => {
|
||||
const options = { plugins };
|
||||
(plugins: PluginList) => {
|
||||
const options: ValidatedOptions = { plugins };
|
||||
|
||||
return makeStrongCache((dirname: string) =>
|
||||
flattenOptionsParts(buildArgumentsRawConfig(options, dirname)),
|
||||
flattenOptionsParts(buildArgumentsItem(options, dirname)),
|
||||
);
|
||||
},
|
||||
);
|
||||
@ -200,20 +200,23 @@ const flattenArgumentsPluginsOptionsParts = makeWeakCache(
|
||||
* the object identity of the 'presets' object.
|
||||
*/
|
||||
const flattenArgumentsPresetsOptionsParts = makeWeakCache(
|
||||
(presets: Array<mixed>) =>
|
||||
makeStrongCache((passPerPreset: ?boolean) => {
|
||||
(presets: PluginList) =>
|
||||
makeStrongCache((passPerPreset: boolean) => {
|
||||
// The concept of passPerPreset is integrally tied to the preset list
|
||||
// so unfortunately we need to copy both values here, adding an extra
|
||||
// layer of caching functions.
|
||||
const options = { presets, passPerPreset };
|
||||
|
||||
return makeStrongCache((dirname: string) =>
|
||||
flattenOptionsParts(buildArgumentsRawConfig(options, dirname)),
|
||||
flattenOptionsParts(buildArgumentsItem(options, dirname)),
|
||||
);
|
||||
}),
|
||||
);
|
||||
|
||||
function buildArgumentsRawConfig(options: {}, dirname: string): ConfigRaw {
|
||||
function buildArgumentsItem(
|
||||
options: ValidatedOptions,
|
||||
dirname: string,
|
||||
): ConfigItem {
|
||||
return {
|
||||
type: "arguments",
|
||||
options,
|
||||
@ -229,8 +232,8 @@ function buildArgumentsRawConfig(options: {}, dirname: string): ConfigRaw {
|
||||
*/
|
||||
const flattenFileOptionsParts = makeWeakCache((file: ConfigFile) => {
|
||||
return flattenOptionsPartsLookup({
|
||||
type: "options",
|
||||
options: file.options,
|
||||
type: "file",
|
||||
options: validate("file", file.options),
|
||||
alias: file.filepath,
|
||||
dirname: file.dirname,
|
||||
});
|
||||
@ -241,7 +244,7 @@ const flattenFileOptionsParts = makeWeakCache((file: ConfigFile) => {
|
||||
* the environment passed as the first argument.
|
||||
*/
|
||||
function flattenOptionsPartsLookup(
|
||||
config: ConfigRaw,
|
||||
config: ConfigItem,
|
||||
): (string | null) => Array<ConfigPart> {
|
||||
const parts = flattenOptionsParts(config);
|
||||
|
||||
@ -263,107 +266,45 @@ function flattenOptionsPartsLookup(
|
||||
return envKey => lookup.get(envKey) || def;
|
||||
}
|
||||
|
||||
type ConfigPart =
|
||||
| {
|
||||
part: "config",
|
||||
config: ConfigItem,
|
||||
ignore: ?Array<mixed>,
|
||||
only: ?Array<mixed>,
|
||||
activeEnv: string | null,
|
||||
}
|
||||
| {
|
||||
part: "extends",
|
||||
path: string,
|
||||
dirname: string,
|
||||
activeEnv: string | null,
|
||||
};
|
||||
|
||||
/**
|
||||
* Given a generic config object, flatten it into its various parts so that
|
||||
* then can be cached and processed later.
|
||||
*/
|
||||
function flattenOptionsParts(
|
||||
rawConfig: ConfigRaw,
|
||||
config: ConfigItem,
|
||||
activeEnv: string | null = null,
|
||||
): Array<ConfigPart> {
|
||||
const { type, options: rawOpts, alias, dirname } = rawConfig;
|
||||
|
||||
if (rawOpts.ignore != null && !Array.isArray(rawOpts.ignore)) {
|
||||
throw new Error(
|
||||
`.ignore should be an array, ${JSON.stringify(rawOpts.ignore)} given`,
|
||||
);
|
||||
}
|
||||
if (rawOpts.only != null && !Array.isArray(rawOpts.only)) {
|
||||
throw new Error(
|
||||
`.only should be an array, ${JSON.stringify(rawOpts.only)} given`,
|
||||
);
|
||||
}
|
||||
const ignore = rawOpts.ignore || null;
|
||||
const only = rawOpts.only || null;
|
||||
const { options: rawOpts, alias, dirname } = config;
|
||||
|
||||
const parts = [];
|
||||
|
||||
if (
|
||||
rawOpts.env != null &&
|
||||
(typeof rawOpts.env !== "object" || Array.isArray(rawOpts.env))
|
||||
) {
|
||||
throw new Error(".env block must be an object, null, or undefined");
|
||||
if (rawOpts.env) {
|
||||
for (const envKey of Object.keys(rawOpts.env)) {
|
||||
if (rawOpts.env[envKey]) {
|
||||
parts.push(
|
||||
...flattenOptionsParts(
|
||||
{
|
||||
type: "env",
|
||||
options: rawOpts.env[envKey],
|
||||
alias: alias + `.env.${envKey}`,
|
||||
dirname,
|
||||
},
|
||||
envKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const rawEnv = rawOpts.env || {};
|
||||
|
||||
Object.keys(rawEnv).forEach(envKey => {
|
||||
const envOpts = rawEnv[envKey];
|
||||
|
||||
if (envOpts !== undefined && activeEnv !== null && activeEnv !== envKey) {
|
||||
throw new Error(`Unreachable .env[${envKey}] block detected`);
|
||||
}
|
||||
|
||||
if (
|
||||
envOpts != null &&
|
||||
(typeof envOpts !== "object" || Array.isArray(envOpts))
|
||||
) {
|
||||
throw new Error(".env[...] block must be an object, null, or undefined");
|
||||
}
|
||||
|
||||
if (envOpts) {
|
||||
parts.push(
|
||||
...flattenOptionsParts(
|
||||
{
|
||||
type,
|
||||
options: envOpts,
|
||||
alias: alias + `.env.${envKey}`,
|
||||
dirname,
|
||||
},
|
||||
envKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const options = Object.assign({}, rawOpts);
|
||||
delete options.env;
|
||||
delete options.extends;
|
||||
|
||||
parts.push({
|
||||
part: "config",
|
||||
config: {
|
||||
type,
|
||||
options,
|
||||
alias,
|
||||
loc: alias,
|
||||
dirname,
|
||||
},
|
||||
ignore,
|
||||
only,
|
||||
config,
|
||||
ignore: rawOpts.ignore,
|
||||
only: rawOpts.only,
|
||||
activeEnv,
|
||||
});
|
||||
|
||||
if (rawOpts.extends != null) {
|
||||
if (typeof rawOpts.extends !== "string") {
|
||||
throw new Error(".extends must be a string");
|
||||
}
|
||||
|
||||
parts.push({
|
||||
part: "extends",
|
||||
path: rawOpts.extends,
|
||||
@ -390,8 +331,8 @@ class LoadedFile {
|
||||
* Tests if a filename should be ignored based on "ignore" and "only" options.
|
||||
*/
|
||||
shouldIgnore(
|
||||
ignore: ?Array<mixed>,
|
||||
only: ?Array<mixed>,
|
||||
ignore: ?IgnoreList,
|
||||
only: ?IgnoreList,
|
||||
dirname: string,
|
||||
): boolean {
|
||||
if (ignore) {
|
||||
@ -425,7 +366,7 @@ class LoadedFile {
|
||||
* Returns result of calling function with filename if pattern is a function.
|
||||
* Otherwise returns result of matching pattern Regex with filename.
|
||||
*/
|
||||
_matchesPatterns(patterns: Array<mixed>, dirname: string): boolean {
|
||||
_matchesPatterns(patterns: IgnoreList, dirname: string): boolean {
|
||||
const res = [];
|
||||
const strings = [];
|
||||
const fns = [];
|
||||
@ -433,12 +374,7 @@ class LoadedFile {
|
||||
patterns.forEach(pattern => {
|
||||
if (typeof pattern === "string") strings.push(pattern);
|
||||
else if (typeof pattern === "function") fns.push(pattern);
|
||||
else if (pattern instanceof RegExp) res.push(pattern);
|
||||
else {
|
||||
throw new Error(
|
||||
"Patterns must be a string, function, or regular expression",
|
||||
);
|
||||
}
|
||||
else res.push(pattern);
|
||||
});
|
||||
|
||||
const filename = this.filename;
|
||||
|
||||
@ -31,7 +31,7 @@ export function makeStrongCache<ArgT, ResultT>(
|
||||
* configures its caching behavior. Cached values are stored weakly and the function argument must be
|
||||
* an object type.
|
||||
*/
|
||||
export function makeWeakCache<ArgT: {} | Array<*>, ResultT>(
|
||||
export function makeWeakCache<ArgT: {} | Array<*> | $ReadOnlyArray<*>, ResultT>(
|
||||
handler: (ArgT, CacheConfigurator) => ResultT,
|
||||
autoPermacache?: boolean,
|
||||
): ArgT => ResultT {
|
||||
|
||||
@ -16,7 +16,7 @@ export type PluginPasses = Array<PluginPassList>;
|
||||
* Standard API for loading Babel configuration data. Not for public consumption.
|
||||
*/
|
||||
export default function loadConfig(opts: mixed): ResolvedConfig | null {
|
||||
if (opts != null && typeof opts !== "object") {
|
||||
if (opts != null && (typeof opts !== "object" || Array.isArray(opts))) {
|
||||
throw new Error("Babel options must be an object, null, or undefined");
|
||||
}
|
||||
|
||||
|
||||
179
packages/babel-core/src/config/option-assertions.js
Normal file
179
packages/babel-core/src/config/option-assertions.js
Normal file
@ -0,0 +1,179 @@
|
||||
// @flow
|
||||
|
||||
import type {
|
||||
IgnoreList,
|
||||
IgnoreItem,
|
||||
PluginList,
|
||||
PluginItem,
|
||||
PluginTarget,
|
||||
SourceMapsOption,
|
||||
SourceTypeOption,
|
||||
CompactOption,
|
||||
RootInputSourceMapOption,
|
||||
} from "./options";
|
||||
|
||||
export function assertSourceMaps(
|
||||
key: string,
|
||||
value: mixed,
|
||||
): SourceMapsOption | void {
|
||||
if (
|
||||
value !== undefined &&
|
||||
typeof value !== "boolean" &&
|
||||
value !== "inline" &&
|
||||
value !== "both"
|
||||
) {
|
||||
throw new Error(
|
||||
`.${key} must be a boolean, "inline", "both", or undefined`,
|
||||
);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export function assertCompact(key: string, value: mixed): CompactOption | void {
|
||||
if (value !== undefined && typeof value !== "boolean" && value !== "auto") {
|
||||
throw new Error(`.${key} must be a boolean, "auto", or undefined`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export function assertSourceType(
|
||||
key: string,
|
||||
value: mixed,
|
||||
): SourceTypeOption | void {
|
||||
if (value !== undefined && value !== "module" && value !== "script") {
|
||||
throw new Error(`.${key} must be "module", "script", or undefined`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export function assertInputSourceMap(
|
||||
key: string,
|
||||
value: mixed,
|
||||
): RootInputSourceMapOption | void {
|
||||
if (
|
||||
value !== undefined &&
|
||||
typeof value !== "boolean" &&
|
||||
(typeof value !== "object" || !value)
|
||||
) {
|
||||
throw new Error(".inputSourceMap must be a boolean, object, or undefined");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export function assertString(key: string, value: mixed): string | void {
|
||||
if (value !== undefined && typeof value !== "string") {
|
||||
throw new Error(`.${key} must be a string, or undefined`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export function assertFunction(key: string, value: mixed): Function | void {
|
||||
if (value !== undefined && typeof value !== "function") {
|
||||
throw new Error(`.${key} must be a function, or undefined`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export function assertBoolean(key: string, value: mixed): boolean | void {
|
||||
if (value !== undefined && typeof value !== "boolean") {
|
||||
throw new Error(`.${key} must be a boolean, or undefined`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export function assertObject(key: string, value: mixed): {} | void {
|
||||
if (
|
||||
value !== undefined &&
|
||||
(typeof value !== "object" || Array.isArray(value) || !value)
|
||||
) {
|
||||
throw new Error(`.${key} must be an object, or undefined`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export function assertIgnoreList(key: string, value: mixed): IgnoreList | void {
|
||||
const arr = assertArray(key, value);
|
||||
if (arr) {
|
||||
arr.forEach((item, i) => assertIgnoreItem(key, i, item));
|
||||
}
|
||||
return (arr: any);
|
||||
}
|
||||
function assertIgnoreItem(
|
||||
key: string,
|
||||
index: number,
|
||||
value: mixed,
|
||||
): IgnoreItem {
|
||||
if (
|
||||
typeof value !== "string" &&
|
||||
typeof value !== "function" &&
|
||||
!(value instanceof RegExp)
|
||||
) {
|
||||
throw new Error(
|
||||
`.${key}[${index}] must be an array of string/Funtion/RegExp values, or or undefined`,
|
||||
);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export function assertPluginList(key: string, value: mixed): PluginList | void {
|
||||
const arr = assertArray(key, value);
|
||||
if (arr) {
|
||||
// Loop instead of using `.map` in order to preserve object identity
|
||||
// for plugin array for use during config chain processing.
|
||||
arr.forEach((item, i) => assertPluginItem(key, i, item));
|
||||
}
|
||||
return (arr: any);
|
||||
}
|
||||
function assertPluginItem(
|
||||
key: string,
|
||||
index: number,
|
||||
value: mixed,
|
||||
): PluginItem {
|
||||
if (Array.isArray(value)) {
|
||||
if (value.length === 0) {
|
||||
throw new Error(`.${key}[${index}] must include an object`);
|
||||
}
|
||||
if (value.length > 2) {
|
||||
throw new Error(`.${key}[${index}] may only be a two-tuple`);
|
||||
}
|
||||
|
||||
assertPluginTarget(key, index, true, value[0]);
|
||||
|
||||
if (value.length === 2) {
|
||||
const opts = value[1];
|
||||
if (opts != null && (typeof opts !== "object" || Array.isArray(opts))) {
|
||||
throw new Error(`.${key}[${index}][1] must be an object, or undefined`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assertPluginTarget(key, index, false, value);
|
||||
}
|
||||
|
||||
return (value: any);
|
||||
}
|
||||
function assertPluginTarget(
|
||||
key: string,
|
||||
index: number,
|
||||
inArray: boolean,
|
||||
value: mixed,
|
||||
): PluginTarget {
|
||||
if (
|
||||
(typeof value !== "object" || !value) &&
|
||||
typeof value !== "string" &&
|
||||
typeof value !== "function"
|
||||
) {
|
||||
throw new Error(
|
||||
`.${key}[${index}]${inArray
|
||||
? `[0]`
|
||||
: ""} must be a string, object, function`,
|
||||
);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function assertArray(key: string, value: mixed): ?$ReadOnlyArray<mixed> {
|
||||
if (value != null && !Array.isArray(value)) {
|
||||
throw new Error(`.${key} must be an array, or undefined`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@ -4,13 +4,13 @@ import * as context from "../index";
|
||||
import Plugin from "./plugin";
|
||||
import defaults from "lodash/defaults";
|
||||
import merge from "lodash/merge";
|
||||
import removed from "./removed";
|
||||
import buildConfigChain from "./build-config-chain";
|
||||
import buildConfigChain, { type ConfigItem } from "./build-config-chain";
|
||||
import path from "path";
|
||||
import traverse from "@babel/traverse";
|
||||
import clone from "lodash/clone";
|
||||
import { makeWeakCache } from "./caching";
|
||||
import { getEnv } from "./helpers/environment";
|
||||
import { validate, type ValidatedOptions, type PluginItem } from "./options";
|
||||
|
||||
import {
|
||||
loadPlugin,
|
||||
@ -19,54 +19,14 @@ import {
|
||||
loadGenerator,
|
||||
} from "./loading/files";
|
||||
|
||||
type MergeOptions = {
|
||||
+type: "arguments" | "options" | "preset",
|
||||
options: {},
|
||||
alias: string,
|
||||
loc: string,
|
||||
dirname: string,
|
||||
};
|
||||
|
||||
const optionNames = new Set([
|
||||
"relative",
|
||||
"filename",
|
||||
"filenameRelative",
|
||||
"inputSourceMap",
|
||||
"env",
|
||||
"mode",
|
||||
"retainLines",
|
||||
"highlightCode",
|
||||
"suppressDeprecationMessages",
|
||||
"presets",
|
||||
"plugins",
|
||||
"ignore",
|
||||
"only",
|
||||
"code",
|
||||
"ast",
|
||||
"extends",
|
||||
"comments",
|
||||
"shouldPrintComment",
|
||||
"wrapPluginVisitorMethod",
|
||||
"compact",
|
||||
"minified",
|
||||
"sourceMaps",
|
||||
"sourceMapTarget",
|
||||
"sourceFileName",
|
||||
"sourceRoot",
|
||||
"babelrc",
|
||||
"sourceType",
|
||||
"auxiliaryCommentBefore",
|
||||
"auxiliaryCommentAfter",
|
||||
"getModuleId",
|
||||
"moduleRoot",
|
||||
"moduleIds",
|
||||
"moduleId",
|
||||
"passPerPreset",
|
||||
// Deprecate top level parserOpts
|
||||
"parserOpts",
|
||||
// Deprecate top level generatorOpts
|
||||
"generatorOpts",
|
||||
]);
|
||||
type MergeOptions =
|
||||
| ConfigItem
|
||||
| {
|
||||
type: "preset",
|
||||
options: ValidatedOptions,
|
||||
alias: string,
|
||||
dirname: string,
|
||||
};
|
||||
|
||||
const ALLOWED_PLUGIN_KEYS = new Set([
|
||||
"name",
|
||||
@ -86,11 +46,11 @@ export default function manageOptions(opts: {}): {
|
||||
|
||||
class OptionManager {
|
||||
constructor() {
|
||||
this.options = createInitialOptions();
|
||||
this.options = {};
|
||||
this.passes = [[]];
|
||||
}
|
||||
|
||||
options: Object;
|
||||
options: ValidatedOptions;
|
||||
passes: Array<Array<Plugin>>;
|
||||
|
||||
/**
|
||||
@ -112,12 +72,6 @@ class OptionManager {
|
||||
loadPresetDescriptor(descriptor),
|
||||
);
|
||||
|
||||
if (
|
||||
config.options.passPerPreset != null &&
|
||||
typeof config.options.passPerPreset !== "boolean"
|
||||
) {
|
||||
throw new Error(".passPerPreset must be a boolean or undefined");
|
||||
}
|
||||
const passPerPreset = config.options.passPerPreset;
|
||||
pass = pass || this.passes[0];
|
||||
|
||||
@ -141,11 +95,27 @@ class OptionManager {
|
||||
pass.unshift(...plugins);
|
||||
}
|
||||
|
||||
merge(this.options, result.options);
|
||||
const options = Object.assign({}, result.options);
|
||||
delete options.extends;
|
||||
delete options.env;
|
||||
delete options.plugins;
|
||||
delete options.presets;
|
||||
delete options.passPerPreset;
|
||||
|
||||
// "sourceMap" is just aliased to sourceMap, so copy it over as
|
||||
// we merge the options together.
|
||||
if (options.sourceMap) {
|
||||
options.sourceMaps = options.sourceMap;
|
||||
delete options.sourceMap;
|
||||
}
|
||||
|
||||
merge(this.options, options);
|
||||
}
|
||||
|
||||
init(opts: {}) {
|
||||
const configChain = buildConfigChain(opts);
|
||||
init(inputOpts: {}) {
|
||||
const args = validate("arguments", inputOpts);
|
||||
|
||||
const configChain = buildConfigChain(args);
|
||||
if (!configChain) return null;
|
||||
|
||||
try {
|
||||
@ -156,15 +126,13 @@ class OptionManager {
|
||||
// There are a few case where thrown errors will try to annotate themselves multiple times, so
|
||||
// to keep things simple we just bail out if re-wrapping the message.
|
||||
if (!/^\[BABEL\]/.test(e.message)) {
|
||||
const filename =
|
||||
typeof opts.filename === "string" ? opts.filename : null;
|
||||
e.message = `[BABEL] ${filename || "unknown"}: ${e.message}`;
|
||||
e.message = `[BABEL] ${args.filename || "unknown"}: ${e.message}`;
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
|
||||
opts = this.options;
|
||||
const opts: Object = merge(createInitialOptions(), this.options);
|
||||
|
||||
// Tack the passes onto the object itself so that, if this object is passed back to Babel a second time,
|
||||
// it will be in the right structure to not change behavior.
|
||||
@ -173,6 +141,7 @@ class OptionManager {
|
||||
.slice(1)
|
||||
.filter(plugins => plugins.length > 0)
|
||||
.map(plugins => ({ plugins }));
|
||||
opts.passPerPreset = opts.presets.length > 0;
|
||||
|
||||
if (opts.inputSourceMap) {
|
||||
opts.sourceMaps = true;
|
||||
@ -217,7 +186,6 @@ type BasicDescriptor = {
|
||||
options: {} | void,
|
||||
dirname: string,
|
||||
alias: string,
|
||||
loc: string,
|
||||
};
|
||||
|
||||
type LoadedDescriptor = {
|
||||
@ -225,64 +193,31 @@ type LoadedDescriptor = {
|
||||
options: {},
|
||||
dirname: string,
|
||||
alias: string,
|
||||
loc: string,
|
||||
};
|
||||
|
||||
/**
|
||||
* Load and validate the given config into a set of options, plugins, and presets.
|
||||
*/
|
||||
const loadConfig = makeWeakCache((config): {
|
||||
const loadConfig = makeWeakCache((config: MergeOptions): {
|
||||
options: {},
|
||||
plugins: Array<BasicDescriptor>,
|
||||
presets: Array<BasicDescriptor>,
|
||||
} => {
|
||||
const options = normalizeOptions(config);
|
||||
|
||||
if (
|
||||
config.options.plugins != null &&
|
||||
!Array.isArray(config.options.plugins)
|
||||
) {
|
||||
throw new Error(".plugins should be an array, null, or undefined");
|
||||
}
|
||||
const plugins = (config.options.plugins || []).map((plugin, index) =>
|
||||
createDescriptor(plugin, loadPlugin, config.dirname, {
|
||||
index,
|
||||
alias: config.alias,
|
||||
}),
|
||||
);
|
||||
|
||||
const plugins = (config.options.plugins || []).map((plugin, index) => {
|
||||
const { filepath, value, options } = normalizePair(
|
||||
plugin,
|
||||
loadPlugin,
|
||||
config.dirname,
|
||||
);
|
||||
|
||||
return {
|
||||
alias: filepath || `${config.loc}$${index}`,
|
||||
loc: filepath || config.loc,
|
||||
value,
|
||||
options,
|
||||
dirname: config.dirname,
|
||||
};
|
||||
});
|
||||
|
||||
if (
|
||||
config.options.presets != null &&
|
||||
!Array.isArray(config.options.presets)
|
||||
) {
|
||||
throw new Error(".presets should be an array, null, or undefined");
|
||||
}
|
||||
|
||||
const presets = (config.options.presets || []).map((preset, index) => {
|
||||
const { filepath, value, options } = normalizePair(
|
||||
preset,
|
||||
loadPreset,
|
||||
config.dirname,
|
||||
);
|
||||
|
||||
return {
|
||||
alias: filepath || `${config.loc}$${index}`,
|
||||
loc: filepath || config.loc,
|
||||
value,
|
||||
options,
|
||||
dirname: config.dirname,
|
||||
};
|
||||
});
|
||||
const presets = (config.options.presets || []).map((preset, index) =>
|
||||
createDescriptor(preset, loadPreset, config.dirname, {
|
||||
index,
|
||||
alias: config.alias,
|
||||
}),
|
||||
);
|
||||
|
||||
return { options, plugins, presets };
|
||||
});
|
||||
@ -292,7 +227,7 @@ const loadConfig = makeWeakCache((config): {
|
||||
*/
|
||||
const loadDescriptor = makeWeakCache(
|
||||
(
|
||||
{ value, options = {}, dirname, alias, loc }: BasicDescriptor,
|
||||
{ value, options = {}, dirname, alias }: BasicDescriptor,
|
||||
cache,
|
||||
): LoadedDescriptor => {
|
||||
let item = value;
|
||||
@ -316,7 +251,7 @@ const loadDescriptor = makeWeakCache(
|
||||
throw new Error("Plugin/Preset did not return an object.");
|
||||
}
|
||||
|
||||
return { value: item, options, dirname, alias, loc };
|
||||
return { value: item, options, dirname, alias };
|
||||
},
|
||||
);
|
||||
|
||||
@ -339,7 +274,7 @@ function loadPluginDescriptor(descriptor: BasicDescriptor): Plugin {
|
||||
|
||||
const instantiatePlugin = makeWeakCache(
|
||||
(
|
||||
{ value: pluginObj, options, dirname, alias, loc }: LoadedDescriptor,
|
||||
{ value: pluginObj, options, dirname, alias }: LoadedDescriptor,
|
||||
cache,
|
||||
): Plugin => {
|
||||
Object.keys(pluginObj).forEach(key => {
|
||||
@ -369,8 +304,7 @@ const instantiatePlugin = makeWeakCache(
|
||||
let inherits;
|
||||
if (plugin.inherits) {
|
||||
inheritsDescriptor = {
|
||||
alias: `${loc}$inherits`,
|
||||
loc,
|
||||
alias: `${alias}$inherits`,
|
||||
value: plugin.inherits,
|
||||
options,
|
||||
dirname,
|
||||
@ -405,12 +339,11 @@ const loadPresetDescriptor = (descriptor: BasicDescriptor): MergeOptions => {
|
||||
};
|
||||
|
||||
const instantiatePreset = makeWeakCache(
|
||||
({ value, dirname, alias, loc }: LoadedDescriptor): MergeOptions => {
|
||||
({ value, dirname, alias }: LoadedDescriptor): MergeOptions => {
|
||||
return {
|
||||
type: "preset",
|
||||
options: value,
|
||||
options: validate("preset", value),
|
||||
alias,
|
||||
loc,
|
||||
dirname,
|
||||
};
|
||||
},
|
||||
@ -420,72 +353,12 @@ const instantiatePreset = makeWeakCache(
|
||||
* Validate and return the options object for the config.
|
||||
*/
|
||||
function normalizeOptions(config) {
|
||||
const alias = config.alias || "foreign";
|
||||
const type = config.type;
|
||||
|
||||
//
|
||||
if (typeof config.options !== "object" || Array.isArray(config.options)) {
|
||||
throw new TypeError(`Invalid options type for ${alias}`);
|
||||
}
|
||||
|
||||
//
|
||||
const options = Object.assign({}, config.options);
|
||||
|
||||
if (type !== "arguments") {
|
||||
if (options.filename !== undefined) {
|
||||
throw new Error(`${alias}.filename is only allowed as a root argument`);
|
||||
}
|
||||
|
||||
if (options.babelrc !== undefined) {
|
||||
throw new Error(`${alias}.babelrc is only allowed as a root argument`);
|
||||
}
|
||||
}
|
||||
|
||||
if (type === "preset") {
|
||||
if (options.only !== undefined) {
|
||||
throw new Error(`${alias}.only is not supported in a preset`);
|
||||
}
|
||||
if (options.ignore !== undefined) {
|
||||
throw new Error(`${alias}.ignore is not supported in a preset`);
|
||||
}
|
||||
if (options.extends !== undefined) {
|
||||
throw new Error(`${alias}.extends is not supported in a preset`);
|
||||
}
|
||||
if (options.env !== undefined) {
|
||||
throw new Error(`${alias}.env is not supported in a preset`);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.sourceMap !== undefined) {
|
||||
if (options.sourceMaps !== undefined) {
|
||||
throw new Error(`Both ${alias}.sourceMap and .sourceMaps have been set`);
|
||||
}
|
||||
|
||||
options.sourceMaps = options.sourceMap;
|
||||
delete options.sourceMap;
|
||||
}
|
||||
|
||||
for (const key in options) {
|
||||
// check for an unknown option
|
||||
if (!optionNames.has(key)) {
|
||||
if (removed[key]) {
|
||||
const { message, version = 5 } = removed[key];
|
||||
|
||||
throw new ReferenceError(
|
||||
`Using removed Babel ${version} option: ${alias}.${key} - ${message}`,
|
||||
);
|
||||
} else {
|
||||
// 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.`;
|
||||
|
||||
throw new ReferenceError(unknownOptErr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (options.parserOpts && typeof options.parserOpts.parser === "string") {
|
||||
options.parserOpts = Object.assign({}, options.parserOpts);
|
||||
options.parserOpts.parser = loadParser(
|
||||
(options.parserOpts: any).parser = loadParser(
|
||||
options.parserOpts.parser,
|
||||
config.dirname,
|
||||
).value;
|
||||
@ -496,41 +369,34 @@ function normalizeOptions(config) {
|
||||
typeof options.generatorOpts.generator === "string"
|
||||
) {
|
||||
options.generatorOpts = Object.assign({}, options.generatorOpts);
|
||||
options.generatorOpts.generator = loadGenerator(
|
||||
(options.generatorOpts: any).generator = loadGenerator(
|
||||
options.generatorOpts.generator,
|
||||
config.dirname,
|
||||
).value;
|
||||
}
|
||||
|
||||
delete options.passPerPreset;
|
||||
delete options.plugins;
|
||||
delete options.presets;
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a plugin/preset item, resolve it into a standard format.
|
||||
*/
|
||||
function normalizePair(
|
||||
pair: mixed,
|
||||
function createDescriptor(
|
||||
pair: PluginItem,
|
||||
resolver,
|
||||
dirname,
|
||||
): {
|
||||
filepath: string | null,
|
||||
value: {} | Function,
|
||||
options: {} | void,
|
||||
} {
|
||||
{
|
||||
index,
|
||||
alias,
|
||||
}: {
|
||||
index: number,
|
||||
alias: string,
|
||||
},
|
||||
): BasicDescriptor {
|
||||
let options;
|
||||
let value = pair;
|
||||
if (Array.isArray(pair)) {
|
||||
if (pair.length > 2) {
|
||||
throw new Error(
|
||||
`Unexpected extra options ${JSON.stringify(pair.slice(2))}.`,
|
||||
);
|
||||
}
|
||||
|
||||
[value, options] = pair;
|
||||
if (Array.isArray(value)) {
|
||||
[value, options] = value;
|
||||
}
|
||||
|
||||
let filepath = null;
|
||||
@ -572,7 +438,12 @@ function normalizePair(
|
||||
}
|
||||
options = options || undefined;
|
||||
|
||||
return { filepath, value, options };
|
||||
return {
|
||||
alias: filepath || `${alias}$${index}`,
|
||||
value,
|
||||
options,
|
||||
dirname,
|
||||
};
|
||||
}
|
||||
|
||||
function chain(a, b) {
|
||||
|
||||
255
packages/babel-core/src/config/options.js
Normal file
255
packages/babel-core/src/config/options.js
Normal file
@ -0,0 +1,255 @@
|
||||
// @flow
|
||||
|
||||
import removed from "./removed";
|
||||
import {
|
||||
assertString,
|
||||
assertBoolean,
|
||||
assertObject,
|
||||
assertInputSourceMap,
|
||||
assertIgnoreList,
|
||||
assertPluginList,
|
||||
assertFunction,
|
||||
assertSourceMaps,
|
||||
assertCompact,
|
||||
assertSourceType,
|
||||
} from "./option-assertions";
|
||||
|
||||
type ValidatorSet = {
|
||||
[string]: Validator<any>,
|
||||
};
|
||||
|
||||
type Validator<T> = (string, mixed) => T;
|
||||
|
||||
const ROOT_VALIDATORS: ValidatorSet = {
|
||||
filename: (assertString: Validator<
|
||||
$PropertyType<ValidatedOptions, "filename">,
|
||||
>),
|
||||
filenameRelative: (assertString: Validator<
|
||||
$PropertyType<ValidatedOptions, "filenameRelative">,
|
||||
>),
|
||||
babelrc: (assertBoolean: Validator<
|
||||
$PropertyType<ValidatedOptions, "babelrc">,
|
||||
>),
|
||||
code: (assertBoolean: Validator<$PropertyType<ValidatedOptions, "code">>),
|
||||
ast: (assertBoolean: Validator<$PropertyType<ValidatedOptions, "ast">>),
|
||||
};
|
||||
|
||||
const NONPRESET_VALIDATORS: ValidatorSet = {
|
||||
extends: (assertString: Validator<
|
||||
$PropertyType<ValidatedOptions, "extends">,
|
||||
>),
|
||||
env: (assertEnvSet: Validator<$PropertyType<ValidatedOptions, "env">>),
|
||||
ignore: (assertIgnoreList: Validator<
|
||||
$PropertyType<ValidatedOptions, "ignore">,
|
||||
>),
|
||||
only: (assertIgnoreList: Validator<$PropertyType<ValidatedOptions, "only">>),
|
||||
};
|
||||
|
||||
const COMMON_VALIDATORS: ValidatorSet = {
|
||||
// TODO: Should 'inputSourceMap' be moved to be a root-only option?
|
||||
// We may want a boolean-only version to be a common option, with the
|
||||
// object only allowed as a root config argument.
|
||||
inputSourceMap: (assertInputSourceMap: Validator<
|
||||
$PropertyType<ValidatedOptions, "inputSourceMap">,
|
||||
>),
|
||||
presets: (assertPluginList: Validator<
|
||||
$PropertyType<ValidatedOptions, "presets">,
|
||||
>),
|
||||
plugins: (assertPluginList: Validator<
|
||||
$PropertyType<ValidatedOptions, "plugins">,
|
||||
>),
|
||||
passPerPreset: (assertBoolean: Validator<
|
||||
$PropertyType<ValidatedOptions, "passPerPreset">,
|
||||
>),
|
||||
retainLines: (assertBoolean: Validator<
|
||||
$PropertyType<ValidatedOptions, "retainLines">,
|
||||
>),
|
||||
comments: (assertBoolean: Validator<
|
||||
$PropertyType<ValidatedOptions, "comments">,
|
||||
>),
|
||||
shouldPrintComment: (assertFunction: Validator<
|
||||
$PropertyType<ValidatedOptions, "shouldPrintComment">,
|
||||
>),
|
||||
compact: (assertCompact: Validator<
|
||||
$PropertyType<ValidatedOptions, "compact">,
|
||||
>),
|
||||
minified: (assertBoolean: Validator<
|
||||
$PropertyType<ValidatedOptions, "minified">,
|
||||
>),
|
||||
auxiliaryCommentBefore: (assertString: Validator<
|
||||
$PropertyType<ValidatedOptions, "auxiliaryCommentBefore">,
|
||||
>),
|
||||
auxiliaryCommentAfter: (assertString: Validator<
|
||||
$PropertyType<ValidatedOptions, "auxiliaryCommentAfter">,
|
||||
>),
|
||||
sourceType: (assertSourceType: Validator<
|
||||
$PropertyType<ValidatedOptions, "sourceType">,
|
||||
>),
|
||||
wrapPluginVisitorMethod: (assertFunction: Validator<
|
||||
$PropertyType<ValidatedOptions, "wrapPluginVisitorMethod">,
|
||||
>),
|
||||
highlightCode: (assertBoolean: Validator<
|
||||
$PropertyType<ValidatedOptions, "highlightCode">,
|
||||
>),
|
||||
sourceMaps: (assertSourceMaps: Validator<
|
||||
$PropertyType<ValidatedOptions, "sourceMaps">,
|
||||
>),
|
||||
sourceMap: (assertSourceMaps: Validator<
|
||||
$PropertyType<ValidatedOptions, "sourceMap">,
|
||||
>),
|
||||
sourceMapTarget: (assertString: Validator<
|
||||
$PropertyType<ValidatedOptions, "sourceMapTarget">,
|
||||
>),
|
||||
sourceFileName: (assertString: Validator<
|
||||
$PropertyType<ValidatedOptions, "sourceFileName">,
|
||||
>),
|
||||
sourceRoot: (assertString: Validator<
|
||||
$PropertyType<ValidatedOptions, "sourceRoot">,
|
||||
>),
|
||||
getModuleId: (assertFunction: Validator<
|
||||
$PropertyType<ValidatedOptions, "getModuleId">,
|
||||
>),
|
||||
moduleRoot: (assertString: Validator<
|
||||
$PropertyType<ValidatedOptions, "moduleRoot">,
|
||||
>),
|
||||
moduleIds: (assertBoolean: Validator<
|
||||
$PropertyType<ValidatedOptions, "moduleIds">,
|
||||
>),
|
||||
moduleId: (assertString: Validator<
|
||||
$PropertyType<ValidatedOptions, "moduleId">,
|
||||
>),
|
||||
parserOpts: (assertObject: Validator<
|
||||
$PropertyType<ValidatedOptions, "parserOpts">,
|
||||
>),
|
||||
generatorOpts: (assertObject: Validator<
|
||||
$PropertyType<ValidatedOptions, "generatorOpts">,
|
||||
>),
|
||||
};
|
||||
export type ValidatedOptions = {
|
||||
filename?: string,
|
||||
filenameRelative?: string,
|
||||
babelrc?: boolean,
|
||||
code?: boolean,
|
||||
ast?: boolean,
|
||||
inputSourceMap?: RootInputSourceMapOption,
|
||||
|
||||
extends?: string,
|
||||
env?: EnvSet<ValidatedOptions>,
|
||||
ignore?: IgnoreList,
|
||||
only?: IgnoreList,
|
||||
|
||||
presets?: PluginList,
|
||||
plugins?: PluginList,
|
||||
passPerPreset?: boolean,
|
||||
|
||||
// Options for @babel/generator
|
||||
retainLines?: boolean,
|
||||
comments?: boolean,
|
||||
shouldPrintComment?: Function,
|
||||
compact?: CompactOption,
|
||||
minified?: boolean,
|
||||
auxiliaryCommentBefore?: string,
|
||||
auxiliaryCommentAfter?: string,
|
||||
|
||||
// Parser
|
||||
sourceType?: SourceTypeOption,
|
||||
|
||||
wrapPluginVisitorMethod?: Function,
|
||||
highlightCode?: boolean,
|
||||
|
||||
// Sourcemap generation options.
|
||||
sourceMaps?: SourceMapsOption,
|
||||
sourceMap?: SourceMapsOption,
|
||||
sourceMapTarget?: string,
|
||||
sourceFileName?: string,
|
||||
sourceRoot?: string,
|
||||
|
||||
// AMD/UMD/SystemJS module naming options.
|
||||
getModuleId?: Function,
|
||||
moduleRoot?: string,
|
||||
moduleIds?: boolean,
|
||||
moduleId?: string,
|
||||
|
||||
// Deprecate top level parserOpts
|
||||
parserOpts?: {},
|
||||
// Deprecate top level generatorOpts
|
||||
generatorOpts?: {},
|
||||
};
|
||||
|
||||
export type EnvSet<T> = {
|
||||
[string]: ?T,
|
||||
};
|
||||
export type IgnoreItem = string | Function | RegExp;
|
||||
export type IgnoreList = $ReadOnlyArray<IgnoreItem>;
|
||||
|
||||
export type PluginTarget = string | {} | Function;
|
||||
export type PluginItem = PluginTarget | [PluginTarget, {} | void];
|
||||
export type PluginList = $ReadOnlyArray<PluginItem>;
|
||||
|
||||
export type SourceMapsOption = boolean | "inline" | "both";
|
||||
export type SourceTypeOption = "module" | "script";
|
||||
export type CompactOption = boolean | "auto";
|
||||
export type RootInputSourceMapOption = {} | boolean;
|
||||
|
||||
export type OptionsType = "arguments" | "file" | "env" | "preset";
|
||||
|
||||
export function validate(type: OptionsType, opts: {}): ValidatedOptions {
|
||||
assertNoDuplicateSourcemap(opts);
|
||||
|
||||
Object.keys(opts).forEach(key => {
|
||||
if (type === "preset" && NONPRESET_VALIDATORS[key]) {
|
||||
throw new Error(`.${key} is not allowed in preset options`);
|
||||
}
|
||||
if (type !== "arguments" && ROOT_VALIDATORS[key]) {
|
||||
throw new Error(`.${key} is only allowed in root programmatic options`);
|
||||
}
|
||||
|
||||
const validator =
|
||||
COMMON_VALIDATORS[key] ||
|
||||
NONPRESET_VALIDATORS[key] ||
|
||||
ROOT_VALIDATORS[key];
|
||||
|
||||
if (validator) validator(key, opts[key]);
|
||||
else throw buildUnknownError(key);
|
||||
});
|
||||
|
||||
return (opts: any);
|
||||
}
|
||||
|
||||
function buildUnknownError(key: string) {
|
||||
if (removed[key]) {
|
||||
const { message, version = 5 } = removed[key];
|
||||
|
||||
throw new ReferenceError(
|
||||
`Using removed Babel ${version} option: .${key} - ${message}`,
|
||||
);
|
||||
} else {
|
||||
// eslint-disable-next-line max-len
|
||||
const unknownOptErr = `Unknown option: .${key}. Check out http://babeljs.io/docs/usage/options/ for more information about options.`;
|
||||
|
||||
throw new ReferenceError(unknownOptErr);
|
||||
}
|
||||
}
|
||||
|
||||
function has(obj: {}, key: string) {
|
||||
return Object.prototype.hasOwnProperty.call(obj, key);
|
||||
}
|
||||
|
||||
function assertNoDuplicateSourcemap(opts: {}): void {
|
||||
if (has(opts, "sourceMap") && has(opts, "sourceMaps")) {
|
||||
throw new Error(".sourceMap is an alias for .sourceMaps, cannot use both");
|
||||
}
|
||||
}
|
||||
|
||||
function assertEnvSet(key: string, value: mixed): EnvSet<ValidatedOptions> {
|
||||
const obj = assertObject(key, value);
|
||||
if (obj) {
|
||||
// Validate but don't copy the .env object in order to preserve
|
||||
// object identity for use during config chain processing.
|
||||
for (const key of Object.keys(obj)) {
|
||||
const env = assertObject(key, obj[key]);
|
||||
if (env) validate("env", env);
|
||||
}
|
||||
}
|
||||
return (obj: any);
|
||||
}
|
||||
@ -145,7 +145,7 @@ describe("api", function() {
|
||||
babel.transform("", {
|
||||
plugins: [__dirname + "/../../babel-plugin-syntax-jsx", false],
|
||||
});
|
||||
}, /Error: \[BABEL\] unknown: Unexpected falsy value: false/);
|
||||
}, /.plugins\[1\] must be a string, object, function/);
|
||||
});
|
||||
|
||||
it("options merge backwards", function() {
|
||||
@ -530,31 +530,31 @@ describe("api", function() {
|
||||
it("default", function() {
|
||||
const result = babel.transform("foo;", {
|
||||
env: {
|
||||
development: { code: false },
|
||||
development: { comments: false },
|
||||
},
|
||||
});
|
||||
|
||||
assert.equal(result.code, undefined);
|
||||
assert.equal(result.options.comments, false);
|
||||
});
|
||||
|
||||
it("BABEL_ENV", function() {
|
||||
process.env.BABEL_ENV = "foo";
|
||||
const result = babel.transform("foo;", {
|
||||
env: {
|
||||
foo: { code: false },
|
||||
foo: { comments: false },
|
||||
},
|
||||
});
|
||||
assert.equal(result.code, undefined);
|
||||
assert.equal(result.options.comments, false);
|
||||
});
|
||||
|
||||
it("NODE_ENV", function() {
|
||||
process.env.NODE_ENV = "foo";
|
||||
const result = babel.transform("foo;", {
|
||||
env: {
|
||||
foo: { code: false },
|
||||
foo: { comments: false },
|
||||
},
|
||||
});
|
||||
assert.equal(result.code, undefined);
|
||||
assert.equal(result.options.comments, false);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -72,7 +72,6 @@ describe("buildConfigChain", function() {
|
||||
],
|
||||
},
|
||||
alias: "base",
|
||||
loc: "base",
|
||||
dirname: base(),
|
||||
},
|
||||
];
|
||||
@ -117,7 +116,6 @@ describe("buildConfigChain", function() {
|
||||
],
|
||||
},
|
||||
alias: "base",
|
||||
loc: "base",
|
||||
dirname: base(),
|
||||
},
|
||||
];
|
||||
@ -374,30 +372,28 @@ describe("buildConfigChain", function() {
|
||||
|
||||
const expected = [
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
plugins: ["extended"],
|
||||
},
|
||||
alias: fixture("extended.babelrc.json"),
|
||||
loc: fixture("extended.babelrc.json"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
extends: "./extended.babelrc.json",
|
||||
plugins: ["root"],
|
||||
},
|
||||
alias: fixture(".babelrc"),
|
||||
loc: fixture(".babelrc"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
@ -406,7 +402,6 @@ describe("buildConfigChain", function() {
|
||||
filename: fixture("dir1", "src.js"),
|
||||
},
|
||||
alias: "base",
|
||||
loc: "base",
|
||||
dirname: base(),
|
||||
},
|
||||
];
|
||||
@ -421,21 +416,19 @@ describe("buildConfigChain", function() {
|
||||
|
||||
const expected = [
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
plugins: ["dir2"],
|
||||
},
|
||||
alias: fixture("dir2", ".babelrc"),
|
||||
loc: fixture("dir2", ".babelrc"),
|
||||
dirname: fixture("dir2"),
|
||||
},
|
||||
{
|
||||
@ -444,7 +437,6 @@ describe("buildConfigChain", function() {
|
||||
filename: fixture("dir2", "src.js"),
|
||||
},
|
||||
alias: "base",
|
||||
loc: "base",
|
||||
dirname: base(),
|
||||
},
|
||||
];
|
||||
@ -459,30 +451,28 @@ describe("buildConfigChain", function() {
|
||||
|
||||
const expected = [
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
plugins: ["extended"],
|
||||
},
|
||||
alias: fixture("extended.babelrc.json"),
|
||||
loc: fixture("extended.babelrc.json"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
extends: "./extended.babelrc.json",
|
||||
plugins: ["root"],
|
||||
},
|
||||
alias: fixture(".babelrc"),
|
||||
loc: fixture(".babelrc"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
@ -491,7 +481,6 @@ describe("buildConfigChain", function() {
|
||||
filename: fixture("dir3", "src.js"),
|
||||
},
|
||||
alias: "base",
|
||||
loc: "base",
|
||||
dirname: base(),
|
||||
},
|
||||
];
|
||||
@ -506,21 +495,27 @@ describe("buildConfigChain", function() {
|
||||
|
||||
const expected = [
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
env: {
|
||||
bar: {
|
||||
plugins: ["env-bar"],
|
||||
},
|
||||
foo: {
|
||||
plugins: ["env-foo"],
|
||||
},
|
||||
},
|
||||
plugins: ["env-base"],
|
||||
},
|
||||
alias: fixture("env", ".babelrc"),
|
||||
loc: fixture("env", ".babelrc"),
|
||||
dirname: fixture("env"),
|
||||
},
|
||||
{
|
||||
@ -529,7 +524,6 @@ describe("buildConfigChain", function() {
|
||||
filename: fixture("env", "src.js"),
|
||||
},
|
||||
alias: "base",
|
||||
loc: "base",
|
||||
dirname: base(),
|
||||
},
|
||||
];
|
||||
@ -546,30 +540,35 @@ describe("buildConfigChain", function() {
|
||||
|
||||
const expected = [
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
env: {
|
||||
bar: {
|
||||
plugins: ["env-bar"],
|
||||
},
|
||||
foo: {
|
||||
plugins: ["env-foo"],
|
||||
},
|
||||
},
|
||||
plugins: ["env-base"],
|
||||
},
|
||||
alias: fixture("env", ".babelrc"),
|
||||
loc: fixture("env", ".babelrc"),
|
||||
dirname: fixture("env"),
|
||||
},
|
||||
{
|
||||
type: "options",
|
||||
type: "env",
|
||||
options: {
|
||||
plugins: ["env-foo"],
|
||||
},
|
||||
alias: fixture("env", ".babelrc.env.foo"),
|
||||
loc: fixture("env", ".babelrc.env.foo"),
|
||||
dirname: fixture("env"),
|
||||
},
|
||||
{
|
||||
@ -578,7 +577,6 @@ describe("buildConfigChain", function() {
|
||||
filename: fixture("env", "src.js"),
|
||||
},
|
||||
alias: "base",
|
||||
loc: "base",
|
||||
dirname: base(),
|
||||
},
|
||||
];
|
||||
@ -596,30 +594,35 @@ describe("buildConfigChain", function() {
|
||||
|
||||
const expected = [
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
env: {
|
||||
bar: {
|
||||
plugins: ["env-bar"],
|
||||
},
|
||||
foo: {
|
||||
plugins: ["env-foo"],
|
||||
},
|
||||
},
|
||||
plugins: ["env-base"],
|
||||
},
|
||||
alias: fixture("env", ".babelrc"),
|
||||
loc: fixture("env", ".babelrc"),
|
||||
dirname: fixture("env"),
|
||||
},
|
||||
{
|
||||
type: "options",
|
||||
type: "env",
|
||||
options: {
|
||||
plugins: ["env-bar"],
|
||||
},
|
||||
alias: fixture("env", ".babelrc.env.bar"),
|
||||
loc: fixture("env", ".babelrc.env.bar"),
|
||||
dirname: fixture("env"),
|
||||
},
|
||||
{
|
||||
@ -628,7 +631,6 @@ describe("buildConfigChain", function() {
|
||||
filename: fixture("env", "src.js"),
|
||||
},
|
||||
alias: "base",
|
||||
loc: "base",
|
||||
dirname: base(),
|
||||
},
|
||||
];
|
||||
@ -645,21 +647,19 @@ describe("buildConfigChain", function() {
|
||||
|
||||
const expected = [
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
plugins: ["pkg-plugin"],
|
||||
},
|
||||
alias: fixture("pkg", "package.json"),
|
||||
loc: fixture("pkg", "package.json"),
|
||||
dirname: fixture("pkg"),
|
||||
},
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
ignore: ["pkg-ignore"],
|
||||
},
|
||||
alias: fixture("pkg", ".babelignore"),
|
||||
loc: fixture("pkg", ".babelignore"),
|
||||
dirname: fixture("pkg"),
|
||||
},
|
||||
{
|
||||
@ -668,7 +668,6 @@ describe("buildConfigChain", function() {
|
||||
filename: fixture("pkg", "src.js"),
|
||||
},
|
||||
alias: "base",
|
||||
loc: "base",
|
||||
dirname: base(),
|
||||
},
|
||||
];
|
||||
@ -683,21 +682,19 @@ describe("buildConfigChain", function() {
|
||||
|
||||
const expected = [
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
plugins: ["foo", "bar"],
|
||||
},
|
||||
alias: fixture("js-config", ".babelrc.js"),
|
||||
loc: fixture("js-config", ".babelrc.js"),
|
||||
dirname: fixture("js-config"),
|
||||
},
|
||||
{
|
||||
@ -706,7 +703,6 @@ describe("buildConfigChain", function() {
|
||||
filename: fixture("js-config", "src.js"),
|
||||
},
|
||||
alias: "base",
|
||||
loc: "base",
|
||||
dirname: base(),
|
||||
},
|
||||
];
|
||||
@ -721,21 +717,19 @@ describe("buildConfigChain", function() {
|
||||
|
||||
const expected = [
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
compact: true,
|
||||
},
|
||||
alias: fixture("js-config-function", ".babelrc.js"),
|
||||
loc: fixture("js-config-function", ".babelrc.js"),
|
||||
dirname: fixture("js-config-function"),
|
||||
},
|
||||
{
|
||||
@ -744,7 +738,6 @@ describe("buildConfigChain", function() {
|
||||
filename: fixture("js-config-function", "src.js"),
|
||||
},
|
||||
alias: "base",
|
||||
loc: "base",
|
||||
dirname: base(),
|
||||
},
|
||||
];
|
||||
@ -759,21 +752,19 @@ describe("buildConfigChain", function() {
|
||||
|
||||
const expected = [
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
plugins: ["foo", "bar"],
|
||||
},
|
||||
alias: fixture("js-config-default", ".babelrc.js"),
|
||||
loc: fixture("js-config-default", ".babelrc.js"),
|
||||
dirname: fixture("js-config-default"),
|
||||
},
|
||||
{
|
||||
@ -782,7 +773,6 @@ describe("buildConfigChain", function() {
|
||||
filename: fixture("js-config-default", "src.js"),
|
||||
},
|
||||
alias: "base",
|
||||
loc: "base",
|
||||
dirname: base(),
|
||||
},
|
||||
];
|
||||
@ -796,30 +786,28 @@ describe("buildConfigChain", function() {
|
||||
|
||||
const expected = [
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
plugins: ["extended"],
|
||||
},
|
||||
alias: fixture("extended.babelrc.json"),
|
||||
loc: fixture("extended.babelrc.json"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
extends: "../extended.babelrc.json",
|
||||
plugins: ["foo", "bar"],
|
||||
},
|
||||
alias: fixture("js-config-extended", ".babelrc.js"),
|
||||
loc: fixture("js-config-extended", ".babelrc.js"),
|
||||
dirname: fixture("js-config-extended"),
|
||||
},
|
||||
{
|
||||
@ -828,7 +816,6 @@ describe("buildConfigChain", function() {
|
||||
filename: fixture("js-config-extended", "src.js"),
|
||||
},
|
||||
alias: "base",
|
||||
loc: "base",
|
||||
dirname: base(),
|
||||
},
|
||||
];
|
||||
@ -846,21 +833,19 @@ describe("buildConfigChain", function() {
|
||||
|
||||
const expected = [
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
plugins: ["json"],
|
||||
},
|
||||
alias: fixture("json-pkg-config-no-babel", ".babelrc"),
|
||||
loc: fixture("json-pkg-config-no-babel", ".babelrc"),
|
||||
dirname: fixture("json-pkg-config-no-babel"),
|
||||
},
|
||||
{
|
||||
@ -869,7 +854,6 @@ describe("buildConfigChain", function() {
|
||||
filename: fixture("json-pkg-config-no-babel", "src.js"),
|
||||
},
|
||||
alias: "base",
|
||||
loc: "base",
|
||||
dirname: base(),
|
||||
},
|
||||
];
|
||||
@ -885,21 +869,19 @@ describe("buildConfigChain", function() {
|
||||
|
||||
const expected = [
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
ignore: ["*", "!src.js"],
|
||||
},
|
||||
alias: fixture("ignore-negate", ".babelrc"),
|
||||
loc: fixture("ignore-negate", ".babelrc"),
|
||||
dirname: fixture("ignore-negate"),
|
||||
},
|
||||
{
|
||||
@ -908,7 +890,6 @@ describe("buildConfigChain", function() {
|
||||
filename: fixture("ignore-negate", "src.js"),
|
||||
},
|
||||
alias: "base",
|
||||
loc: "base",
|
||||
dirname: base(),
|
||||
},
|
||||
];
|
||||
@ -929,21 +910,19 @@ describe("buildConfigChain", function() {
|
||||
|
||||
const expected = [
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
type: "options",
|
||||
type: "file",
|
||||
options: {
|
||||
ignore: ["*", "!folder"],
|
||||
},
|
||||
alias: fixture("ignore-negate-folder", ".babelrc"),
|
||||
loc: fixture("ignore-negate-folder", ".babelrc"),
|
||||
dirname: fixture("ignore-negate-folder"),
|
||||
},
|
||||
{
|
||||
@ -952,7 +931,6 @@ describe("buildConfigChain", function() {
|
||||
filename: fixture("ignore-negate-folder", "folder", "src.js"),
|
||||
},
|
||||
alias: "base",
|
||||
loc: "base",
|
||||
dirname: base(),
|
||||
},
|
||||
];
|
||||
|
||||
@ -17,7 +17,7 @@ describe("option-manager", () => {
|
||||
manageOptions({
|
||||
randomOption: true,
|
||||
});
|
||||
}, /Unknown option: base.randomOption/);
|
||||
}, /Unknown option: .randomOption/);
|
||||
});
|
||||
|
||||
it("throws for removed babel 5 options", () => {
|
||||
@ -29,7 +29,7 @@ describe("option-manager", () => {
|
||||
});
|
||||
},
|
||||
// eslint-disable-next-line max-len
|
||||
/Using removed Babel 5 option: base.auxiliaryComment - Use `auxiliaryCommentBefore` or `auxiliaryCommentAfter`/,
|
||||
/Using removed Babel 5 option: .auxiliaryComment - Use `auxiliaryCommentBefore` or `auxiliaryCommentAfter`/,
|
||||
);
|
||||
});
|
||||
|
||||
@ -47,7 +47,7 @@ describe("option-manager", () => {
|
||||
describe("source type", function() {
|
||||
it("should set module for .mjs extension", () => {
|
||||
const config = manageOptions({
|
||||
sourceType: "program",
|
||||
sourceType: "script",
|
||||
filename: "foo.mjs",
|
||||
});
|
||||
|
||||
|
||||
@ -259,7 +259,6 @@ export default function(
|
||||
filenameRelative: task.expect.filename,
|
||||
sourceFileName: task.actual.filename,
|
||||
sourceMapTarget: task.expect.filename,
|
||||
suppressDeprecationMessages: true,
|
||||
babelrc: false,
|
||||
sourceMap: !!(task.sourceMappings || task.sourceMap),
|
||||
});
|
||||
|
||||
@ -18,7 +18,7 @@ Installation
|
||||
|
||||
There are several ways to get a copy of @babel/standalone. Pick whichever one you like:
|
||||
|
||||
- Use it via UNPKG: https://unpkg.com/@babel/standalone@6/babel.min.js. This is a simple way to embed it on a webpage without having to do any other setup.
|
||||
- Use it via UNPKG: https://unpkg.com/@babel/standalone/babel.min.js. This is a simple way to embed it on a webpage without having to do any other setup.
|
||||
- Install via Bower: `bower install @babel/standalone`
|
||||
- Install via NPM: `npm install --save @babel/standalone`
|
||||
- Manually grab `babel.js` and/or `babel.min.js` from the [GitHub releases page](https://github.com/Daniel15/babel-standalone/releases). Every release includes these files.
|
||||
|
||||
@ -437,6 +437,7 @@ export default class Tokenizer extends LocationParser {
|
||||
let type = code === charCodes.asterisk ? tt.star : tt.modulo;
|
||||
let width = 1;
|
||||
let next = this.input.charCodeAt(this.state.pos + 1);
|
||||
const exprAllowed = this.state.exprAllowed;
|
||||
|
||||
// Exponentiation operator **
|
||||
if (code === charCodes.asterisk && next === charCodes.asterisk) {
|
||||
@ -445,7 +446,7 @@ export default class Tokenizer extends LocationParser {
|
||||
type = tt.exponent;
|
||||
}
|
||||
|
||||
if (next === charCodes.equalsTo) {
|
||||
if (next === charCodes.equalsTo && !exprAllowed) {
|
||||
width++;
|
||||
type = tt.assign;
|
||||
}
|
||||
|
||||
1
packages/babylon/test/fixtures/flow/anonymous-function-no-parens-types/good_13/actual.js
vendored
Normal file
1
packages/babylon/test/fixtures/flow/anonymous-function-no-parens-types/good_13/actual.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
const x = ():*=>{}
|
||||
152
packages/babylon/test/fixtures/flow/anonymous-function-no-parens-types/good_13/expected.json
vendored
Normal file
152
packages/babylon/test/fixtures/flow/anonymous-function-no-parens-types/good_13/expected.json
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
{
|
||||
"type": "File",
|
||||
"start": 0,
|
||||
"end": 18,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 18
|
||||
}
|
||||
},
|
||||
"program": {
|
||||
"type": "Program",
|
||||
"start": 0,
|
||||
"end": 18,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 18
|
||||
}
|
||||
},
|
||||
"sourceType": "module",
|
||||
"body": [
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"start": 0,
|
||||
"end": 18,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 18
|
||||
}
|
||||
},
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"start": 6,
|
||||
"end": 18,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 6
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 18
|
||||
}
|
||||
},
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start": 6,
|
||||
"end": 7,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 6
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 7
|
||||
},
|
||||
"identifierName": "x"
|
||||
},
|
||||
"name": "x"
|
||||
},
|
||||
"init": {
|
||||
"type": "ArrowFunctionExpression",
|
||||
"start": 10,
|
||||
"end": 18,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 10
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 18
|
||||
}
|
||||
},
|
||||
"predicate": null,
|
||||
"returnType": {
|
||||
"type": "TypeAnnotation",
|
||||
"start": 12,
|
||||
"end": 14,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 12
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 14
|
||||
}
|
||||
},
|
||||
"typeAnnotation": {
|
||||
"type": "ExistsTypeAnnotation",
|
||||
"start": 13,
|
||||
"end": 14,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 13
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 14
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": null,
|
||||
"generator": false,
|
||||
"expression": false,
|
||||
"async": false,
|
||||
"params": [],
|
||||
"body": {
|
||||
"type": "BlockStatement",
|
||||
"start": 16,
|
||||
"end": 18,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 16
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 18
|
||||
}
|
||||
},
|
||||
"body": [],
|
||||
"directives": []
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "const"
|
||||
}
|
||||
],
|
||||
"directives": []
|
||||
}
|
||||
}
|
||||
1
packages/babylon/test/fixtures/flow/classes/good_01/actual.js
vendored
Normal file
1
packages/babylon/test/fixtures/flow/classes/good_01/actual.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
class C { field:*=null }
|
||||
164
packages/babylon/test/fixtures/flow/classes/good_01/expected.json
vendored
Normal file
164
packages/babylon/test/fixtures/flow/classes/good_01/expected.json
vendored
Normal file
@ -0,0 +1,164 @@
|
||||
{
|
||||
"type": "File",
|
||||
"start": 0,
|
||||
"end": 24,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 24
|
||||
}
|
||||
},
|
||||
"program": {
|
||||
"type": "Program",
|
||||
"start": 0,
|
||||
"end": 24,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 24
|
||||
}
|
||||
},
|
||||
"sourceType": "module",
|
||||
"body": [
|
||||
{
|
||||
"type": "ClassDeclaration",
|
||||
"start": 0,
|
||||
"end": 24,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 24
|
||||
}
|
||||
},
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start": 6,
|
||||
"end": 7,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 6
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 7
|
||||
},
|
||||
"identifierName": "C"
|
||||
},
|
||||
"name": "C"
|
||||
},
|
||||
"superClass": null,
|
||||
"body": {
|
||||
"type": "ClassBody",
|
||||
"start": 8,
|
||||
"end": 24,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 8
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 24
|
||||
}
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "ClassProperty",
|
||||
"start": 10,
|
||||
"end": 22,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 10
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 22
|
||||
}
|
||||
},
|
||||
"static": false,
|
||||
"key": {
|
||||
"type": "Identifier",
|
||||
"start": 10,
|
||||
"end": 15,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 10
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 15
|
||||
},
|
||||
"identifierName": "field"
|
||||
},
|
||||
"name": "field"
|
||||
},
|
||||
"computed": false,
|
||||
"variance": null,
|
||||
"typeAnnotation": {
|
||||
"type": "TypeAnnotation",
|
||||
"start": 15,
|
||||
"end": 17,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 15
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 17
|
||||
}
|
||||
},
|
||||
"typeAnnotation": {
|
||||
"type": "ExistsTypeAnnotation",
|
||||
"start": 16,
|
||||
"end": 17,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 16
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 17
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"value": {
|
||||
"type": "NullLiteral",
|
||||
"start": 18,
|
||||
"end": 22,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 18
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 22
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"directives": []
|
||||
}
|
||||
}
|
||||
3
packages/babylon/test/fixtures/flow/classes/good_01/options.json
vendored
Normal file
3
packages/babylon/test/fixtures/flow/classes/good_01/options.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugins": ["flow", "classProperties"]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user