Skip to content

Commit

Permalink
Fix reinstantiation of inherited plugins (#14241)
Browse files Browse the repository at this point in the history
* Add test for 14233

* Fix it
  • Loading branch information
nicolo-ribaudo committed Feb 7, 2022
1 parent 1deccb0 commit 165b735
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 8 deletions.
23 changes: 19 additions & 4 deletions packages/babel-core/src/config/full.ts
Expand Up @@ -37,7 +37,7 @@ type LoadedDescriptor = {
options: {};
dirname: string;
alias: string;
externalDependencies: DeepArray<string>;
externalDependencies: ReadonlyDeepArray<string>;
};

export type { InputOptions } from "./validation/options";
Expand Down Expand Up @@ -319,7 +319,13 @@ const makeDescriptorLoader = <Context, API>(
throw new Error(error);
}

return { value: item, options, dirname, alias, externalDependencies };
return {
value: item,
options,
dirname,
alias,
externalDependencies: freezeDeepArray(externalDependencies),
};
});

const pluginDescriptorLoader = makeDescriptorLoader<
Expand Down Expand Up @@ -397,7 +403,16 @@ const instantiatePlugin = makeWeakCache(function* (
plugin.visitor || {},
]);

externalDependencies.push(inherits.externalDependencies);
if (inherits.externalDependencies.length > 0) {
if (externalDependencies.length === 0) {
externalDependencies = inherits.externalDependencies;
} else {
externalDependencies = freezeDeepArray([
externalDependencies,
inherits.externalDependencies,
]);
}
}
}

return new Plugin(plugin, options, alias, externalDependencies);
Expand Down Expand Up @@ -470,7 +485,7 @@ const instantiatePreset = makeWeakCacheSync(
options: validate("preset", value),
alias,
dirname,
externalDependencies: freezeDeepArray(externalDependencies),
externalDependencies,
};
},
);
Expand Down
7 changes: 3 additions & 4 deletions packages/babel-core/src/config/plugin.ts
@@ -1,5 +1,5 @@
import { finalize } from "./helpers/deep-array";
import type { DeepArray, ReadonlyDeepArray } from "./helpers/deep-array";
import type { ReadonlyDeepArray } from "./helpers/deep-array";
import type { PluginObject } from "./validation/plugins";

export default class Plugin {
Expand All @@ -20,7 +20,7 @@ export default class Plugin {
plugin: PluginObject,
options: {},
key?: string,
externalDependencies: DeepArray<string> = [],
externalDependencies: ReadonlyDeepArray<string> = finalize([]),
) {
this.key = plugin.name || key;

Expand All @@ -32,7 +32,6 @@ export default class Plugin {
this.generatorOverride = plugin.generatorOverride;

this.options = options;

this.externalDependencies = finalize(externalDependencies);
this.externalDependencies = externalDependencies;
}
}
51 changes: 51 additions & 0 deletions packages/babel-core/test/external-dependencies.js
Expand Up @@ -230,4 +230,55 @@ describe("externalDependencies", () => {
).not.toThrow();
});
});

describe("regressions", () => {
describe("#14233", () => {
it("no external dependencies", () => {
const code = `let a = 1`;

function pluginA(api) {
api.cache.never();
return { name: "plugin-a" };
}
function pluginB() {
return { name: "plugin-b", inherits: pluginA };
}

expect(() => {
transform(code, { plugins: [pluginB] });

transform(code, { plugins: [pluginB] });
}).not.toThrow();
});

it("with external dependencies", () => {
const code = `let a = 1`;

let pluginAdep = "./a-foo";

function pluginA(api) {
api.cache.never();
api.addExternalDependency(pluginAdep);
return { name: "plugin-a" };
}
const pluginB = jest.fn(function pluginB(api) {
api.cache.using(() => 0);
api.addExternalDependency("./b-foo");
return { name: "plugin-b", inherits: pluginA };
});

const result1 = transform(code, { plugins: [pluginB] });
pluginAdep = "./a-bar";
const result2 = transform(code, { plugins: [pluginB] });

expect(pluginB).toHaveBeenCalledTimes(1);
expect(new Set(result1.externalDependencies)).toEqual(
new Set(["./a-foo", "./b-foo"]),
);
expect(new Set(result2.externalDependencies)).toEqual(
new Set(["./a-bar", "./b-foo"]),
);
});
});
});
});

0 comments on commit 165b735

Please sign in to comment.