# The Broccoli Plugin Base Class [![Build Status](https://travis-ci.org/broccolijs/broccoli-plugin.svg?branch=master)](https://travis-ci.org/broccolijs/broccoli-plugin) [![Build status](https://ci.appveyor.com/api/projects/status/k4tk8b99m1e58ftd?svg=true)](https://ci.appveyor.com/project/joliss/broccoli-plugin) ## Example Usage ```js var Plugin = require('broccoli-plugin'); var path = require('path'); // Create a subclass MyPlugin derived from Plugin MyPlugin.prototype = Object.create(Plugin.prototype); MyPlugin.prototype.constructor = MyPlugin; function MyPlugin(inputNodes, options) { options = options || {}; Plugin.call(this, inputNodes, { annotation: options.annotation }); this.options = options; } MyPlugin.prototype.build = function() { // Read files from this.inputPaths, and write files to this.outputPath. // Silly example: // Read 'foo.txt' from the third input node var inputBuffer = fs.readFileSync(path.join(this.inputPaths[2], 'foo.txt')); var outputBuffer = someCompiler(inputBuffer); // Write to 'bar.txt' in this node's output fs.writeFileSync(path.join(this.outputPath, 'bar.txt'), outputBuffer); }; ``` ## Reference ### `new Plugin(inputNodes, options)` Call this base class constructor from your subclass constructor. * `inputNodes`: An array of node objects that this plugin will read from. Nodes are usually other plugin instances; they were formerly known as "trees". * `options` * `name`: The name of this plugin class. Defaults to `this.constructor.name`. * `annotation`: A descriptive annotation. Useful for debugging, to tell multiple instances of the same plugin apart. * `persistentOutput`: If true, the output directory is not automatically emptied between builds. * `needsCache` : If `true`, a cache directory is created automatically and the path is set at `cachePath`. If `false`, a cache directory is not created and `this.cachePath` is `undefined`. Defaults to `true`. ### `Plugin.prototype.build()` Override this method in your subclass. It will be called on each (re-)build. This function will typically access the following read-only properties: * `this.inputPaths`: An array of paths on disk corresponding to each node in `inputNodes`. Your plugin will read files from these paths. * `this.outputPath`: The path on disk corresponding to this plugin instance (this node). Your plugin will write files to this path. This directory is emptied by Broccoli before each build, unless the `persistentOutput` options is true. * `this.cachePath`: The path on disk to an auxiliary cache directory. Use this to store files that you want preserved between builds. This directory will only be deleted when Broccoli exits. If a cache directory is not needed, set `needsCache` to `false` when calling `broccoli-plugin` constructor. All paths stay the same between builds. To perform asynchronous work, return a promise. The promise's eventual value is ignored (typically `null`). To report a compile error, `throw` it or return a rejected promise. Also see section "Error Objects" below. ### `Plugin.prototype.getCallbackObject()` Advanced usage only. Return the object on which Broccoli will call `obj.build()`. Called once after instantiation. By default, returns `this`. Plugins do not usually need to override this, but it can be useful for base classes that other plugins in turn derive from, such as [broccoli-caching-writer](https://github.com/ember-cli/broccoli-caching-writer). For example, to intercept `.build()` calls, you might `return { build: this.buildWrapper.bind(this) }`. Or, to hand off the plugin implementation to a completely separate object: `return new MyPluginWorker(this.inputPaths, this.outputPath, this.cachePath)`, where `MyPluginWorker` provides a `.build` method. ### Error Objects To help with displaying clear error messages for build errors, error objects may have the following optional properties in addition to the standard `message` property: * `file`: Path of the file in which the error occurred, relative to one of the `inputPaths` directories * `treeDir`: The path that `file` is relative to. Must be an element of `this.inputPaths`. (The name `treeDir` is for historical reasons.) * `line`: Line in which the error occurred (one-indexed) * `column`: Column in which the error occurred (zero-indexed)