From 8964aac2cb2eef68a0ca112de14ee6da6e88ffe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hua=CC=81ng=20Ju=CC=80nlia=CC=80ng?= Date: Mon, 8 Jul 2019 23:17:17 -0400 Subject: [PATCH 1/4] feat(errors): validate preset when filename is absent Closes #10154 --- packages/babel-core/src/config/full.js | 23 +++++++++++++++---- packages/babel-core/test/config-chain.js | 14 +++++++++++ .../test/fixtures/config-loading/preset4.js | 6 +++++ 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 packages/babel-core/test/fixtures/config-loading/preset4.js diff --git a/packages/babel-core/src/config/full.js b/packages/babel-core/src/config/full.js index 88c65ff882be..8a1a26c0e29e 100644 --- a/packages/babel-core/src/config/full.js +++ b/packages/babel-core/src/config/full.js @@ -278,6 +278,22 @@ const instantiatePlugin = makeWeakCache( }, ); +const validatePreset = ( + preset: PresetInstance, + context: ConfigContext, + descriptor: UnloadedDescriptor, +): void => { + if (!context.filename) { + const { options } = preset; + if (options.test || options.include || options.exclude) { + throw new Error( + `Preset ${descriptor.name || + ""} requires filename, but it was not passed.`.replace(/\s{2}/, " "), + ); + } + } +}; + /** * Generate a config object that will act as the root of a new nested config. */ @@ -285,10 +301,9 @@ const loadPresetDescriptor = ( descriptor: UnloadedDescriptor, context: ConfigContext, ): ConfigChain | null => { - return buildPresetChain( - instantiatePreset(loadDescriptor(descriptor, context)), - context, - ); + const preset = instantiatePreset(loadDescriptor(descriptor, context)); + validatePreset(preset, context, descriptor); + return buildPresetChain(preset, context); }; const instantiatePreset = makeWeakCache( diff --git a/packages/babel-core/test/config-chain.js b/packages/babel-core/test/config-chain.js index 849da38cfc02..84a816eab445 100644 --- a/packages/babel-core/test/config-chain.js +++ b/packages/babel-core/test/config-chain.js @@ -1049,5 +1049,19 @@ describe("buildConfigChain", function() { loadOptions({ filename, cwd: path.dirname(filename) }), ).toThrow(/Error while parsing JSON - /); }); + + it("should throw when `test` presents but `filename` is not passed", () => { + expect(() => loadOptions({ test: /\.ts$/, plugins: [] })).toThrow( + /Configuration contains string\/RegExp pattern/, + ); + }); + + it("should throw when `preset` requires `filename` but it was not passed", () => { + expect(() => { + loadOptions({ + presets: [require("./fixtures/config-loading/preset4")], + }); + }).toThrow(/Preset requires filename/); + }); }); }); diff --git a/packages/babel-core/test/fixtures/config-loading/preset4.js b/packages/babel-core/test/fixtures/config-loading/preset4.js new file mode 100644 index 000000000000..1698ff05edd1 --- /dev/null +++ b/packages/babel-core/test/fixtures/config-loading/preset4.js @@ -0,0 +1,6 @@ +module.exports = function() { + return { + test: /\.ts$/, + plugins: [] + } +}; From 8fa4131721732af3f0e642badea73974b7dfe0c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hua=CC=81ng=20Ju=CC=80nlia=CC=80ng?= Date: Tue, 9 Jul 2019 18:30:28 -0400 Subject: [PATCH 2/4] fix: test overrides for filename compulsory --- packages/babel-core/src/config/full.js | 21 +++++++++++++++---- packages/babel-core/test/config-chain.js | 8 +++++++ .../test/fixtures/config-loading/preset5.js | 8 +++++++ 3 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 packages/babel-core/test/fixtures/config-loading/preset5.js diff --git a/packages/babel-core/src/config/full.js b/packages/babel-core/src/config/full.js index 8a1a26c0e29e..eba908c2566e 100644 --- a/packages/babel-core/src/config/full.js +++ b/packages/babel-core/src/config/full.js @@ -18,6 +18,7 @@ import { validatePluginObject } from "./validation/plugins"; import makeAPI from "./helpers/config-api"; import loadPrivatePartialConfig from "./partial"; +import type { ValidatedOptions } from "./validation/options"; type LoadedDescriptor = { value: {}, @@ -278,6 +279,18 @@ const instantiatePlugin = makeWeakCache( }, ); +const validateIfOptionNeedsFilename = ( + options: ValidatedOptions, + descriptor: UnloadedDescriptor, +): void => { + if (options.test || options.include || options.exclude) { + throw new Error( + `Preset ${descriptor.name || + ""} requires filename, but it was not passed.`.replace(/\s{2}/, " "), + ); + } +}; + const validatePreset = ( preset: PresetInstance, context: ConfigContext, @@ -285,10 +298,10 @@ const validatePreset = ( ): void => { if (!context.filename) { const { options } = preset; - if (options.test || options.include || options.exclude) { - throw new Error( - `Preset ${descriptor.name || - ""} requires filename, but it was not passed.`.replace(/\s{2}/, " "), + validateIfOptionNeedsFilename(options, descriptor); + if (options.overrides) { + options.overrides.forEach(overrideOptions => + validateIfOptionNeedsFilename(overrideOptions, descriptor), ); } } diff --git a/packages/babel-core/test/config-chain.js b/packages/babel-core/test/config-chain.js index 84a816eab445..7aacbe62d1e9 100644 --- a/packages/babel-core/test/config-chain.js +++ b/packages/babel-core/test/config-chain.js @@ -1063,5 +1063,13 @@ describe("buildConfigChain", function() { }); }).toThrow(/Preset requires filename/); }); + + it("should throw when `preset.overrides` requires `filename` but it was not passed", () => { + expect(() => { + loadOptions({ + presets: [require("./fixtures/config-loading/preset5")], + }); + }).toThrow(/Preset requires filename/); + }); }); }); diff --git a/packages/babel-core/test/fixtures/config-loading/preset5.js b/packages/babel-core/test/fixtures/config-loading/preset5.js new file mode 100644 index 000000000000..65ecb47f93c8 --- /dev/null +++ b/packages/babel-core/test/fixtures/config-loading/preset5.js @@ -0,0 +1,8 @@ +module.exports = function() { + return { + overrides: [{ + test: /\.ts$/, + plugins: [] + }] + } +}; From 0b90ef2e1a2dd091c8faab59ab36fadf8143c69e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hua=CC=81ng=20Ju=CC=80nlia=CC=80ng?= Date: Tue, 9 Jul 2019 19:04:45 -0400 Subject: [PATCH 3/4] docs: rewrite validate error message per https://github.com/babel/babel/pull/10181#discussion_r301607986 --- packages/babel-core/src/config/full.js | 13 +++++++++++-- packages/babel-core/test/config-chain.js | 4 ++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/babel-core/src/config/full.js b/packages/babel-core/src/config/full.js index eba908c2566e..5ba198d91d17 100644 --- a/packages/babel-core/src/config/full.js +++ b/packages/babel-core/src/config/full.js @@ -284,9 +284,18 @@ const validateIfOptionNeedsFilename = ( descriptor: UnloadedDescriptor, ): void => { if (options.test || options.include || options.exclude) { + const formattedPresetName = descriptor.name + ? `"${descriptor.name}"` + : "/* your preset */"; throw new Error( - `Preset ${descriptor.name || - ""} requires filename, but it was not passed.`.replace(/\s{2}/, " "), + [ + `Preset ${formattedPresetName} requires a filename be set.`, + `For example, if you are calling Babel directly`, + `\`\`\``, + `babel.transform(code, { filename: 'file.js', presets: [${formattedPresetName}] });`, + `\`\`\``, + `See https://babeljs.io/docs/en/options#filename for more information.`, + ].join("\n"), ); } }; diff --git a/packages/babel-core/test/config-chain.js b/packages/babel-core/test/config-chain.js index 7aacbe62d1e9..32ee13867568 100644 --- a/packages/babel-core/test/config-chain.js +++ b/packages/babel-core/test/config-chain.js @@ -1061,7 +1061,7 @@ describe("buildConfigChain", function() { loadOptions({ presets: [require("./fixtures/config-loading/preset4")], }); - }).toThrow(/Preset requires filename/); + }).toThrow(/Preset \/\* your preset \*\/ requires a filename/); }); it("should throw when `preset.overrides` requires `filename` but it was not passed", () => { @@ -1069,7 +1069,7 @@ describe("buildConfigChain", function() { loadOptions({ presets: [require("./fixtures/config-loading/preset5")], }); - }).toThrow(/Preset requires filename/); + }).toThrow(/Preset \/\* your preset \*\/ requires a filename/); }); }); }); From 4597db5efb625664731f057525a2d657f9cf7264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Thu, 5 Sep 2019 12:46:27 -0400 Subject: [PATCH 4/4] polish error message --- packages/babel-core/src/config/full.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/babel-core/src/config/full.js b/packages/babel-core/src/config/full.js index 5ba198d91d17..d38aec4ba698 100644 --- a/packages/babel-core/src/config/full.js +++ b/packages/babel-core/src/config/full.js @@ -289,10 +289,9 @@ const validateIfOptionNeedsFilename = ( : "/* your preset */"; throw new Error( [ - `Preset ${formattedPresetName} requires a filename be set.`, - `For example, if you are calling Babel directly`, + `Preset ${formattedPresetName} requires a filename to be set when babel is called directly,`, `\`\`\``, - `babel.transform(code, { filename: 'file.js', presets: [${formattedPresetName}] });`, + `babel.transform(code, { filename: 'file.ts', presets: [${formattedPresetName}] });`, `\`\`\``, `See https://babeljs.io/docs/en/options#filename for more information.`, ].join("\n"),