Broccoli Bridge

1.0.0 · maintenance · verified Sun Apr 19

The `broccoli-bridge` package, currently at version 1.0.0, provides a specific utility for managing dependencies between Broccoli build system nodes. Its primary function is to allow developers to define dependencies between Broccoli plugins (`nodes`) even when those nodes are instantiated in different parts of an application's codebase or at different times, thus addressing potential circular dependency issues or inconvenient instantiation order. It achieves this by offering `placeholderFor(name)` to create a temporary node and `fulfill(name, node)` to later link that placeholder to an actual Broccoli node. This enables a more flexible composition of complex Broccoli build pipelines. The package has not seen a new major release, remaining at 1.0.0. A key architectural note is its reliance on internal details of the Broccoli `Plugin` API, meaning its stability is inherently tied to the evolution of the core Broccoli project and it carries a risk of breaking changes if Broccoli's internals change.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates how to use `broccoli-bridge` to manage dependencies between Broccoli nodes, allowing for flexible instantiation order by using named placeholders that are later fulfilled.

class MockBroccoliNode {
  constructor(name) {
    this.name = name;
    this.inputPaths = []; // Mock required property for some Broccoli contexts
    this.outputPath = `/tmp/broccoli-${name}`;
  }
}

// Mock Broccoli Plugin classes for demonstration
class PluginA {
  constructor(inputNodes) {
    this.inputNodes = inputNodes;
    this.name = 'PluginA_Node';
    console.log('PluginA instantiated with inputs:', inputNodes.map(n => n.name || 'placeholder'));
  }
  // In a real scenario, PluginA would implement a `build` method.
}

class PluginB {
  constructor(inputNodes) {
    this.inputNodes = inputNodes;
    this.name = 'PluginB_Node';
    console.log('PluginB instantiated with inputs:', inputNodes.map(n => n.name || 'unknown'));
  }
  // In a real scenario, PluginB would implement a `build` method.
}

const BroccoliBridge = require('broccoli-bridge');

// Stash your bridge instance somewhere central for later access
let bridge = new BroccoliBridge();
console.log('BroccoliBridge instance created.\n');

// Create your `PluginA` instance using a placeholder for PluginB's output
const inputOne = new MockBroccoliNode('InputOne');
const placeholderForB = bridge.placeholderFor('plugin-b');
console.log('Placeholder for "plugin-b" created.');

let a = new PluginA([
  inputOne,
  placeholderForB // PluginA depends on the future output of 'plugin-b'
]);
console.log('PluginA created, its second input is currently a placeholder.\n');

// Instantiate PluginB and fulfill the placeholder with its actual instance
const inputTwo = new MockBroccoliNode('InputTwo');
const inputThree = new MockBroccoliNode('InputThree');
let b = new PluginB([inputTwo, inputThree]);
console.log('PluginB created with its own inputs.');

bridge.fulfill('plugin-b', b);
console.log('Placeholder "plugin-b" fulfilled with the actual PluginB instance.\n');

// At this point, if a Broccoli build process were to start,
// PluginA would correctly receive the output of PluginB
// via the fulfilled placeholder. The conceptual dependency is resolved.
console.log('During a Broccoli build, PluginA will effectively receive the node named: ' + b.name + ' as its second input.');
console.log('The order of instantiation for PluginA and PluginB did not matter thanks to broccoli-bridge.');

view raw JSON →