From afe0304b29e6a5e2a406c669bf2cd277de97cc92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Fri, 16 Oct 2020 00:15:45 +0200 Subject: [PATCH] Pass "targets" to plugins and presets --- .../src/config/files/configuration.js | 4 +-- packages/babel-core/src/config/full.js | 24 ++++++++++---- .../src/config/helpers/config-api.js | 33 ++++++++++++++++--- .../fixtures/plugins/targets/plugin/input.js | 1 + .../plugins/targets/plugin/options.json | 4 +++ .../fixtures/plugins/targets/plugin/output.js | 2 ++ .../fixtures/plugins/targets/plugin/plugin.js | 14 ++++++++ .../fixtures/plugins/targets/preset/input.js | 1 + .../plugins/targets/preset/options.json | 4 +++ .../fixtures/plugins/targets/preset/output.js | 2 ++ .../fixtures/plugins/targets/preset/preset.js | 18 ++++++++++ 11 files changed, 95 insertions(+), 12 deletions(-) create mode 100644 packages/babel-core/test/fixtures/plugins/targets/plugin/input.js create mode 100644 packages/babel-core/test/fixtures/plugins/targets/plugin/options.json create mode 100644 packages/babel-core/test/fixtures/plugins/targets/plugin/output.js create mode 100644 packages/babel-core/test/fixtures/plugins/targets/plugin/plugin.js create mode 100644 packages/babel-core/test/fixtures/plugins/targets/preset/input.js create mode 100644 packages/babel-core/test/fixtures/plugins/targets/preset/options.json create mode 100644 packages/babel-core/test/fixtures/plugins/targets/preset/output.js create mode 100644 packages/babel-core/test/fixtures/plugins/targets/preset/preset.js diff --git a/packages/babel-core/src/config/files/configuration.js b/packages/babel-core/src/config/files/configuration.js index 3107786cf3d8..9ef83442339c 100644 --- a/packages/babel-core/src/config/files/configuration.js +++ b/packages/babel-core/src/config/files/configuration.js @@ -9,7 +9,7 @@ import { makeWeakCacheSync, type CacheConfigurator, } from "../caching"; -import makeAPI, { type PluginAPI } from "../helpers/config-api"; +import { makeConfigAPI, type ConfigAPI } from "../helpers/config-api"; import { makeStaticFileCache } from "./utils"; import loadCjsOrMjsDefault from "./module-types"; import pathPatternToRegex from "../pattern-to-regex"; @@ -204,7 +204,7 @@ const readConfigJS = makeStrongCache(function* readConfigJS( let assertCache = false; if (typeof options === "function") { yield* []; // if we want to make it possible to use async configs - options = ((options: any): (api: PluginAPI) => {})(makeAPI(cache)); + options = ((options: any): (api: ConfigAPI) => {})(makeConfigAPI(cache)); assertCache = true; } diff --git a/packages/babel-core/src/config/full.js b/packages/babel-core/src/config/full.js index 75fbe293c7c9..fff0468f4366 100644 --- a/packages/babel-core/src/config/full.js +++ b/packages/babel-core/src/config/full.js @@ -14,6 +14,7 @@ import { type PresetInstance, } from "./config-chain"; import type { UnloadedDescriptor } from "./config-descriptors"; +import type { Targets } from "@babel/helper-compilation-targets"; import traverse from "@babel/traverse"; import { makeWeakCache, @@ -27,7 +28,7 @@ import { type PluginItem, } from "./validation/options"; import { validatePluginObject } from "./validation/plugins"; -import makeAPI from "./helpers/config-api"; +import { makePluginAPI } from "./helpers/config-api"; import loadPrivatePartialConfig from "./partial"; import type { ValidatedOptions } from "./validation/options"; @@ -39,6 +40,11 @@ type LoadedDescriptor = { alias: string, }; +type PluginContext = { + ...ConfigContext, + targets: Targets, +}; + export type { InputOptions } from "./validation/options"; export type ResolvedConfig = { @@ -55,6 +61,7 @@ export type PluginPasses = Array; type SimpleContext = { envName: string, caller: CallerMetadata | void, + targets: Targets, }; export default gensync<[any], ResolvedConfig | null>(function* loadFullConfig( @@ -78,6 +85,11 @@ export default gensync<[any], ResolvedConfig | null>(function* loadFullConfig( throw new Error("Assertion failure - plugins and presets exist"); } + const pluginContext: PluginContext = { + ...context, + targets: options.targets, + }; + const toDescriptor = (item: PluginItem) => { const desc = getItemDescriptor(item); if (!desc) { @@ -112,12 +124,12 @@ export default gensync<[any], ResolvedConfig | null>(function* loadFullConfig( // in the previous pass. if (descriptor.ownPass) { presets.push({ - preset: yield* loadPresetDescriptor(descriptor, context), + preset: yield* loadPresetDescriptor(descriptor, pluginContext), pass: [], }); } else { presets.unshift({ - preset: yield* loadPresetDescriptor(descriptor, context), + preset: yield* loadPresetDescriptor(descriptor, pluginContext), pass: pluginDescriptorsPass, }); } @@ -172,7 +184,7 @@ export default gensync<[any], ResolvedConfig | null>(function* loadFullConfig( const descriptor: UnloadedDescriptor = descs[i]; if (descriptor.options !== false) { try { - pass.push(yield* loadPluginDescriptor(descriptor, context)); + pass.push(yield* loadPluginDescriptor(descriptor, pluginContext)); } catch (e) { if (e.code === "BABEL_UNKNOWN_PLUGIN_PROPERTY") { // print special message for `plugins: ["@babel/foo", { foo: "option" }]` @@ -230,7 +242,7 @@ const loadDescriptor = makeWeakCache(function* ( if (typeof value === "function") { const api = { ...context, - ...makeAPI(cache), + ...makePluginAPI(cache), }; try { item = value(api, options, dirname); @@ -368,7 +380,7 @@ const validatePreset = ( */ function* loadPresetDescriptor( descriptor: UnloadedDescriptor, - context: ConfigContext, + context: PluginContext, ): Handler { const preset = instantiatePreset(yield* loadDescriptor(descriptor, context)); validatePreset(preset, context, descriptor); diff --git a/packages/babel-core/src/config/helpers/config-api.js b/packages/babel-core/src/config/helpers/config-api.js index fea73139af68..70d793995d1a 100644 --- a/packages/babel-core/src/config/helpers/config-api.js +++ b/packages/babel-core/src/config/helpers/config-api.js @@ -1,6 +1,8 @@ // @flow import semver from "semver"; +import type { Targets } from "@babel/helper-compilation-targets"; + import { version as coreVersion } from "../../"; import { assertSimpleType, @@ -20,7 +22,9 @@ type EnvFunction = { type CallerFactory = ((CallerMetadata | void) => mixed) => SimpleType; -export type PluginAPI = {| +type TargetsFunction = () => Targets; + +export type ConfigAPI = {| version: string, cache: SimpleCacheConfigurator, env: EnvFunction, @@ -29,9 +33,14 @@ export type PluginAPI = {| caller?: CallerFactory, |}; -export default function makeAPI( - cache: CacheConfigurator<{ envName: string, caller: CallerMetadata | void }>, -): PluginAPI { +export type PluginAPI = {| + ...ConfigAPI, + targets: TargetsFunction, +|}; + +export function makeConfigAPI< + SideChannel: { envName: string, caller: CallerMetadata | void }, +>(cache: CacheConfigurator): ConfigAPI { const env: any = value => cache.using(data => { if (typeof value === "undefined") return data.envName; @@ -61,6 +70,22 @@ export default function makeAPI( }; } +export function makePluginAPI( + cache: CacheConfigurator<{ + envName: string, + caller: CallerMetadata | void, + targets: Targets, + }>, +): PluginAPI { + const targets = () => + // We are using JSON.parse/JSON.stringify because it's only possible to cache + // primitive values. We can safely stringify the targets object because it + // only contains strings as its properties. + // Please make the Record and Tuple proposal happen! + JSON.parse(cache.using(data => JSON.stringify(data.targets))); + return { ...makeConfigAPI(cache), targets }; +} + function assertVersion(range: string | number): void { if (typeof range === "number") { if (!Number.isInteger(range)) { diff --git a/packages/babel-core/test/fixtures/plugins/targets/plugin/input.js b/packages/babel-core/test/fixtures/plugins/targets/plugin/input.js new file mode 100644 index 000000000000..092bc2b04126 --- /dev/null +++ b/packages/babel-core/test/fixtures/plugins/targets/plugin/input.js @@ -0,0 +1 @@ +; diff --git a/packages/babel-core/test/fixtures/plugins/targets/plugin/options.json b/packages/babel-core/test/fixtures/plugins/targets/plugin/options.json new file mode 100644 index 000000000000..ca5100967dc3 --- /dev/null +++ b/packages/babel-core/test/fixtures/plugins/targets/plugin/options.json @@ -0,0 +1,4 @@ +{ + "targets": ["firefox 64", "node 8"], + "plugins": ["./plugin"] +} diff --git a/packages/babel-core/test/fixtures/plugins/targets/plugin/output.js b/packages/babel-core/test/fixtures/plugins/targets/plugin/output.js new file mode 100644 index 000000000000..4ae652ed9fa8 --- /dev/null +++ b/packages/babel-core/test/fixtures/plugins/targets/plugin/output.js @@ -0,0 +1,2 @@ +; +"plugin: {\"firefox\":\"64.0.0\",\"node\":\"8.17.0\"}" diff --git a/packages/babel-core/test/fixtures/plugins/targets/plugin/plugin.js b/packages/babel-core/test/fixtures/plugins/targets/plugin/plugin.js new file mode 100644 index 000000000000..b268497cd97e --- /dev/null +++ b/packages/babel-core/test/fixtures/plugins/targets/plugin/plugin.js @@ -0,0 +1,14 @@ +module.exports = function (api) { + const { types: t } = api; + + const targets = api.targets(); + + return { + visitor: { + Program(path) { + const output = t.stringLiteral(`plugin: ${JSON.stringify(targets)}`); + path.pushContainer("body", output); + }, + }, + }; +}; diff --git a/packages/babel-core/test/fixtures/plugins/targets/preset/input.js b/packages/babel-core/test/fixtures/plugins/targets/preset/input.js new file mode 100644 index 000000000000..092bc2b04126 --- /dev/null +++ b/packages/babel-core/test/fixtures/plugins/targets/preset/input.js @@ -0,0 +1 @@ +; diff --git a/packages/babel-core/test/fixtures/plugins/targets/preset/options.json b/packages/babel-core/test/fixtures/plugins/targets/preset/options.json new file mode 100644 index 000000000000..2e86914c87e1 --- /dev/null +++ b/packages/babel-core/test/fixtures/plugins/targets/preset/options.json @@ -0,0 +1,4 @@ +{ + "targets": ["firefox 64", "node 8"], + "presets": ["./preset"] +} diff --git a/packages/babel-core/test/fixtures/plugins/targets/preset/output.js b/packages/babel-core/test/fixtures/plugins/targets/preset/output.js new file mode 100644 index 000000000000..570eb08d2ee3 --- /dev/null +++ b/packages/babel-core/test/fixtures/plugins/targets/preset/output.js @@ -0,0 +1,2 @@ +; +"preset: {\"firefox\":\"64.0.0\",\"node\":\"8.17.0\"}" diff --git a/packages/babel-core/test/fixtures/plugins/targets/preset/preset.js b/packages/babel-core/test/fixtures/plugins/targets/preset/preset.js new file mode 100644 index 000000000000..b35f4d5fa94e --- /dev/null +++ b/packages/babel-core/test/fixtures/plugins/targets/preset/preset.js @@ -0,0 +1,18 @@ +module.exports = function (api) { + const targets = api.targets(); + + return { + plugins: [plugin], + }; + + function plugin({ types: t }) { + return { + visitor: { + Program(path) { + const output = t.stringLiteral(`preset: ${JSON.stringify(targets)}`); + path.pushContainer("body", output); + }, + }, + }; + } +};