Skip to content

Commit

Permalink
Merge pull request #915 from embroider-build/disable-heimdall-gatheri…
Browse files Browse the repository at this point in the history
…ng-for-one-shots
  • Loading branch information
rwjblue authored Aug 3, 2021
2 parents 3c72889 + 6db5bc7 commit c9a8f48
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 10 deletions.
1 change: 1 addition & 0 deletions packages/compat/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"debug": "^4.3.2",
"fs-extra": "^9.1.0",
"fs-tree-diff": "^2.0.1",
"heimdalljs": "^0.2.6",
"jsdom": "^16.6.0",
"lodash": "^4.17.21",
"pkg-up": "^3.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/compat/src/build-compat-addon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
tree = new OneShot(tree, originalPackage.name);
}
return tree;
}
Expand Down
56 changes: 47 additions & 9 deletions packages/compat/src/one-shot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,65 @@ import Plugin from 'broccoli-plugin';
import { Node } from 'broccoli-node-api';
import { Builder } from 'broccoli';
import { copySync } from 'fs-extra';
import heimdall from 'heimdalljs';

class NerfHeimdallReparentingBuilder extends Builder {
/*
Replace the code used to track heimdall nodes: https://github.com/broccolijs/broccoli/blob/v3.5.2/lib/builder.ts#L463-L503
This reduces the amount of memory that these one-shot's create by:
- Avoiding creating Heimdall nodes for each broccoli plugin
- Disabling the "re-parenting" process done by Broccoli builder (which ends up creating **double** the heimdall nodes)
*/
setupHeimdall() {}
buildHeimdallTree() {}
}

// 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: Builder;
private didBuild = false;
private builder: NerfHeimdallReparentingBuilder | null;

constructor(originalTree: Node) {
constructor(originalTree: Node, private addonName: string) {
// from broccoli's perspective, we don't depend on any input trees!
super([], {
annotation: `@embroider/compat: ${addonName}`,
persistentOutput: true,
});
this.builder = new Builder(originalTree);

// create a nested builder in order to isolate the specific addon
this.builder = new NerfHeimdallReparentingBuilder(originalTree);
}

async build() {
if (this.didBuild) {
const { builder } = this;

// only build the first time
if (builder === null) {
return;
}
await this.builder.build();
copySync(this.builder.outputPath, this.outputPath, { dereference: true });
await this.builder.cleanup();
this.didBuild = true;
this.builder = null;

// Make a heimdall node so that we know for sure, all nodes created during our
// inner builder can be remove easily
const oneshotCookie = heimdall.start({
name: `@embroider/compat: OneShot (${this.addonName})`,
});
const oneshotHeimdallNode = heimdall.current;

try {
await builder.build();
copySync(builder.outputPath, this.outputPath, { dereference: true });
await builder.cleanup();
} finally {
oneshotCookie.stop();
/*
Remove any of the current node's direct children, this ensures that we do not bloat the
current Broccoli builder's heimdall node graph (e.g. the one that is calling
OneShotPlugin; **not** the one that the OneShotPlugin internally creates).
*/
oneshotHeimdallNode.remove();
}
}
}
3 changes: 3 additions & 0 deletions types/heimdalljs/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare module 'heimdalljs' {
export default any
}

0 comments on commit c9a8f48

Please sign in to comment.