There are a couple of Gulp plugins to help with this process:
- gulp-iife: wraps JS code in an immediately invoked function expression
- gulp-concat: concatenates multiple files
- gulp-uglify: minifies JS files
- gulp-rename: renames files
- gulp-jshint: error detection for JS files (optional but recommended)
You will need to install each plugin and save it as a dependency, like so:
npm install --save-dev gulp-iife
plugins.min.js, and all of our custom scripts into one file,
script.min.js. We’ll then take both of these files and concatenate them into
main.js, which we can then minify into our final file,
main.min.js. You could skip the first step of splitting plugins and custom scripts into separate files, but this method ensures that any plugin scripts will be included before our custom scripts. This is important in case any of our custom scripts rely on a plugin script, such as modernizr.
Here’s an example of the file structure:
At the top of your gulpfile, you will need to require each of the above plugins, along with Gulp:
Compiling Third-Party Scripts
Next, we’ll create a new task to handle our plugin scripts:
First, we need to specify the source. Normally, we would pass something like
'js/plugins/*.js', but in this example, we want to specify the order each plugin script is called. This is ideal if you have third-party scripts that rely on other third-party scripts, but keep in mind that every time you add a new plugin, you will need to update the gulpfile to include it in this task.
Second, we are going to concatenate all of the source files we specified into a single file, which we’ll name
plugins.min.js. We’ll then minify that file and put it in the main ‘js’ directory.
Compiling Custom Scripts
Our custom scripts will get their own task:
This is very similar to the plugins task, but now we’re grabbing any JS files in the
'js/custom' directory and running them through JSHint. We could run the plugin scripts through JSHint as well, but we’re assuming that any third-party plugins have been properly tested before release.
We’ll use JSHint’s default reporter, which will include any errors or potential problems in the CLI when you run this task. Then we’ll wrap all of our custom scripts in an immediately invoked function expression, or IIFE. This way, we don’t need to set this up in each individual file and all of our custom script partials are contained in one function. Just as we did for the plugin scripts, we’ll concatenate all of the partials into a single file,
script.min.js, minify it, and put it in the main ‘js’ directory.
Concatenating All Scripts
For the final piece, we’ll need to create a task to concatenate both
You’ll see that we’ve added a new parameter to the
gulp.task. Between the task name and the actual function, we can define any dependencies this task may have. In this case, we want the
custom-scripts tasks to be completed before we do anything else, so they’ve been included in brackets as the second parameter. This tells Gulp to run those two tasks before this one if they haven’t already run. We’ll then concatenate the two files into
main.js and put it in the main ‘js’ directory. Because this file concatenated two already minified files, we don’t necessarily need to minify it again, so you could just concatenate and name it
main.min.js instead of going through the extra step.
Running Gulp Tasks
You could run each task individually, like so:
But because we gave our
scripts task dependencies for the other two tasks, we only have to run the one:
This will run all three tasks any time you need to manually run them. You should also set them up in your
gulp-watch task to run all three whenever you run
I’ve used this technique on a couple of projects now and find that it works pretty well, especially in terms of code organization and simplicity. It also didn’t require much setup as I’m already using Gulp to handle Sass compilation. All I had to do was add it into my existing gulpfile, unlike other tools that require entirely different workflows. On the downside, it can be tedious to manually add in third-party scripts into the gulpfile, especially if you have a lot of them. I typically try not to rely on too many third-party scripts, so it hasn’t gotten out of control for me yet, although I can definitely see how it could.
There are a couple areas I’m still stress-testing, so let me know if you see any errors or use this method in your own projects!