diff --git a/packages/babel-core/src/config/files/plugins.ts b/packages/babel-core/src/config/files/plugins.ts index fa707b7aebe1..cf1099134453 100644 --- a/packages/babel-core/src/config/files/plugins.ts +++ b/packages/babel-core/src/config/files/plugins.ts @@ -111,6 +111,22 @@ function* resolveAlternativesHelper( error.message += `\n- Did you accidentally pass a ${oppositeType} as a ${type}?`; } + if (type === "plugin") { + const transformName = standardizedName.replace("-proposal-", "-transform-"); + if (transformName !== standardizedName && !(yield transformName).error) { + error.message += `\n- Did you mean "${transformName}"?`; + } + } + + error.message += `\n +Make sure that all the Babel plugins and presets you are using +are defined as dependencies or devDependencies in your package.json +file. It's possible that the missing plugin is loaded by a preset +you are using that forgot to add the plugin to its dependencies: you +can workaround this problem by explicitly adding the missing package +to your top-level package.json. +`; + throw error; } diff --git a/packages/babel-core/test/fixtures/resolution/throw-proposal-to-transform/node_modules/@babel/plugin-transform-halting-functions/index.js b/packages/babel-core/test/fixtures/resolution/throw-proposal-to-transform/node_modules/@babel/plugin-transform-halting-functions/index.js new file mode 100644 index 000000000000..90cdc52c4182 --- /dev/null +++ b/packages/babel-core/test/fixtures/resolution/throw-proposal-to-transform/node_modules/@babel/plugin-transform-halting-functions/index.js @@ -0,0 +1,3 @@ +module.exports = function () { + return {} +}; diff --git a/packages/babel-core/test/resolution.js b/packages/babel-core/test/resolution.js index 614ed63c6e38..d6f95daa84c0 100644 --- a/packages/babel-core/test/resolution.js +++ b/packages/babel-core/test/resolution.js @@ -466,6 +466,22 @@ describe("addon resolution", function () { const nodeGte12 = parseInt(process.versions.node, 10) >= 12 ? it : it.skip; + nodeGte12( + "should suggest -transform- as an alternative to -proposal-", + function () { + process.chdir("throw-proposal-to-transform"); + + expect(() => { + babel.transformSync("", { + filename: "filename.js", + configFile: false, + plugins: ["@babel/proposal-halting-functions"], + }); + }).toThrow( + /Cannot (?:find|resolve) module '@babel\/plugin-proposal-halting-functions'.*\n- Did you mean "@babel\/plugin-transform-halting-functions"\?/s, + ); + }, + ); nodeGte12("should respect package.json#exports", async function () { process.chdir("pkg-exports");