diff --git a/packages/compat/src/build-compat-addon.ts b/packages/compat/src/build-compat-addon.ts index 7305ecaf6..0a623935e 100644 --- a/packages/compat/src/build-compat-addon.ts +++ b/packages/compat/src/build-compat-addon.ts @@ -11,7 +11,7 @@ import EmptyPackageTree from './empty-package-tree'; export default function cachedBuildCompatAddon(originalPackage: Package, v1Cache: V1InstanceCache): Node { let tree = buildCompatAddon(originalPackage, v1Cache); if (!originalPackage.mayRebuild) { - tree = new OneShot(tree, originalPackage.name); + tree = OneShot.create(tree, originalPackage.name); } return tree; } diff --git a/packages/compat/src/one-shot.ts b/packages/compat/src/one-shot.ts index e8ad10fc7..3bc7e178e 100644 --- a/packages/compat/src/one-shot.ts +++ b/packages/compat/src/one-shot.ts @@ -17,12 +17,23 @@ class NerfHeimdallBuilder extends Builder { buildHeimdallTree() {} } +let seen = new WeakMap(); + // Wraps a broccoli tree such that it (and everything it depends on) will only // build a single time. export default class OneShot extends Plugin { private builder: NerfHeimdallBuilder | null; - constructor(originalTree: Node, private addonName: string) { + static create(originalTree: Node, privateAddonName: string) { + let output = seen.get(originalTree); + if (!output) { + output = new this(originalTree, privateAddonName); + seen.set(originalTree, output); + } + return output; + } + + private constructor(originalTree: Node, private addonName: string) { // from broccoli's perspective, we don't depend on any input trees! super([], { annotation: `@embroider/compat: ${addonName}`,