initial commit
This commit is contained in:
commit
d3fcd7f10c
3159 files changed
+349702
No files matched your search
+53
@@ -0,0 +1,53 @@
|
||||
# Writing a plugin
|
||||
|
||||
If you plan to create your own Gulp plugin, you will save time by reading the full documentation.
|
||||
|
||||
* [Guidelines](guidelines.md) (a MUST read)
|
||||
* [Using buffers](using-buffers.md)
|
||||
* [Dealing with streams](dealing-with-streams.md)
|
||||
* [Testing](testing.md)
|
||||
* [README conventions](readme-conventions.md)
|
||||
|
||||
## What it does
|
||||
|
||||
### Streaming file objects
|
||||
|
||||
A gulp plugin always returns a stream in [object mode](http://nodejs.org/api/stream.html#stream_object_mode) that does the following:
|
||||
|
||||
1. Takes in [vinyl File objects](http://github.com/wearefractal/vinyl)
|
||||
2. Outputs [vinyl File objects](http://github.com/wearefractal/vinyl)
|
||||
|
||||
These are known as [transform streams](http://nodejs.org/api/stream.html#stream_class_stream_transform_1) (also sometimes called through streams). Transform streams are streams that are readable and writable which manipulate objects as they're being passed through.
|
||||
|
||||
### Modifying file content
|
||||
|
||||
Vinyl files can have 3 possible forms for the contents attribute:
|
||||
|
||||
- [Streams](dealing-with-streams.md)
|
||||
- [Buffers](using-buffers.md)
|
||||
- Empty (null) - Useful for things like rimraf, clean, where contents is not neeeded.
|
||||
|
||||
## Useful resources
|
||||
|
||||
* [File object](https://github.com/wearefractal/gulp-util/#new-fileobj)
|
||||
* [PluginError](https://github.com/gulpjs/gulp-util#new-pluginerrorpluginname-message-options)
|
||||
* [event-stream](https://github.com/dominictarr/event-stream)
|
||||
* [BufferStream](https://github.com/nfroidure/BufferStream)
|
||||
* [gulp-util](https://github.com/wearefractal/gulp-util)
|
||||
|
||||
|
||||
## Sample plugins
|
||||
|
||||
* [sindresorhus' gulp plugins](https://github.com/search?q=%40sindresorhus+gulp-)
|
||||
* [Fractal's gulp plugins](https://github.com/search?q=%40wearefractal+gulp-)
|
||||
* [gulp-replace](https://github.com/lazd/gulp-replace)
|
||||
|
||||
|
||||
## About streams
|
||||
|
||||
If you're unfamiliar with streams, you will need to read up on them:
|
||||
|
||||
* https://github.com/substack/stream-handbook (a MUST read)
|
||||
* http://nodejs.org/api/stream.html
|
||||
|
||||
Other libraries that are not file manipulating through streams but are made for use with gulp are tagged with the [gulpfriendly](https://npmjs.org/browse/keyword/gulpfriendly) keyword on npm.
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
# Dealing with streams
|
||||
|
||||
> It is highly recommended to write plugins supporting streams. Here is some information on creating a gulp plugin that supports streams.
|
||||
|
||||
> Make sure to follow the best practice regarging error handling and add the line that make the gulp plugin re-emit the first error catched during the transformation of the content
|
||||
|
||||
[Writing a Plugin](README.md) > Writing stream based plugins
|
||||
|
||||
## Dealing with streams
|
||||
|
||||
Let's implement a plugin prepending some text to files. This plugin supports all possible forms of file.contents.
|
||||
|
||||
```js
|
||||
var through = require('through2');
|
||||
var gutil = require('gulp-util');
|
||||
var PluginError = gutil.PluginError;
|
||||
|
||||
// Consts
|
||||
const PLUGIN_NAME = 'gulp-prefixer';
|
||||
|
||||
function prefixStream(prefixText) {
|
||||
var stream = through();
|
||||
stream.write(prefixText);
|
||||
return stream;
|
||||
}
|
||||
|
||||
// Plugin level function (dealing with files)
|
||||
function gulpPrefixer(prefixText) {
|
||||
|
||||
if (!prefixText) {
|
||||
throw PluginError(PLUGIN_NAME, "Missing prefix text!");
|
||||
}
|
||||
prefixText = new Buffer(prefixText); // allocate ahead of time
|
||||
|
||||
// Creating a stream through which each file will pass
|
||||
var stream = through.obj(function (file, enc, callback) {
|
||||
if (file.isNull()) {
|
||||
this.push(file); // Do nothing if no contents
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (file.isBuffer()) {
|
||||
this.emit('error', new PluginError(PLUGIN_NAME, 'Buffers not supported!'));
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (file.isStream()) {
|
||||
// define the streamer that will transform the content
|
||||
var streamer = prefixStream(prefixText);
|
||||
// catch errors from the streamer and emit a gulp plugin error
|
||||
streamer.on('error', this.emit.bind(this, 'error'));
|
||||
// start the transformation
|
||||
file.contents = file.contents.pipe(streamer);
|
||||
// make sure the file goes through the next gulp plugin
|
||||
this.push(file);
|
||||
// tell the stream engine that we are done with this file
|
||||
return callback();
|
||||
}
|
||||
});
|
||||
|
||||
// returning the file stream
|
||||
return stream;
|
||||
};
|
||||
|
||||
// Exporting the plugin main function
|
||||
module.exports = gulpPrefixer;
|
||||
```
|
||||
|
||||
The above plugin can be used like this:
|
||||
|
||||
```js
|
||||
var gulp = require('gulp');
|
||||
var gulpPrefixer = require('gulp-prefixer');
|
||||
|
||||
gulp.src('files/**/*.js')
|
||||
.pipe(gulpPrefixer('prepended string'))
|
||||
.pipe(gulp.dest('/modified-files/'));
|
||||
```
|
||||
|
||||
## Some plugins using streams
|
||||
|
||||
* [gulp-svgicons2svgfont](https://github.com/nfroidure/gulp-svgiconstosvgfont)
|
||||
* gulp-browserify (Soon)
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
# Guidelines
|
||||
|
||||
> While these guidelines are totally optional, we **HIGHLY** recommend that everyone follows them. Nobody wants to use a bad plugin. These guidelines will actually help make your life easier by giving you assurance that your plugin fits well within gulp.
|
||||
|
||||
[Writing a Plugin](README.md) > Guidelines
|
||||
|
||||
1. Your plugin should not do something that can be done easily with an existing node module
|
||||
- Wrapping every possible thing just for the sake of wrapping it will pollute the ecosystem with low quality plugins that don't make sense
|
||||
1. Your plugin should only do **one thing**, and do it well.
|
||||
- Avoid config options that make your plugin do completely different tasks
|
||||
1. Your plugin shouldn't do things that other plugins are responsible for
|
||||
- It should not concat, [gulp-concat](https://github.com/wearefractal/gulp-concat) does that
|
||||
- It should not add headers, [gulp-header](https://github.com/godaddy/gulp-header) does that
|
||||
- It should not add footers, [gulp-footer](https://github.com/godaddy/gulp-footer) does that
|
||||
- If it's a common but optional use case, document that your plugin is often used with another plugin
|
||||
- If it's an internal requirement, make use of existing plugins by piping your plugin's output to them
|
||||
1. Your plugin **must be tested**
|
||||
- Testing a gulp plugin is easy, you don't even need gulp to test it
|
||||
- Look at other plugins for examples
|
||||
1. Add `gulpplugin` as a keyword in your `package.json` so you show up on our search
|
||||
1. Do not throw errors inside a stream
|
||||
- Instead, you should emit it as an **error** event.
|
||||
- If you encounter an error **outside** the stream, such as invalid configuration, you may throw it.
|
||||
1. Prefix any errors with the name of your plugin
|
||||
- For example: `gulp-replace: Cannot do regexp replace on a stream`
|
||||
- Use gulp-util's [PluginError](https://github.com/gulpjs/gulp-util#new-pluginerrorpluginname-message-options) class to make this easy
|
||||
1. The type of `file.contents` should always be the same going out as it was when it came in
|
||||
- If file.contents is null (non-read) just ignore the file and pass it along
|
||||
- If file.contents is a Stream and you don't support that just emit an error
|
||||
- If you choose to support file.contents as a Stream, use [BufferStream](https://github.com/nfroidure/BufferStream) to make this easy
|
||||
1. Do not pass the `file` object downstream until you are done with it
|
||||
1. Make use of the [gulp-util](https://github.com/gulpjs/gulp-util) library
|
||||
- It provides templating, CLI colors, logging, changing file extensions
|
||||
- Try looking for common things there first and add it if it doesn't exist
|
||||
1. Do NOT require `gulp` as a dependency or peerDependency
|
||||
- There is no reason you should have to do this and it will cause problems if you do
|
||||
|
||||
## Why are these guidelines so strict?
|
||||
|
||||
gulp aims to be simple for users. By providing strict guidelines we are able to provide a consistent and high-quality ecosystem for everyone. While this does add a little more work and thought for plugin authors, it removes a lot of problems later down the road.
|
||||
|
||||
### What happens if I don't follow them?
|
||||
|
||||
npm is open for everyone, and you are free to make whatever you want but these guidelines were prescribed for a reason. There are acceptances tests coming soon that will be integrated into the plugin search. If you fail to adhere to the plugin guidelines it will be publicly visible/sortable via a scoring system. People will always prefer to use plugins that match "the gulp way".
|
||||
|
||||
### What does a good plugin look like?
|
||||
|
||||
```js
|
||||
// through2 is a thin wrapper around node transform streams
|
||||
var through = require('through2');
|
||||
var gutil = require('gulp-util');
|
||||
var PluginError = gutil.PluginError;
|
||||
|
||||
// Consts
|
||||
const PLUGIN_NAME = 'gulp-prefixer';
|
||||
|
||||
function prefixStream(prefixText) {
|
||||
var stream = through();
|
||||
stream.write(prefixText);
|
||||
return stream;
|
||||
}
|
||||
|
||||
// Plugin level function (dealing with files)
|
||||
function gulpPrefixer(prefixText) {
|
||||
|
||||
if (!prefixText) {
|
||||
throw PluginError(PLUGIN_NAME, "Missing prefix text!");
|
||||
}
|
||||
prefixText = new Buffer(prefixText); // allocate ahead of time
|
||||
|
||||
// Creating a stream through which each file will pass
|
||||
var stream = through.obj(function (file, enc, callback) {
|
||||
if (file.isNull()) {
|
||||
this.push(file); // Do nothing if no contents
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (file.isBuffer()) {
|
||||
file.contents = Buffer.concat([prefixText, file.contents]);
|
||||
this.push(file);
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (file.isStream()) {
|
||||
file.contents = file.contents.pipe(prefixStream(prefixText));
|
||||
this.push(file);
|
||||
return callback();
|
||||
}
|
||||
});
|
||||
|
||||
// returning the file stream
|
||||
return stream;
|
||||
};
|
||||
|
||||
// Exporting the plugin main function
|
||||
module.exports = gulpPrefixer;
|
||||
```
|
||||
+218
@@ -0,0 +1,218 @@
|
||||
# README conventions
|
||||
|
||||
> Follow README conventions to increase your plugin readability and usability.
|
||||
|
||||
[Writing a Gulp Plugin](README.md) > README conventions
|
||||
|
||||
A plugin README should have the following parts at a minimum:
|
||||
|
||||
1. **Heading**: Give a short introduction to your plugin
|
||||
* Include the version of gulp your plugin was designed for
|
||||
* Include any badges on the same line as the heading
|
||||
1. **Usage**: Include a simple usage example
|
||||
* Show the plugin used on the context of a `gulpfile.js`
|
||||
* Cover the most common or simplest use case
|
||||
1. **API**: Document your plugin's API
|
||||
* For individual parameters, include:
|
||||
1. Parameter name
|
||||
1. Type
|
||||
1. Default value
|
||||
1. Description
|
||||
1. Optional example for complex options
|
||||
* If a parameter accepts an Object, do the above for each property
|
||||
* If your plugin accepts overloaded arguments, document each style individually
|
||||
|
||||
|
||||
# Example: Options object
|
||||
|
||||
The following is an example of a plugin that takes a single options object (from [gulp-handlebars](https://github.com/lazd/gulp-handlebars)).
|
||||
|
||||
|
||||
***
|
||||
|
||||
# gulp-handlebars [![NPM version][handlebars-npm-image]][handlebars-npm-url] [![Build status][handlebars-travis-image]][handlebars-travis-url]
|
||||
> Handlebars plugin for gulp 3
|
||||
|
||||
## Usage
|
||||
|
||||
First, install `gulp-handlebars` as a development dependency:
|
||||
|
||||
```shell
|
||||
npm install --save-dev gulp-handlebars
|
||||
```
|
||||
|
||||
Then, add it to your `gulpfile.js`:
|
||||
|
||||
```js
|
||||
var handlebars = require('gulp-handlebars');
|
||||
|
||||
gulp.task('templates', function(){
|
||||
gulp.src(['client/templates/*.hbs'])
|
||||
.pipe(handlebars({
|
||||
namespace: 'MyApp.templates',
|
||||
outputType: 'hybrid'
|
||||
}))
|
||||
.pipe(concat('templates.js'))
|
||||
.pipe(gulp.dest('build/js/'));
|
||||
});
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### handlebars(options)
|
||||
|
||||
#### options.namespace
|
||||
Type: `String`
|
||||
Default: `templates`
|
||||
|
||||
The namespace in which the precompiled templates will be assigned. Use dot notation (e.g. `App.Templates`) for nested namespaces or false to declare templates in the global namespace.
|
||||
|
||||
#### options.outputType
|
||||
Type: `String`
|
||||
Default: `browser`
|
||||
|
||||
The desired output type. One of the following:
|
||||
|
||||
* `browser` - Produce plain JavaScript files for the browser
|
||||
* `hybrid` - Produce Node modules that can optionally be used on the frontend
|
||||
* `node` - Produce Node modules
|
||||
* `amd` - Produce AMD modules
|
||||
* `commonjs` - Produce CommonJS modules
|
||||
* `bare` - Return an unmolested function definition
|
||||
|
||||
#### options.declareNamespace
|
||||
Type: `Boolean`
|
||||
Default: `true`
|
||||
|
||||
If true, non-destructively declare all parts of the namespace. This option is only necessary when `options.type` is `browser` or `hybrid`.
|
||||
|
||||
For example, if the namespace is `MyApp.Templates` and a template is named `App.Header.hbs`, the following declaration will be present in the output file for that template:
|
||||
|
||||
```js
|
||||
this["MyApp"] = this["MyApp"] || {};
|
||||
this["MyApp"]["templates"] = this["MyApp"]["templates"] || {};
|
||||
this["MyApp"]["templates"]["App"] = this["MyApp"]["templates"]["App"] || {};
|
||||
this["MyApp"]["templates"]["App"]["Header"] = function () {};
|
||||
```
|
||||
|
||||
When processing multiple templates under a given namespace, this will result in duplicate declarations. That is, the non-destructive declaration of the namespace will be repeated for each template compiled.
|
||||
|
||||
#### options.processName
|
||||
Type: `Function`
|
||||
Default: Strip file extension
|
||||
|
||||
This option accepts a function which takes one argument (the template filepath) and returns a string which will be used as the key for the precompiled template object. By default, the filename minus the extension is used.
|
||||
|
||||
If this function returns a string containing periods (not including the file extension), they will be represented as a sub-namespace. See `options.declareNamespace` for an example of the effect.
|
||||
|
||||
#### options.compilerOptions
|
||||
Type: `Object`
|
||||
|
||||
Compiler options to pass to `Handlebars.precompile()`.
|
||||
|
||||
|
||||
[handlebars-travis-url]: http://travis-ci.org/lazd/gulp-handlebars
|
||||
[handlebars-travis-image]: https://secure.travis-ci.org/lazd/gulp-handlebars.png?branch=master
|
||||
[handlebars-npm-url]: https://npmjs.org/package/gulp-handlebars
|
||||
[handlebars-npm-image]: https://badge.fury.io/js/gulp-handlebars.png
|
||||
***
|
||||
|
||||
|
||||
# Example: Overloaded API
|
||||
|
||||
The following is an example of a plugin that has an overloaded API (from [gulp-csslint](https://github.com/lazd/gulp-csslint)).
|
||||
|
||||
|
||||
***
|
||||
# gulp-csslint [![NPM version][csslint-npm-image]][csslint-npm-url] [![Build status][csslint-travis-image]][csslint-travis-url]
|
||||
> CSSLint plugin for gulp 3
|
||||
|
||||
## Usage
|
||||
|
||||
First, install `gulp-csslint` as a development dependency:
|
||||
|
||||
```shell
|
||||
npm install --save-dev gulp-csslint
|
||||
```
|
||||
|
||||
Then, add it to your `gulpfile.js`:
|
||||
|
||||
```javascript
|
||||
var csslint = require('gulp-csslint');
|
||||
|
||||
gulp.task('css', function() {
|
||||
gulp.src('./client/css/*.css')
|
||||
.pipe(csslint())
|
||||
.pipe(csslint.reporter());
|
||||
});
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### csslint(ruleConfiguration)
|
||||
|
||||
#### ruleConfiguration
|
||||
Type: `Object`
|
||||
|
||||
You can pass rule configuration as an object. See the [list of rules by ID on the CSSLint wiki](https://github.com/stubbornella/csslint/wiki/Rules-by-ID) for valid rule IDs.
|
||||
|
||||
```javascript
|
||||
gulp.src('./client/css/*.css')
|
||||
.pipe(csslint({
|
||||
'shorthand': false
|
||||
}))
|
||||
.pipe(csslint.reporter());
|
||||
```
|
||||
|
||||
### csslint(csslintrc)
|
||||
|
||||
#### csslintrc
|
||||
Type: `String`
|
||||
|
||||
You can also pass the path to your csslintrc file instead of a rule configuration object.
|
||||
|
||||
```javascript
|
||||
gulp.src('./client/css/*.css')
|
||||
.pipe(csslint('csslintrc.json'))
|
||||
.pipe(csslint.reporter());
|
||||
```
|
||||
|
||||
## Results
|
||||
|
||||
Adds the following properties to the file object:
|
||||
|
||||
```javascript
|
||||
file.csslint.success = true; // or false
|
||||
file.csslint.errorCount = 0; // number of errors returned by CSSLint
|
||||
file.csslint.results = []; // CSSLint errors
|
||||
file.csslint.opt = {}; // The options you passed to CSSLint
|
||||
```
|
||||
|
||||
## Custom Reporters
|
||||
|
||||
Custom reporter functions can be passed as `cssline.reporter(reporterFunc)`. The reporter function will be called for each linted file and passed the file object as described above.
|
||||
|
||||
```javascript
|
||||
var csslint = require('gulp-csslint');
|
||||
var gutil = require('gulp-util');
|
||||
|
||||
var customReporter = function(file) {
|
||||
gutil.log(gutil.colors.cyan(file.csslint.errorCount)+' errors in '+gutil.colors.magenta(file.path));
|
||||
|
||||
file.csslint.results.forEach(function(result) {
|
||||
gutil.log(result.error.message+' on line '+result.error.line);
|
||||
});
|
||||
};
|
||||
|
||||
gulp.task('lint', function() {
|
||||
gulp.files('./lib/*.js')
|
||||
.pipe(csslint())
|
||||
.pipe(csslint.reporter(customReporter));
|
||||
});
|
||||
```
|
||||
|
||||
[csslint-travis-url]: http://travis-ci.org/lazd/gulp-csslint
|
||||
[csslint-travis-image]: https://secure.travis-ci.org/lazd/gulp-csslint.png?branch=master
|
||||
[csslint-npm-url]: https://npmjs.org/package/gulp-csslint
|
||||
[csslint-npm-image]: https://badge.fury.io/js/gulp-csslint.png
|
||||
***
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
# Testing
|
||||
|
||||
> Testing your plugin is the only way to ensure quality. It brings confidence to your users and makes your life easier.
|
||||
|
||||
[Writing a Plugin](README.md) > Testing
|
||||
|
||||
## Tooling
|
||||
|
||||
Most plugins use [mocha](https://github.com/visionmedia/mocha) and [event-stream](https://github.com/dominictarr/event-stream) to help them test. The following examples will use these tools.
|
||||
|
||||
## Testing plugins for streaming mode
|
||||
|
||||
```js
|
||||
var assert = require('assert');
|
||||
var es = require('event-stream');
|
||||
var gutil = require('gulp-util');
|
||||
var prefixer = require('../index');
|
||||
|
||||
describe('gulp-prefixer', function () {
|
||||
describe('in streaming mode', function () {
|
||||
|
||||
it('should prepend text', function (done) {
|
||||
|
||||
// create the fake file
|
||||
var fakeFile = new gutil.File({
|
||||
contents: es.readArray(['stream', 'with', 'those', 'contents'])
|
||||
});
|
||||
|
||||
// Create a prefixer plugin stream
|
||||
var myPrefixer = prefixer('prependthis');
|
||||
|
||||
// write the fake file to it
|
||||
myPrefixer.write(fakeFile);
|
||||
|
||||
// wait for the file to come back out
|
||||
myPrefixer.once('data', function (file) {
|
||||
// make sure it came out the same way it went in
|
||||
assert(file.isStream());
|
||||
|
||||
// buffer the contents to make sure it got prepended to
|
||||
file.contents.pipe(es.wait(function (err, data) {
|
||||
// check the contents
|
||||
assert.equal(data, 'prependthistostreamwiththosecontents');
|
||||
done();
|
||||
}));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Testing plugins for buffer mode
|
||||
|
||||
```js
|
||||
var assert = require('assert');
|
||||
var es = require('event-stream');
|
||||
var gutil = require('gulp-util');
|
||||
var prefixer = require('../index');
|
||||
|
||||
describe('gulp-prefixer', function () {
|
||||
describe('in buffer mode', function () {
|
||||
|
||||
it('should prepend text', function (done) {
|
||||
|
||||
// create the fake file
|
||||
var fakeFile = new gutil.File({
|
||||
contents: new Buffer('abufferwiththiscontent')
|
||||
});
|
||||
|
||||
// Create a prefixer plugin stream
|
||||
var myPrefixer = prefixer('prependthis');
|
||||
|
||||
// write the fake file to it
|
||||
myPrefixer.write(fakeFile);
|
||||
|
||||
// wait for the file to come back out
|
||||
myPrefixer.once('data', function (file) {
|
||||
// make sure it came out the same way it went in
|
||||
assert(file.isBuffer());
|
||||
|
||||
// check the contents
|
||||
assert.equal(file.contents.toString('utf8'), 'prependthisabufferwiththiscontent');
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Sample tests
|
||||
* [gulp-cat](https://github.com/ben-eb/gulp-cat/blob/master/test.js)
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
# Using buffers
|
||||
|
||||
> Here is some information on creating gulp plugin that manipulates buffers.
|
||||
|
||||
[Writing a Plugin](README.md) > Using buffers
|
||||
|
||||
## Using buffers
|
||||
If your plugin is relying on a buffer based library, you will probably choose to base your plugin around file.contents as a buffer. Let's implement a plugin prepending some text to files:
|
||||
|
||||
```js
|
||||
var through = require('through2');
|
||||
var gutil = require('gulp-util');
|
||||
var PluginError = gutil.PluginError;
|
||||
|
||||
// Consts
|
||||
const PLUGIN_NAME = 'gulp-prefixer';
|
||||
|
||||
// Plugin level function (dealing with files)
|
||||
function gulpPrefixer(prefixText) {
|
||||
|
||||
if (!prefixText) {
|
||||
throw new PluginError(PLUGIN_NAME, "Missing prefix text!");
|
||||
}
|
||||
prefixText = new Buffer(prefixText); // allocate ahead of time
|
||||
|
||||
// Creating a stream through which each file will pass
|
||||
var stream = through.obj(function (file, enc, callback) {
|
||||
if (file.isNull()) {
|
||||
this.push(file); // Do nothing if no contents
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (file.isBuffer()) {
|
||||
file.contents = Buffer.concat([prefixText, file.contents]);
|
||||
this.push(file);
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (file.isStream()) {
|
||||
this.emit('error', new PluginError(PLUGIN_NAME, 'Streams are not supported!'));
|
||||
return callback();
|
||||
}
|
||||
});
|
||||
|
||||
// returning the file stream
|
||||
return stream;
|
||||
};
|
||||
|
||||
// Exporting the plugin main function
|
||||
module.exports = gulpPrefixer;
|
||||
```
|
||||
The above plugin can be used like this:
|
||||
|
||||
```js
|
||||
var gulp = require('gulp');
|
||||
var gulpPrefixer = require('gulp-prefixer');
|
||||
|
||||
gulp.src('files/**/*.js')
|
||||
.pipe(gulpPrefixer('prepended string'))
|
||||
.pipe(gulp.dest('/modified-files/'));
|
||||
```
|
||||
|
||||
## Handling streams
|
||||
|
||||
Unfortunately, the above plugin will error when using gulp.src in non-buffered (streaming) mode. You should support streams too if possible. See [Dealing with streams](dealing-with-streams.md) for more information.
|
||||
|
||||
## Some plugins based on buffers
|
||||
|
||||
* [gulp-coffee](https://github.com/wearefractal/gulp-coffee)
|
||||
* [gulp-svgmin](https://github.com/ben-eb/gulp-svgmin)
|
||||
* [gulp-marked](https://github.com/lmtm/gulp-marked)
|
||||
* [gulp-svg2ttf](https://github.com/nfroidure/gulp-svg2ttf)
|
||||
Reference in new issue
Block a user