Skip to content

Commit

Permalink
Implement new transform-runtime protocol for runtime package name (#160)
Browse files Browse the repository at this point in the history
* Implement new transform-runtime protocol for runtime package name

* Better error mesage
  • Loading branch information
nicolo-ribaudo committed May 10, 2023
1 parent 8c6d4d7 commit 185c51f
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 31 deletions.
48 changes: 35 additions & 13 deletions packages/babel-helper-define-polyfill-provider/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ function instantiateProvider<Options>(
}
if (!polyfillsNames.has(name)) {
console.warn(
`Internal error in the ${provider.name} provider: ` +
`Internal error in the ${providerName} provider: ` +
`unknown polyfill "${name}".`,
);
}
Expand All @@ -219,7 +219,7 @@ function instantiateProvider<Options>(

if (!debug || !name) return;

if (debugLog().polyfills.has(provider.name)) return;
if (debugLog().polyfills.has(providerName)) return;
debugLog().polyfills.add(name);
debugLog().polyfillsSupport ??= polyfillsSupport;
},
Expand Down Expand Up @@ -247,11 +247,11 @@ function instantiateProvider<Options>(
};

const provider = factory(api, providerOptions, dirname);
const providerName = provider.name || factory.name;

if (typeof provider[methodName] !== "function") {
throw new Error(
`The "${provider.name || factory.name}" provider doesn't ` +
`support the "${method}" polyfilling method.`,
`The "${providerName}" provider doesn't support the "${method}" polyfilling method.`,
);
}

Expand All @@ -267,7 +267,7 @@ function instantiateProvider<Options>(
}

({ include, exclude } = validateIncludeExclude(
provider.name || factory.name,
providerName,
polyfillsNames,
providerOptions.include || [],
providerOptions.exclude || [],
Expand All @@ -278,6 +278,7 @@ function instantiateProvider<Options>(
method,
targets,
provider,
providerName,
callProvider(payload: MetaDescriptor, path: NodePath) {
const utils = getUtils(path);
provider[methodName](payload, utils, path);
Expand All @@ -299,7 +300,7 @@ export default function definePolyfillProvider<Options>(
babelApi,
);

const { debug, method, targets, provider, callProvider } =
const { debug, method, targets, provider, providerName, callProvider } =
instantiateProvider<Options>(
factory,
options,
Expand All @@ -316,16 +317,37 @@ export default function definePolyfillProvider<Options>(
: createVisitor(callProvider);

if (debug && debug !== presetEnvSilentDebugHeader) {
console.log(`${provider.name}: \`DEBUG\` option`);
console.log(`${providerName}: \`DEBUG\` option`);
console.log(`\nUsing targets: ${stringifyTargetsMultiline(targets)}`);
console.log(`\nUsing polyfills with \`${method}\` method:`);
}

const { runtimeName } = provider;

return {
name: "inject-polyfills",
visitor,

pre() {
pre(file) {
if (runtimeName) {
if (
file.get("runtimeHelpersModuleName") &&
file.get("runtimeHelpersModuleName") !== runtimeName
) {
console.warn(
`Two different polyfill providers` +
` (${file.get("runtimeHelpersModuleProvider")}` +
` and ${providerName}) are trying to define two` +
` conflicting @babel/runtime alternatives:` +
` ${file.get("runtimeHelpersModuleName")} and ${runtimeName}.` +
` The second one will be ignored.`,
);
} else {
file.set("runtimeHelpersModuleName", runtimeName);
file.set("runtimeHelpersModuleProvider", providerName);
}
}

debugLog = {
polyfills: new Set(),
polyfillsSupport: undefined,
Expand Down Expand Up @@ -355,22 +377,22 @@ export default function definePolyfillProvider<Options>(
console.log(
method === "entry-global"
? debugLog.found
? `Based on your targets, the ${provider.name} polyfill did not add any polyfill.`
: `The entry point for the ${provider.name} polyfill has not been found.`
: `Based on your code and targets, the ${provider.name} polyfill did not add any polyfill.`,
? `Based on your targets, the ${providerName} polyfill did not add any polyfill.`
: `The entry point for the ${providerName} polyfill has not been found.`
: `Based on your code and targets, the ${providerName} polyfill did not add any polyfill.`,
);

return;
}

if (method === "entry-global") {
console.log(
`The ${provider.name} polyfill entry has been replaced with ` +
`The ${providerName} polyfill entry has been replaced with ` +
`the following polyfills:`,
);
} else {
console.log(
`The ${provider.name} polyfill added the following polyfills:`,
`The ${providerName} polyfill added the following polyfills:`,
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export type Utils = {

export type ProviderResult = {
name: string;
runtimeName?: string;
polyfills?: string[] | { [name: string]: Targets };
filterPolyfills?: (name: string) => boolean;
entryGlobal?: (meta: MetaDescriptor, utils: Utils, path: NodePath) => void;
Expand Down
31 changes: 31 additions & 0 deletions packages/babel-helper-define-polyfill-provider/test/misc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as babel from "@babel/core";
import definePolyfillProvider from "../lib";

function transform(code, objs) {
return babel.transformSync(code, {
configFile: false,
plugins: objs.map(obj => [
definePolyfillProvider(() => ({ usagePure() {}, ...obj })),
{ method: "usage-pure" },
]),
});
}

describe("misc", () => {
it("warns if two different providers provide a @babel/runtime alternative", () => {
const warn = jest.spyOn(console, "warn").mockImplementation(() => {});
try {
transform("code", [
{ name: "provider-1", runtimeName: "@provider-1/babel-runtime" },
{ name: "provider-2", runtimeName: "@provider-2/babel-runtime" },
]);

expect(warn).toHaveBeenCalledTimes(1);
expect(warn.mock.lastCall[0]).toMatchInlineSnapshot(
`"Two different polyfill providers (provider-1 and provider-2) are trying to define two conflicting @babel/runtime alternatives: @provider-1/babel-runtime and @provider-2/babel-runtime. The second one will be ignored."`,
);
} finally {
warn.mockRestore();
}
});
});
17 changes: 11 additions & 6 deletions packages/babel-plugin-polyfill-corejs2/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import defineProvider from "@babel/helper-define-polyfill-provider";
import type { NodePath } from "@babel/traverse";
import { types as t } from "@babel/core";

const BABEL_RUNTIME = "@babel/runtime-corejs2";

const presetEnvCompat = "#__secret_key__@babel/preset-env__compatibility";
const runtimeCompat = "#__secret_key__@babel/runtime__compatibility";

Expand All @@ -22,7 +24,7 @@ type Options = {
entryInjectRegenerator: boolean;
};
"#__secret_key__@babel/runtime__compatibility": void | {
useBabelRuntime: string;
useBabelRuntime: boolean;
runtimeVersion: string;
ext: string;
};
Expand All @@ -34,10 +36,11 @@ export default defineProvider<Options>(function (
[presetEnvCompat]: { entryInjectRegenerator } = {
entryInjectRegenerator: false,
},
[runtimeCompat]: { useBabelRuntime, runtimeVersion, ext = ".js" } = {
useBabelRuntime: "",
runtimeVersion: "",
},
[runtimeCompat]: {
useBabelRuntime = false,
runtimeVersion = "",
ext = ".js",
} = {},
},
) {
const resolve = api.createMetaResolver({
Expand All @@ -55,7 +58,7 @@ export default defineProvider<Options>(function (
);

const coreJSBase = useBabelRuntime
? `${useBabelRuntime}/core-js`
? `${BABEL_RUNTIME}/core-js`
: method === "usage-pure"
? "core-js/library/fn"
: "core-js/modules";
Expand Down Expand Up @@ -94,6 +97,8 @@ export default defineProvider<Options>(function (
return {
name: "corejs2",

runtimeName: BABEL_RUNTIME,

polyfills,

entryGlobal(meta, utils, path) {
Expand Down
12 changes: 8 additions & 4 deletions packages/babel-plugin-polyfill-corejs3/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
coreJSModule,
isCoreJSSource,
coreJSPureHelper,
BABEL_RUNTIME,
} from "./utils";

import defineProvider from "@babel/helper-define-polyfill-provider";
Expand All @@ -30,7 +31,8 @@ type Options = {
proposals?: boolean;
shippedProposals?: boolean;
"#__secret_key__@babel/runtime__compatibility": void | {
useBabelRuntime: string;
useBabelRuntime: boolean;
babelRuntimePath: string;
ext: string;
};
};
Expand Down Expand Up @@ -61,7 +63,7 @@ export default defineProvider<Options>(function (
version = 3,
proposals,
shippedProposals,
[runtimeCompat]: { useBabelRuntime, ext = ".js" } = { useBabelRuntime: "" },
[runtimeCompat]: { useBabelRuntime = false, ext = ".js" } = {},
},
) {
const isWebpack = babel.caller(caller => caller?.name === "babel-loader");
Expand All @@ -77,8 +79,8 @@ export default defineProvider<Options>(function (
function getCoreJSPureBase(useProposalBase) {
return useBabelRuntime
? useProposalBase
? `${useBabelRuntime}/core-js`
: `${useBabelRuntime}/core-js-stable`
? `${BABEL_RUNTIME}/core-js`
: `${BABEL_RUNTIME}/core-js-stable`
: useProposalBase
? "core-js-pure/features"
: "core-js-pure/stable";
Expand Down Expand Up @@ -142,6 +144,8 @@ export default defineProvider<Options>(function (
return {
name: "corejs3",

runtimeName: BABEL_RUNTIME,

polyfills: corejs3Polyfills,

filterPolyfills(name) {
Expand Down
6 changes: 4 additions & 2 deletions packages/babel-plugin-polyfill-corejs3/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { types as t } from "@babel/core";
import corejsEntries from "../core-js-compat/entries.js";

export const BABEL_RUNTIME = "@babel/runtime-corejs3";

export function callMethod(path: any, id: t.Identifier) {
const { object } = path.node;

Expand Down Expand Up @@ -40,10 +42,10 @@ export function coreJSModule(name: string) {

export function coreJSPureHelper(
name: string,
useBabelRuntime: string,
useBabelRuntime: boolean,
ext: string,
) {
return useBabelRuntime
? `${useBabelRuntime}/core-js/${name}${ext}`
? `${BABEL_RUNTIME}/core-js/${name}${ext}`
: `core-js-pure/features/${name}.js`;
}
17 changes: 11 additions & 6 deletions packages/babel-plugin-polyfill-regenerator/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import defineProvider from "@babel/helper-define-polyfill-provider";
import type { PluginPass } from "@babel/core";

const runtimeCompat = "#__secret_key__@babel/runtime__compatibility";

Expand All @@ -18,12 +19,7 @@ export default defineProvider<Options>(({ debug, targets, babel }, options) => {
);
}

const { [runtimeCompat]: { useBabelRuntime } = { useBabelRuntime: "" } } =
options;

const pureName = useBabelRuntime
? `${useBabelRuntime}/regenerator`
: "regenerator-runtime";
const { [runtimeCompat]: { useBabelRuntime = false } = {} } = options;

return {
name: "regenerator",
Expand All @@ -38,6 +34,15 @@ export default defineProvider<Options>(({ debug, targets, babel }, options) => {
},
usagePure(meta, utils, path) {
if (isRegenerator(meta)) {
let pureName = "regenerator-runtime";
if (useBabelRuntime) {
const runtimeName =
((path.hub as any).file as PluginPass).get(
"runtimeHelpersModuleName",
) ?? "@babel/runtime";
pureName = `${runtimeName}/regenerator`;
}

path.replaceWith(
utils.injectDefaultImport(pureName, "regenerator-runtime"),
);
Expand Down

0 comments on commit 185c51f

Please sign in to comment.