From fa5a40c8d5eb97f76c6574804bfe37028f3e9e7f Mon Sep 17 00:00:00 2001 From: "David J. Hamilton" Date: Wed, 2 Oct 2019 07:45:03 -0700 Subject: [PATCH] assertNoDuplicates throw with more context (#10419) When users see errors like ``` Duplicate plugin/preset detected. If you'd like to use two separate instances of a plugin, they need separate names, e.g. plugins: [ ['some-plugin', {}], ['some-plugin', {}, 'some unique name'], ] ``` It can be difficult to determine the source of the conflict, especially in a larger build system. This commit outputs what is known about the plugins that actually conflict, which can be helpful for users to determine the root cause of the conflict. Partially addresses #9778 --- .../babel-core/src/config/config-descriptors.js | 4 ++++ packages/babel-core/test/option-manager.js | 13 +++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/babel-core/src/config/config-descriptors.js b/packages/babel-core/src/config/config-descriptors.js index e17cca93c680..d9218a87c020 100644 --- a/packages/babel-core/src/config/config-descriptors.js +++ b/packages/babel-core/src/config/config-descriptors.js @@ -345,6 +345,7 @@ function assertNoDuplicates(items: Array): void { } if (nameMap.has(item.name)) { + const conflicts = items.filter(i => i.value === item.value); throw new Error( [ `Duplicate plugin/preset detected.`, @@ -355,6 +356,9 @@ function assertNoDuplicates(items: Array): void { ` ['some-plugin', {}],`, ` ['some-plugin', {}, 'some unique name'],`, ` ]`, + ``, + `Duplicates detected are:`, + `${JSON.stringify(conflicts, null, 2)}`, ].join("\n"), ); } diff --git a/packages/babel-core/test/option-manager.js b/packages/babel-core/test/option-manager.js index 4a6301ab4777..8839f1178c3a 100644 --- a/packages/babel-core/test/option-manager.js +++ b/packages/babel-core/test/option-manager.js @@ -27,14 +27,19 @@ describe("option-manager", () => { return { plugin, calls }; } - it("should throw if a plugin is repeated", () => { - const { calls, plugin } = makePlugin(); + it("should throw if a plugin is repeated, with information about the repeated plugin", () => { + const { calls, plugin } = makePlugin("my-plugin"); expect(() => { loadOptions({ - plugins: [plugin, plugin], + plugins: [ + [plugin, undefined, "my-plugin"], + [plugin, undefined, "my-plugin"], + ], }); - }).toThrow(/Duplicate plugin\/preset detected/); + }).toThrow( + /Duplicate plugin\/preset detected.*Duplicates detected are.*my-plugin.*my-plugin/ms, + ); expect(calls).toEqual([]); });