Building a jQuery Plugin From Scratch – Part 1

In the first part of this tutorial series, we will walk through the setup process for a custom jQuery plugin. Setting up version control and build processes.

Building a jQuery Plugin From Scratch – Part 1

Introduction

Check the source code on any of your favorite sites and chances are (and statistics support) that more than half of them will have jQuery installed. It’s not surprising, as everyone’s favorite Javascript library provides a simple, cross-browser way to add interactivity to personal and professional sites. Plus, the plugin scene is just crazy. Some more crazy than others, like this jQuery plugin that adds a raptor to the page. Because why not?

So have you ever wanted to create your own jQuery plugin? For the forks, for the glory, or just because you want a convenient wrapper for functionality you use on every single project?

In this several part series (total parts to be determined), I’ll show you the steps to creating and maintaining your own jQuery plugin and making it available to the public. You’ll be following along with my actual development process for a simple (yet spectacular), modal system called Black & White Box. Part one will focus on project setup — which includes build processes and version control.

From the Beginning

Project setup, due to its tedious nature, is usually the easiest step to either skip or ignore completely. It’s also the most important. And if we’re hoping to extend our amazing new plugin functionality beyond its lowly beginnings, we need to start with a clean, organized slate that we can build on later. Here’s a list of tools that we’re going to install / use for the initial setup:

  • Git
  • Node.js
  • Gulp

This tutorial will only touch briefly on installation for each, but there are plenty of great resources available if you need additional help. And by all means, if you already have these items installed, skip the next couple steps. Alright, let’s jump in!

Back It Up

Ideally, the first step to any coding project is to set up a reliable version control system. Even local, lone-wolf development can benefit greatly from keeping files properly backed up, easily navigable and retrievable. Chances are, if you’re on a Mac, git is already installed and ready to go. If not, or if you’re on a Windows machine, head over here and select the proper operating system to install.

Once git’s installed, we can dive in. To get started, create a new project directory and give it a name (mine is bw-box). Add a README.md file to the directory, then open up the command line to run the following command:

git init

Now, if you run git status you should be given the README file as an option to commit in red. Proceed with the commit:

git add README.md
git commit -m "Initial commit"

Once we’ve made more meaningful progress, we’ll add a remote repo on Github to house the public-facing version of our plugin. For now, we’ll move on and set up the build processes.

Building Blocks

Build systems have become increasingly popular as automation tools for those tedious tasks that developers run through over and over. Compiling Sass, linting scripts, minifying all the things, etc. There are a lot of options here, but my personal favorite is Gulp. Its configuration seems much more streamlined than some of the other popular build tools.

Before we get started, you’ll need to install Node.js and the package manager npm (if you don’t already have them). You’ll find the current version of Node at this page. Again, there are great resources out there if you have any questions. Once installed, the npm command should be available in the console. Navigate to the plugin directory and execute the following command:

npm init

This will prompt you with several questions to populate the package.json configuration file. For the most part, these can be answered with the default values by just hitting Enter for each. Don’t worry, you can always edit the package.json file at any time, if you need to make changes.

Now we can install the build tool gulp to help keep our development process automated and clean. Run the following code to install gulp globally (this allows us to access the gulp command from our local directory). Then we’ll install gulp locally, to be used in our build file:

npm install -g gulp
npm install --save-dev gulp

Now if you open up your package.json file, you should see gulp defined as a dependency. Before we start work on our build configuration, we’ll install a few additional modules:

npm install --save-dev gulp-concat
npm install --save-dev gulp-uglify
npm install --save-dev gulp-sass
npm install --save-dev gulp-jshint
npm install --save-dev gulp-notify
npm install --save-dev jshint-stylish

That’s quite a few modules that we’re adding, but they’ll cut hours off development, deployment and collaboration. So let’s put them to use. In the project’s root directory, create a file called gulpfile.js. This is the main configuration document that defines our build tasks. First, we need to add require statements for each of the modules we plan on using to the top of our gulpfile.js:

