jQuery plugin development with Gulp automation
Create a well structured and automated jQuery plugin development environment with Gulp
In this article, I am trying to explain the step by step process to setup a jQuery Plugin development environment with modern development practice. It will improve the efficiency and maintainability of the project since we can automate tasks like lint, test, build, commit and publish.
TL;DR
You can use the create-jquery-plugin CLI tool to create jQuery Plugins by running
npx create-jquery-plugin
. Or, you can clone the repository jquery-plugin-boilerplate.
Our aim is to…
- Create a nicer directory structure for the jQuery Plugin project.
- Use Gulp to automate tasks lint, transpile, beautify and minimize.
The example project we use for this article is so simple and minimal. You can use it as a boilerplate for your new plugin and get started.
See the jquery-plugin-boilerplate project on GitHub
Prerequisites
You need Node installed on your development machine, if not, please download and install from here
1. Directory Setup for the project
We can use the latest trending directory structure src
and dist
. The src
is the alias for source and dist
for distribution. All our development and coding is happening on src
directory and dist
directory remains untouched by humans. The dist
directory will contain optimized files for the production. Gulp and its plugins are responsible for managing and maintaining the dist
directory for us.
Also, we can add examples
directory for the demo and usage examples, usually the HTML files. If you want to do unit testing, the test
directory can contain your test scripts.
Our final directory structure will look like the following, you can create the directory structure in your project directory.
- dist/
- css/
- js/
- examples
- src/
- css/
- js/
- test
2. Install Gulp and other dependencies
Follows the list of Node tools we are going to use in our example project. These are development dependencies and only used in the development environment. You don’t have to install or bundle them on production.
- Gulp — a toolkit for automating painful or time-consuming tasks in your development
- Babel — a JavaScript compiler
- Jshint — a tool that helps to detect errors and potential problems in your JavaScript code
- UglifyJS — a JavaScript compressor/minifier
- Postcss — A tool for transforming CSS with JavaScript
- cleanCSS — Fast and efficient CSS optimizer for node.js and the Web
- CSS Beautify — a JavaScript implementation of reindenter and reformatter for styles written in CSS
- Autoprefixer — A plugin to parse CSS and add vendor prefixes to CSS rules
- Browsersync — Time-saving synchronised browser testing
Add package.json
file
Before installing the tools, we need to create the package.json
file. It is the configuration file for NPM which contains the details of the project and its dependencies.
It is very easy to create, open the command prompt, go to your project directory and run the command…
npm init
and when asked, type in the details of your project like name, description, version etc. It will create the package.json
file on the root of the project directory for you. More details and option of the file can be found here.
Install development dependencies
Next we can install the tools, open the command prompt, go to your project directory and run the following command.
npm install --save-dev autoprefixer del gulp gulp-babel gulp-clean-css gulp-cssbeautify gulp-jshint gulp-postcss gulp-rename gulp-uglify jshint browser-sync node-sass uglify-save-license
The --save-dev
parameter tells the npm to install them as the development dependency.
Install project dependencies
Since we are developing the jQuery plugin, we can also install jQuery from npm. Note that we are using -save
, to tell npm that it is a project dependency.
npm install -save jquery
These commands will install all the dependencies on the node_modules
directory of your project.
3. Create Gulp tasks
Now we can create Gulp tasks, we create 3 kinds of Gulp tasks for the project.
clean
=> Delete all files in thedist
folder to keep the directory fresh for every build.lint
=> Lint the JavaScript files for errors and potential problems.build
=> Build the JavaScript/CSS files ondist
folder.
To create the task, we need to create a configuration file for Gulp called gulpfile.js
. It is a simple JavaScript file for defining the tasks. You can create the file on the root of your project directory and let's see what will be the contents of it. Also, you can see the full gulpfile.js
file on GitHub.
See the full example file on GitHub
First, we can include the plugins used by the tasks.
// Include the required tools used on tasks
var gulp = require('gulp'),
jshint = require('gulp-jshint'),
rename = require('gulp-rename'),
uglify = require('gulp-uglify'),
saveLicense = require('uglify-save-license'),
babel = require("gulp-babel"),
postcss = require('gulp-postcss'),
cleanCSS = require('gulp-clean-css'),
cssbeautify = require('gulp-cssbeautify'),
autoprefixer = require('autoprefixer'),
sass = require('gulp-sass'),
del = require('del');
// Initialise plugins
sass.compiler = require('node-sass');
var Server = require('karma').Server;
var browserSync = require('browser-sync').create();
var reload = browserSync.reload;
Then we can set our source and destination files and directories on a variable, So that to avoid repeating it.
// Specify the Source files
var SRC_JS = 'src/js/*.js';
var SRC_CSS = 'src/css/*.css';
var SRC_SCSS = 'src/scss/*.scss';// Specify the Destination folders
var DEST_JS = 'dist/js';
var DEST_CSS = 'dist/css';
var DEST_SCSS = 'src/css';
Clean Tasks
We have two tasks for clean, clean:js
and clean:css
. It just deletes the dist/js
and dist/css
directories.
// CLEAN files
gulp.task('clean:js', function () {
return del([DEST_JS]);
}); gulp.task('clean:css', function () {
return del([DEST_CSS]);
});
You can call the tasks by running
gulp clean:jsgulp clean:css
Lint Task
The lint:js
task will call JSHint on each JavaScript files and report the potential errors and problems.
// Lint JS
gulp.task('lint:js', function() {
return gulp.src(SRC_JS)
.pipe(jshint())
.pipe(jshint.reporter('default'))
.pipe(jshint.reporter('fail'));
});
You can call the tasks by running
gulp lint:js
Build Tasks
We have 2 build tasks here, one for JavaScript files and another one for CSS files.
The build:js
task is configured to call clean:js
and lint:js
tasks before running build. So that it will clean the directory and check for errors before doing the build. The task will fail if we have errors while linting and avoid creating error files on dist
directory.
The build:js
task will read all the JavaScript files one by one and call Babel for transpile the files and save them on dist/js
directory. Then it uses UglifyJS to minimize and compress the JavaScript files, adds .min
suffix on filename and then saves files on dist/js
directory.
The build:css
task first uses Autoprefixer to add prefix to our css rules. For example we only have to write border-radius: 5px;
in our source CSS and the Autoprefixer will add the missing prefixes like -webkit-border-radius: 5px;
, -mos-border-radius: 5px;
for browser compatibility. Then the task uses the CSS Beautify plugin to convert our css in a well formatted style and save it on dist/css
. It will give a nicer look to our non minified css files. And finally, use CleanCSS to minify and compress the css files, adds .min
suffix on filename and then save files on dist/js
directory.
// Build JS
gulp.task('build:js', ['clean:js', 'lint:js'], function() {
return gulp.src(SRC_JS)
.pipe(babel())
.pipe(gulp.dest(DEST_JS))
.pipe(uglify({preserveComments:'license'}))
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest(DEST_JS));
}); // Build CSS
gulp.task('build:css', ['clean:css'], function () {
return gulp.src(SRC_CSS)
.pipe(postcss( [autoprefixer({browsers: ['last 10 versions']})] ))
.pipe(cssbeautify({ autosemicolon: true }))
.pipe(gulp.dest(DEST_CSS))
.pipe(cleanCSS({compatibility: 'ie8'}))
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest(DEST_CSS));
});
You can call the tasks by running
gulp build:jsgulp build:css
As as result of all these tasks, the dist
directory will contain two directories css
and js
. Each of that directory will contain error free and beautiful JavaScript and CSS files along with its minified and compressed versions.
Default Task
Finally, we can specify the default task for Gulp, this will make all the above task run automatically when we simply call gulp
from the command line.
// DEFAULT task
gulp.task('default', function() {
gulp.start( 'build:js', 'build:css' );
});
You can call it by running
gulp
4. Write your jQuery plugin
We are done with our development setup, now we have to only worry about our plugin code. Use src/js
directory to write your JavaScript source code and src/css
directory for CSS files. Also, the demo HTML pages can be saved on example
directory.
The example project has a very simple jQuery plugin called “alterMe”. The plugin alters the text inside an element to uppercase or lowercase. I am not including the plugin code here, but you can see the plugin files on GitHub.
See the example project on GitHub
5. Build the project
Every time you do changes on your project, just run gulp
on your project directory from the command line and sit back. Gulp will do all the clean, lint and build task for you, just remember the magic word...
gulp
Extend Gulp Tasks
We have setup the basic development tasks, we can still extend to add more tasks and features. Let’s discuss some more useful tasks we can add to our project.
Watch Files
Instead of running the tasks every time, you can further automate it by making the tasks run when you modify your files.
// WATCH for file changes and run the tasks
gulp.task('watch', function() {
gulp.watch(SRC_JS, ['build:js']);
gulp.watch(SRC_CSS, ['build:css']);
});
Now run this command and start writing code
gulp watch
Unit Testing
There are many other libraries avaliable for JavaScript unit testing. See this StackOverflow discussion to know more about it.
JavaScript unit test tools for TDD
JavaScript Extensions
Instead of just writing code in plain JavaScript, you can use any of the advanced JavaScript Extensions like CoffeeScript, TypeScript, ECMAScript, etc. and use Gulp tasks to compile that to JavaScript. Please refer the gulp plugins gulp-coffee, gulp-babel, gulp-typescript.
List of languages that compile to JS
CSS Extensions
You can use CSS Extensions like Sass or Less instead of writing plain CSS and use Gulp tasks to convert to CSS. Please refer the gulp plugins gulp-sass, gulp-less
CSS Lint
Like we do JavaScript linting in this example, we can also add CSS linting. Please refer the gulp plugins gulp-csslint, gulp-stylelint also the good article about style linting
How to lint your Sass/CSS properly with Stylelint
HTML Minification
You can minify your HTML using gulp-htmlmin.
npm install gulp-htmlmin --save-dev
Task configuration
var gulp = require('gulp');
var htmlmin = require('gulp-htmlmin'); gulp.task('minify', function() {
return gulp.src('src/*.html')
.pipe(htmlmin({collapseWhitespace: true}))
.pipe(gulp.dest('dist'));
});
Bundling Files
You can bundle your files to a single file using gulp-concat.
npm install gulp-concat --save-dev
Task configuration
var gulp = require('gulp');
var htmlmin = require('gulp-concat'); // Bundle JS
gulp.task('bundle:js', function () {
gulp.src(SRC_JS) // path to your files
.pipe(concat('bundle.js')) // concat and name it "bundle.js"
.pipe(gulp.dest(DEST_JS));
}); // Bundle CSS
gulp.task('bundle:css', function () {
gulp.src(SRC_CSS) // path to your files
.pipe(concat('bundle.css')) // concat and name it "bundle.css"
.pipe(gulp.dest(DEST_CSS));
});
Git Actions
You can perform Git actions like commit and push with gulp-git.