What is broccoli-filter?
The broccoli-filter package is a base class for Broccoli plugins that map input files to output files. It is used to create plugins that process files in a Broccoli build pipeline, such as transpiling, minifying, or compiling files.
What are broccoli-filter's main functionalities?
File Transformation
This code demonstrates how to create a custom Broccoli filter that transforms JavaScript files by replacing all instances of 'console.log' with 'console.debug'. The 'processString' method is where the transformation logic is implemented.
const Filter = require('broccoli-filter');
class MyFilter extends Filter {
constructor(inputNode) {
super(inputNode);
}
get extensions() {
return ['js'];
}
get targetExtension() {
return 'js';
}
processString(content, relativePath) {
// Perform some transformation on the content
return content.replace(/console\.log/g, 'console.debug');
}
}
module.exports = MyFilter;
Handling Multiple File Types
This code demonstrates how to create a Broccoli filter that processes multiple file types (JavaScript and CSS) and outputs them with a '.txt' extension. The 'processString' method adds a comment at the beginning of each file.
const Filter = require('broccoli-filter');
class MultiTypeFilter extends Filter {
constructor(inputNode) {
super(inputNode);
}
get extensions() {
return ['js', 'css'];
}
get targetExtension() {
return 'txt';
}
processString(content, relativePath) {
// Perform some transformation on the content
return `/* Processed File */\n${content}`;
}
}
module.exports = MultiTypeFilter;
Other packages similar to broccoli-filter
broccoli-plugin
broccoli-plugin is a base class for Broccoli plugins that provides a more general-purpose API compared to broccoli-filter. While broccoli-filter is specifically designed for file transformation, broccoli-plugin can be used to create a wider range of plugins, including those that generate new files or perform complex build tasks.
gulp
Gulp is a toolkit for automating painful or time-consuming tasks in your development workflow. It uses a code-over-configuration approach and is highly flexible, allowing for a wide range of file transformations and build tasks. Unlike broccoli-filter, which is specific to the Broccoli build system, Gulp can be used independently or with other build systems.
webpack
Webpack is a module bundler that takes modules with dependencies and generates static assets representing those modules. It is highly configurable and can perform a wide range of file transformations through its loader system. While broccoli-filter is focused on file transformation within the Broccoli ecosystem, Webpack provides a more comprehensive solution for managing and transforming assets in modern web applications.
broccoli-filter
Helper base class for Broccoli plugins that map input files into output files
one-to-one.
API
class Filter {
constructor(inputNode: BroccoliNode, options: FilterOptions): Filter;
abstract processString(contents: string, relativePath: string): string;
virtual canProcessFile(relativePath: string): boolean;
virtual getDestFilePath(relativePath: string): string;
}
Options
extensions
: An array of file extensions to process, e.g. ['md', 'markdown']
.targetExtension
: The file extension of the corresponding output files, e.g.
'html'
.inputEncoding
: The character encoding used for reading input files to be
processed (default: 'utf8'
). For binary files, pass null
to receive a
Buffer
object in processString
.outputEncoding
: The character encoding used for writing output files after
processing (default: 'utf8'
). For binary files, pass null
and return a
Buffer
object from processString
.name
, annotation
: Same as
broccoli-plugin;
see there.
All options except name
and annotation
can also be set on the prototype
instead of being passed into the constructor.
Example Usage
var Filter = require('broccoli-filter');
Awk.prototype = Object.create(Filter.prototype);
Awk.prototype.constructor = Awk;
function Awk(inputNode, search, replace, options) {
options = options || {};
Filter.call(this, inputNode, {
annotation: options.annotation
});
this.search = search;
this.replace = replace;
}
Awk.prototype.extensions = ['txt'];
Awk.prototype.targetExtension = 'txt';
Awk.prototype.processString = function(content, relativePath) {
return content.replace(this.search, this.replace);
};
In Brocfile.js
, use your new Awk
plugin like so:
var node = new Awk('docs', 'ES6', 'ECMAScript 2015');
module.exports = node;
FAQ
Upgrading from 0.1.x to 1.x
You must now call the base class constructor. For example:
function MyPlugin(inputTree) {
this.inputTree = inputTree;
}
function MyPlugin(inputNode) {
Filter.call(this, inputNode);
}
Note that "node" is simply new terminology for "tree".
Source Maps
Can this help with compilers that are almost 1:1, like a minifier that takes
a .js
and .js.map
file and outputs a .js
and .js.map
file?
Not at the moment. I don't know yet how to implement this and still have the
API look beautiful. We also have to make sure that caching works correctly, as
we have to invalidate if either the .js
or the .js.map
file changes. My
plan is to write a source-map-aware uglifier plugin to understand this use
case better, and then extract common code back into this Filter
base class.