// Gulp Dependencies
var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var sass = require('gulp-sass');
var jshint = require('gulp-jshint');
var notify = require('gulp-notify');
var stylish = require('jshint-stylish');

Since we’ll be concatenating and minifying our styles and scripts, let’s define our structure to accommodate the source and output files. Here’s the directory structure we should end up with:

dist/
  css/
    - jquery.bw-box.min.css
  js/
    - jquery.bw-box.min.js
src/
  scss/
    - jquery.bw-box.scss
  js/
    - jquery.bw-box.js
- gulpfile.js
- package.json
- README.md

Before jumping in to create each and every file, keep in mind that the items in the dist directory will be generated via our build process. For now, just create the necessary folder structure and we’ll jump into the rest shortly.

Pull up the gulpfile.js file and we’ll start working through our build processes. First, we’ll populate some path variables and objects that will come in handy in several of our build tasks. Place this below the required modules section:

var src= 'src';
var dist = 'dist';
var paths = {
  js: src + '/js/*.js',
  scss: src + '/scss/**/*.scss'
};

Now we’ll create our first gulp task, which will be compiling and compressing our Sass files. In gulp, the process of creating new tasks is fairly straightforward. First we define the task, then return the source files that we want to alter:

gulp.task('compile-sass', function() {
  return gulp.src(paths.scss)
    .pipe(sass({outputStyle: 'compressed'}).on('error', sass.logError))
    .pipe(concat('jquery.bw-box.min.css'))
    .pipe(gulp.dest(dist + '/css'));
});

Walking through each step – we define a task called compile-sass that we can access later, we pass in the path variable, which includes all scss files in the target directory, then combine all output into the minified file with the concat command, before finally dropping it into our css directory. This already cuts out several tedious tasks from a normal manual build – compiling Sass, minifying, and organizing directories.

Now we’ll add another common task: compiling and minifying javascript files. Just like the previous example, we’ll start by defining the task, before filling in options:

gulp.task('compile-js', function() {
  return gulp.scr(paths.js)
    .pipe(concat('jquery.bw-box.min.js'))
    .pipe(uglify().on('error', function(error) {
      console.log(error);
    }))
    .pipe(gulp.dest(dist + '/js'));
  });

Here, we pull in any javascript files from the specified path, concatenate into a single file, minify the output, and place in our dist folder. Not much different than our compile-sass task, really. Finally, we’ll add a task to watch for any updates to our styling or functionality and run our build processes automatically. This makes all our setup worth its time and weight in gold bullion. Let’s add the following to our gulpfile.js:

gulp.task('watch', function() {
    gulp.watch(paths.js, ['compile-js']);
    gulp.watch(paths.scss, ['compile-sass']);
  });

This task listens for changes at our js or scss paths and runs the specified tasks in real time. Pretty cool, right? There are tons of other build options that we could layer on top, like adding a local server, live reload, or applying javascript / css linting. Let me know in the comments if you want a more in-depth walkthrough on gulp build processes. But this should be a good start for streamlining our plugin development process.

At this point, you’re probably wondering how these tasks are supposed to be running in the first place. We can head back over to the terminal window and run any of the defined tasks, like so:

gulp compile-sass
gulp compile-js
gulp watch

After each command, there should be an output indicating the total compile time and any applicable errors. Since we’ll most likely want to run each command every time we perform a build operation, we can define a default gulp task to do just that. Back in our gulpfile.js, add the following:

gulp.task('default', ['compile-sass', 'compile-js', 'watch']);

Make sure that the tasks listed in the array match the names assigned in the individual task declarations, and that they’re placed in the correct order of operation (if you want to lint your js before minifying, place the lint task first). Easy enough, and now all you need to enter in the terminal is (drum roll please):

gulp

Great work! Now we have the basic structure for our jQuery plugin and the build process hammered out. It’s time to start building the thing! That was a lot of build-up, so hopefully you’re still fired up about the next part of our jQuery plugin tutorial series. Let me know in the comments if you have any questions, or if there’s any other tutorials you’d like to see!