diff --git a/packages/babel-preset-env/src/available-plugins.js b/packages/babel-preset-env/src/available-plugins.ts similarity index 99% rename from packages/babel-preset-env/src/available-plugins.js rename to packages/babel-preset-env/src/available-plugins.ts index d7fb70a939..6fca43d542 100644 --- a/packages/babel-preset-env/src/available-plugins.js +++ b/packages/babel-preset-env/src/available-plugins.ts @@ -1,4 +1,3 @@ -// @flow /* eslint sort-keys: "error" */ import syntaxAsyncGenerators from "@babel/plugin-syntax-async-generators"; diff --git a/packages/babel-preset-env/src/debug.js b/packages/babel-preset-env/src/debug.ts similarity index 84% rename from packages/babel-preset-env/src/debug.js rename to packages/babel-preset-env/src/debug.ts index 3a255d9e0f..7299f62fc2 100644 --- a/packages/babel-preset-env/src/debug.js +++ b/packages/babel-preset-env/src/debug.ts @@ -1,9 +1,6 @@ -// @flow +import { getInclusionReasons } from "@babel/helper-compilation-targets"; -import { - getInclusionReasons, - type Targets, -} from "@babel/helper-compilation-targets"; +import type { Targets } from "@babel/helper-compilation-targets"; // Outputs a message that shows which target(s) caused an item to be included: // transform-foo { "edge":"13", "firefox":"49", "ie":"10" } diff --git a/packages/babel-preset-env/src/filter-items.js b/packages/babel-preset-env/src/filter-items.ts similarity index 98% rename from packages/babel-preset-env/src/filter-items.js rename to packages/babel-preset-env/src/filter-items.ts index 704d72e92c..4189ede7f9 100644 --- a/packages/babel-preset-env/src/filter-items.js +++ b/packages/babel-preset-env/src/filter-items.ts @@ -1,5 +1,3 @@ -// @flow - import { lt } from "semver"; import { minVersions } from "./available-plugins"; diff --git a/packages/babel-preset-env/src/get-option-specific-excludes.js b/packages/babel-preset-env/src/get-option-specific-excludes.ts similarity index 95% rename from packages/babel-preset-env/src/get-option-specific-excludes.js rename to packages/babel-preset-env/src/get-option-specific-excludes.ts index 3adf5dcc77..423d62e5df 100644 --- a/packages/babel-preset-env/src/get-option-specific-excludes.js +++ b/packages/babel-preset-env/src/get-option-specific-excludes.ts @@ -1,5 +1,3 @@ -// @flow - const defaultExcludesForLooseMode = ["transform-typeof-symbol"]; export default function ({ loose }: { loose: boolean }): null | string[] { diff --git a/packages/babel-preset-env/src/index.js b/packages/babel-preset-env/src/index.ts similarity index 93% rename from packages/babel-preset-env/src/index.js rename to packages/babel-preset-env/src/index.ts index 85eb2ff249..86de8f790f 100644 --- a/packages/babel-preset-env/src/index.js +++ b/packages/babel-preset-env/src/index.ts @@ -1,6 +1,5 @@ -//@flow - -import { SemVer, lt } from "semver"; +import { lt } from "semver"; +import type { SemVer } from "semver"; import { logPlugin } from "./debug"; import getOptionSpecificExcludesFor from "./get-option-specific-excludes"; import { removeUnnecessaryItems, removeUnsupportedItems } from "./filter-items"; @@ -27,13 +26,13 @@ import getTargets, { prettifyTargets, filterItems, isRequired, - type Targets, - type InputTargets, } from "@babel/helper-compilation-targets"; +import type { Targets, InputTargets } from "@babel/helper-compilation-targets"; import availablePlugins from "./available-plugins"; import { declare } from "@babel/helper-plugin-utils"; -import typeof ModuleTransformationsType from "./module-transformations"; +type ModuleTransformationsType = + typeof import("./module-transformations").default; import type { BuiltInsOption, ModuleOption } from "./types"; // TODO: Remove in Babel 8 @@ -92,7 +91,7 @@ const getPlugin = (pluginName: string) => { return plugin; }; -export const transformIncludesAndExcludes = (opts: Array): Object => { +export const transformIncludesAndExcludes = (opts: Array): any => { return opts.reduce( (result, opt) => { const target = opt.match(/^(es|es6|es7|esnext|web)\./) @@ -116,14 +115,14 @@ export const getModulesPluginNames = ({ shouldTransformDynamicImport, shouldTransformExportNamespaceFrom, shouldParseTopLevelAwait, -}: {| - modules: ModuleOption, - transformations: ModuleTransformationsType, - shouldTransformESM: boolean, - shouldTransformDynamicImport: boolean, - shouldTransformExportNamespaceFrom: boolean, - shouldParseTopLevelAwait: boolean, -|}) => { +}: { + modules: ModuleOption; + transformations: ModuleTransformationsType; + shouldTransformESM: boolean; + shouldTransformDynamicImport: boolean; + shouldTransformExportNamespaceFrom: boolean; + shouldParseTopLevelAwait: boolean; +}) => { const modulesPluginNames = []; if (modules !== false && transformations[modules]) { if (shouldTransformESM) { @@ -173,15 +172,15 @@ export const getPolyfillPlugins = ({ regenerator, debug, }: { - useBuiltIns: BuiltInsOption, - corejs: typeof SemVer | null | false, - polyfillTargets: Targets, - include: Set, - exclude: Set, - proposals: boolean, - shippedProposals: boolean, - regenerator: boolean, - debug: boolean, + useBuiltIns: BuiltInsOption; + corejs: SemVer | null | false; + polyfillTargets: Targets; + include: Set; + exclude: Set; + proposals: boolean; + shippedProposals: boolean; + regenerator: boolean; + debug: boolean; }) => { const polyfillPlugins = []; if (useBuiltIns === "usage" || useBuiltIns === "entry") { @@ -249,7 +248,7 @@ function getLocalTargets( `); } - return getTargets((optionsTargets: InputTargets), { + return getTargets(optionsTargets as InputTargets, { ignoreBrowserslistConfig, configPath, browserslistEnv, diff --git a/packages/babel-preset-env/src/module-transformations.js b/packages/babel-preset-env/src/module-transformations.ts similarity index 61% rename from packages/babel-preset-env/src/module-transformations.js rename to packages/babel-preset-env/src/module-transformations.ts index 6c9affe6b7..582c1de7a4 100644 --- a/packages/babel-preset-env/src/module-transformations.js +++ b/packages/babel-preset-env/src/module-transformations.ts @@ -1,12 +1,10 @@ -// @flow +type AvailablePlugins = typeof import("./available-plugins").default; -import typeof AvailablePlugins from "./available-plugins"; - -export default ({ +export default { auto: "transform-modules-commonjs", amd: "transform-modules-amd", commonjs: "transform-modules-commonjs", cjs: "transform-modules-commonjs", systemjs: "transform-modules-systemjs", umd: "transform-modules-umd", -}: { [transform: string]: $Keys }); +} as { [transform: string]: keyof AvailablePlugins }; diff --git a/packages/babel-preset-env/src/normalize-options.js b/packages/babel-preset-env/src/normalize-options.ts similarity index 95% rename from packages/babel-preset-env/src/normalize-options.js rename to packages/babel-preset-env/src/normalize-options.ts index a436ddf0ba..955f2bfadd 100644 --- a/packages/babel-preset-env/src/normalize-options.js +++ b/packages/babel-preset-env/src/normalize-options.ts @@ -1,6 +1,6 @@ -// @flow import corejs3Polyfills from "core-js-compat/data.json"; -import { coerce, SemVer } from "semver"; +import { coerce } from "semver"; +import type { SemVer } from "semver"; import corejs2Polyfills from "@babel/compat-data/corejs2-built-ins"; import { plugins as pluginsList } from "./plugins-compat-data"; import moduleTransformations from "./module-transformations"; @@ -22,6 +22,8 @@ import type { PluginListOption, } from "./types"; +declare const PACKAGE_JSON: { name: string; version: string }; + const v = new OptionValidator(PACKAGE_JSON.name); const allPluginsList = Object.keys(pluginsList); @@ -111,9 +113,10 @@ export const checkDuplicateIncludeExcludes = ( ); }; -const normalizeTargets = (targets): $PropertyType => { +const normalizeTargets = (targets): Options["targets"] => { // TODO: Allow to use only query or strings as a targets from next breaking change. if (typeof targets === "string" || Array.isArray(targets)) { + // @ts-expect-error return { browsers: targets }; } return { ...targets }; @@ -150,12 +153,12 @@ export const validateUseBuiltInsOption = ( }; export type NormalizedCorejsOption = { - proposals: boolean, - version: typeof SemVer | null | false, + proposals: boolean; + version: SemVer | null | false; }; export function normalizeCoreJSOption( - corejs?: CorejsOption, + corejs: CorejsOption | undefined | null, useBuiltIns: BuiltInsOption, ): NormalizedCorejsOption { let proposals = false; @@ -249,7 +252,7 @@ export default function normalizeOptions(opts: Options) { opts.ignoreBrowserslistConfig, false, ), - loose: v.validateBooleanOption(TopLevelOptions.loose, opts.loose), + loose: v.validateBooleanOption(TopLevelOptions.loose, opts.loose), modules: validateModulesOption(opts.modules), shippedProposals: v.validateBooleanOption( TopLevelOptions.shippedProposals, diff --git a/packages/babel-preset-env/src/options.js b/packages/babel-preset-env/src/options.ts similarity index 95% rename from packages/babel-preset-env/src/options.js rename to packages/babel-preset-env/src/options.ts index 23460e14d5..715bb8dc6b 100644 --- a/packages/babel-preset-env/src/options.js +++ b/packages/babel-preset-env/src/options.ts @@ -1,5 +1,3 @@ -// @flow - export const TopLevelOptions = { bugfixes: "bugfixes", configPath: "configPath", @@ -16,7 +14,7 @@ export const TopLevelOptions = { targets: "targets", useBuiltIns: "useBuiltIns", browserslistEnv: "browserslistEnv", -}; +} as const; export const ModulesOption = { false: false, @@ -26,10 +24,10 @@ export const ModulesOption = { cjs: "cjs", systemjs: "systemjs", umd: "umd", -}; +} as const; export const UseBuiltInsOption = { false: false, entry: "entry", usage: "usage", -}; +} as const; diff --git a/packages/babel-preset-env/src/plugins-compat-data.js b/packages/babel-preset-env/src/plugins-compat-data.ts similarity index 98% rename from packages/babel-preset-env/src/plugins-compat-data.js rename to packages/babel-preset-env/src/plugins-compat-data.ts index b437c1fe78..c0840eb6c7 100644 --- a/packages/babel-preset-env/src/plugins-compat-data.js +++ b/packages/babel-preset-env/src/plugins-compat-data.ts @@ -1,5 +1,3 @@ -// @flow - import plugins from "@babel/compat-data/plugins"; import bugfixPlugins from "@babel/compat-data/plugin-bugfixes"; import availablePlugins from "./available-plugins"; diff --git a/packages/babel-preset-env/src/polyfills/babel-polyfill.js b/packages/babel-preset-env/src/polyfills/babel-polyfill.ts similarity index 94% rename from packages/babel-preset-env/src/polyfills/babel-polyfill.js rename to packages/babel-preset-env/src/polyfills/babel-polyfill.ts index 832741359d..feb7f2a322 100644 --- a/packages/babel-preset-env/src/polyfills/babel-polyfill.js +++ b/packages/babel-preset-env/src/polyfills/babel-polyfill.ts @@ -1,8 +1,7 @@ -// @flow - import { getImportSource, getRequireSource, isPolyfillSource } from "./utils"; import type { NodePath } from "@babel/traverse"; +import * as t from "@babel/types"; const BABEL_POLYFILL_DEPRECATION = ` \`@babel/polyfill\` is deprecated. Please, use required parts of \`core-js\` @@ -19,7 +18,7 @@ export default function ( return { name: "preset-env/replace-babel-polyfill", visitor: { - ImportDeclaration(path: NodePath) { + ImportDeclaration(path: NodePath) { const src = getImportSource(path); if (usage && isPolyfillSource(src)) { // $FlowIgnore @@ -40,7 +39,7 @@ export default function ( } } }, - Program(path: NodePath) { + Program(path: NodePath) { path.get("body").forEach(bodyPath => { const src = getRequireSource(bodyPath); if (usage && isPolyfillSource(src)) { diff --git a/packages/babel-preset-env/src/polyfills/regenerator.js b/packages/babel-preset-env/src/polyfills/regenerator.ts similarity index 87% rename from packages/babel-preset-env/src/polyfills/regenerator.js rename to packages/babel-preset-env/src/polyfills/regenerator.ts index b49c80a91e..45b23cbb65 100644 --- a/packages/babel-preset-env/src/polyfills/regenerator.js +++ b/packages/babel-preset-env/src/polyfills/regenerator.ts @@ -1,7 +1,5 @@ -// @flow - import { getImportSource, getRequireSource } from "./utils"; -import type { NodePath } from "@babel/traverse"; +import type { Visitor } from "@babel/traverse"; function isRegeneratorSource(source) { return ( @@ -11,14 +9,14 @@ function isRegeneratorSource(source) { } export default function () { - const visitor = { - ImportDeclaration(path: NodePath) { + const visitor: Visitor<{ regeneratorImportExcluded: boolean }> = { + ImportDeclaration(path) { if (isRegeneratorSource(getImportSource(path))) { this.regeneratorImportExcluded = true; path.remove(); } }, - Program(path: NodePath) { + Program(path) { path.get("body").forEach(bodyPath => { if (isRegeneratorSource(getRequireSource(bodyPath))) { this.regeneratorImportExcluded = true; diff --git a/packages/babel-preset-env/src/polyfills/utils.js b/packages/babel-preset-env/src/polyfills/utils.ts similarity index 67% rename from packages/babel-preset-env/src/polyfills/utils.js rename to packages/babel-preset-env/src/polyfills/utils.ts index b0ee9340b4..97012d3a16 100644 --- a/packages/babel-preset-env/src/polyfills/utils.js +++ b/packages/babel-preset-env/src/polyfills/utils.ts @@ -1,24 +1,24 @@ -// @flow - import * as t from "@babel/types"; import type { NodePath } from "@babel/traverse"; -export function getImportSource({ node }: NodePath) { +export function getImportSource({ node }: NodePath) { if (node.specifiers.length === 0) return node.source.value; } export function getRequireSource({ node }: NodePath) { if (!t.isExpressionStatement(node)) return; const { expression } = node; - const isRequire = + if ( t.isCallExpression(expression) && t.isIdentifier(expression.callee) && expression.callee.name === "require" && expression.arguments.length === 1 && - t.isStringLiteral(expression.arguments[0]); - if (isRequire) return expression.arguments[0].value; + t.isStringLiteral(expression.arguments[0]) + ) { + return expression.arguments[0].value; + } } -export function isPolyfillSource(source: ?string): boolean { +export function isPolyfillSource(source?: string | null): boolean { return source === "@babel/polyfill" || source === "core-js"; } diff --git a/packages/babel-preset-env/src/targets-parser.js b/packages/babel-preset-env/src/targets-parser.ts similarity index 89% rename from packages/babel-preset-env/src/targets-parser.js rename to packages/babel-preset-env/src/targets-parser.ts index 3697cb58f2..7e6f41804d 100644 --- a/packages/babel-preset-env/src/targets-parser.js +++ b/packages/babel-preset-env/src/targets-parser.ts @@ -3,5 +3,4 @@ export { default, isBrowsersQueryValid, - semverMin, } from "@babel/helper-compilation-targets"; diff --git a/packages/babel-preset-env/src/types.js b/packages/babel-preset-env/src/types.js deleted file mode 100644 index c963f410c7..0000000000 --- a/packages/babel-preset-env/src/types.js +++ /dev/null @@ -1,52 +0,0 @@ -//@flow - -import { ModulesOption, UseBuiltInsOption } from "./options"; -import type { NormalizedCorejsOption } from "./normalize-options"; -import type { Targets, InputTargets } from "@babel/helper-compilation-targets"; - -// Options -// Use explicit modules to prevent typo errors. -export type ModuleOption = $Values; -export type BuiltInsOption = $Values; - -type CorejsVersion = 2 | 3 | string; - -export type CorejsOption = - | false - | CorejsVersion - | { version: CorejsVersion, proposals: boolean }; - -export type PluginListItem = string | RegExp; -export type PluginListOption = Array; - -export type Options = { - bugfixes: boolean, - configPath: string, - corejs: CorejsOption, - debug: boolean, - exclude: PluginListOption, - forceAllTransforms: boolean, - ignoreBrowserslistConfig: boolean, - include: PluginListOption, - loose: boolean, - modules: ModuleOption, - shippedProposals: boolean, - spec: boolean, - targets: { ...InputTargets, uglify?: boolean, esmodules?: boolean }, - useBuiltIns: BuiltInsOption, - browserslistEnv: string, -}; - -// Babel -export type Plugin = [Object, Object]; - -export type InternalPluginOptions = { - corejs: NormalizedCorejsOption, - include: Set, - exclude: Set, - polyfillTargets: Targets, - debug: boolean, - proposals: boolean, - shippedProposals: boolean, - regenerator: boolean, -}; diff --git a/packages/babel-preset-env/src/types.ts b/packages/babel-preset-env/src/types.ts new file mode 100644 index 0000000000..cdee1f2469 --- /dev/null +++ b/packages/babel-preset-env/src/types.ts @@ -0,0 +1,57 @@ +import { ModulesOption, UseBuiltInsOption } from "./options"; +import type { NormalizedCorejsOption } from "./normalize-options"; +import type { Targets, InputTargets } from "@babel/helper-compilation-targets"; + +// Options +// Use explicit modules to prevent typo errors. +export type ModuleOption = typeof ModulesOption[keyof typeof ModulesOption]; +export type BuiltInsOption = + typeof UseBuiltInsOption[keyof typeof UseBuiltInsOption]; + +type CorejsVersion = 2 | 3 | string; + +export type CorejsOption = + | false + | CorejsVersion + | { + version: CorejsVersion; + proposals: boolean; + }; + +export type PluginListItem = string | RegExp; +export type PluginListOption = Array; + +export type Options = { + bugfixes: boolean; + configPath: string; + corejs: CorejsOption; + debug: boolean; + exclude: PluginListOption; + forceAllTransforms: boolean; + ignoreBrowserslistConfig: boolean; + include: PluginListOption; + loose: boolean; + modules: ModuleOption; + shippedProposals: boolean; + spec: boolean; + targets: { + uglify?: boolean; + esmodules?: boolean; + } & InputTargets; + useBuiltIns: BuiltInsOption; + browserslistEnv: string; +}; + +// Babel +export type Plugin = [any, any]; + +export type InternalPluginOptions = { + corejs: NormalizedCorejsOption; + include: Set; + exclude: Set; + polyfillTargets: Targets; + debug: boolean; + proposals: boolean; + shippedProposals: boolean; + regenerator: boolean; +}; diff --git a/tsconfig.json b/tsconfig.json index e842563ddc..343b582970 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -32,6 +32,7 @@ "./packages/babel-plugin-transform-react-jsx/src/**/*.ts", "./packages/babel-plugin-transform-runtime/src/**/*.ts", "./packages/babel-plugin-transform-typescript/src/**/*.ts", + "./packages/babel-preset-env/src/**/*.ts", "./packages/babel-standalone/src/**/*.ts", "./packages/babel-template/src/**/*.ts", "./packages/babel-traverse/src/**/*.ts", @@ -129,6 +130,9 @@ "@babel/plugin-transform-typescript": [ "./packages/babel-plugin-transform-typescript/src" ], + "@babel/preset-env": [ + "./packages/babel-preset-env/src" + ], "@babel/standalone": [ "./packages/babel-standalone/src" ],