Writing a simple Gulp plugin tutorial
Hi, my name is Tina! I am a Full Stack Software Developer and Tech Lead from Canada. 🙋🏻♀️
Search for a command to run...
Hi, my name is Tina! I am a Full Stack Software Developer and Tech Lead from Canada. 🙋🏻♀️
No comments yet. Be the first to comment.
Have you ever installed a package by using go install <some-package> and wondered how to uninstall it? Go is really great in that respect. Go packages are a single binary and they’re installed based on how your Go tooling is set up. Provided we have ...

Overview This is the 3rd article in a series of posts about working with Open API to create generated API clients and documentation websites. In the 1st post we went over what we can do with Open API spec files, e.g. generate API clients and documen...

Overview This article is the 2nd in a series of blog posts that discuss using Open API to help with API documentation and API client code generation. In the previous article, we went over how we can generate documentation and API clients using existi...

Overview This article starts a series of Open API-related blog posts. OpenAPI, previously known as Swagger (a name still in use today for many of its tools), is a suite of tools that generate documentation and networking clients for various programmi...

You've probably already seen the scary alert (that's possibly why you're here), but in case you haven't, it looks something like this: NewAppIJustDownloaded pasted from your clipboard Sometimes it h

In this simple Gulp plugin tutorial, I will be going through a plugin I wrote. The plugin is simple and transforms an input JSON file. Though Gulp was a great tool I fully leveraged for bundling front-end apps at its inception, I do not currently recommend using Gulp for new projects. You may, however, find yourself in an existing project that already uses Gulp. Keeping an existing Gulp build system is perfectly reasonable. This tutorial would be useful in that case. In order to gain value from this blog post, you should have some basic experience setting up Gulp to bundle your projects.
Writing a Gulp plugin that transforms JSON would be useful when bundling a Chrome extension for distribution. In the final bundle, developers need to provide a manifest.json file. This manifest, among other things, declares lists of domains that you are authorizing your Chrome extension to use. Such domains can include your Chrome extension's back-end API server, for example, a value that changes based on the environment. A plugin that manipulates the manifest.json, adding/removing/replacing values depending on the environment, can be useful to publish different Chrome extension builds for each of the supported environments (development, staging, production). We currently have the following manifest.json file:
{
"manifest_version": 2,
"name": "My Cool Extension",
"version": "1.0.0",
"content_security_policy": "default-src 'self'; connect-src 'self' http://localhost:1337 https://staging.example.com https://app.example.com",
"permissions": [
"tabs",
"storage",
"cookies",
"http://localhost:1337",
"https://staging.example.com",
"https://app.example.com"
]
}
For production, we would like the manifest.json file to look like this:
{
"manifest_version": 2,
"name": "My Cool Extension",
"version": "1.0.0",
"content_security_policy": "default-src 'self'; connect-src 'self' https://app.example.com",
"permissions": [
"tabs",
"storage",
"cookies",
"https://app.example.com"
]
}
Our Gulp plugin needs to remove the localhost and staging entries (http://localhost:1337 and https://staging.example.com) from both the content security policy and the permissions list.
Ideally we should structure our Gulp plugin in 2 files:
When we break our plugin into 2 files instead of one, we can isolate our business logic into a simpler method that is a simple function that takes simple arguments. We can then write tests for our business logic alone. This makes our plugin's logic much easier to test, compared to if we had only one file and we needed to test it within the context of a Gulp stream.
This file is all of the business logic. Given a file buffer as an argument, as well as any other arguments passed through from the Gulpfile, we can perform actions on the provided input.
// transform-manifest.js
const transformManifest = (opts = {}, manifestJsonBuffer) => {
const manifest = JSON.parse(manifestJsonBuffer.contents.toString());
// Modify CSP
const csp = '[my new CSP that is possibly created by removoing things]'
manifest.content_security_policy = csp;
// Modify permissions
const permissions = manifest.permissions.filter(myFilteringCriteria);
manifest.permissions = permissions;
/**
* Rewrite file buffer
*/
const stringContents = JSON.stringify(manifest, null, 2);
const newBuffer = Buffer.alloc(stringContents.length, stringContents);
manifestJsonBuffer.contents = newBuffer;
return manifestJsonBuffer;
};
module.exports = transformManifest;
Our resulting file exports a function that takes a JSON file Buffer and returns a JSON file Buffer to continue down the Gulp stream.
This is the part that ties our primary business logic to the Gulp stream. The Gulp documentation provides multiple options for how to create plugins, but in this example I'll use the module through2 to help tie it together.
// gulp-transform-manifest.js
const through = require('through2');
const transformManifest = require('./transform-manifest');
module.exports = function (opts) {
return through.obj(function(file, encoding, callback) {
callback(null, transformManifest(opts, file));
});
};
You can essentially just copy and paste this Gulp glue verbatim. Keep in mind that opts are options that you can pass in from the Gulpfile. In my Gulpfile, the implementation is as follows:
// Gulpfile.js
const gulp = require('gulp');
const transformManifest = require('./lib/gulp-transform-manifest');
gulp.task('process-manifest', () => {
return gulp.src([
'./src/manifest.json'
])
.pipe(transformManifest({ env: process.env.NODE_ENV }))
.pipe(gulp.dest('./dist'));
});
In the package.json I call my my task like so:
NODE_ENV=production gulp dist
The Gulp task dist uses the process-manifest task as a dependency alongside other tasks. The environment variable is passed through from the executed NPM script to Gulp, which passes it through to our Gulp plugin.
That wraps up this simple Gulp plugin tutorial. Let's take a look at what we've learned: