Gulp示例

Published on 2017 - 01 - 10

we will use very basic "Hello, world!" type of examples to demonstrate how gulp accesses, modifies, and outputs our code and images.

Our project will create separate tasks that will process CSS, JavaScript, and images. For CSS, we will combine all of the files into a single file and then preprocess it to enable additional features in our code. For JavaScript, we will combine the files, check the code for errors, and minify it to reduce the overall file size. For images, we will use a plugin to compress them so that they can load more quickly and improve our project's performance.

Using gulp plugins

Without plugins, gulp is simply a means of connecting and organizing small bits of functionality. The plugins we are going to install will add the functionality we need to properly modify and optimize our code. Like gulp, all of the gulp plugins we will be using are installed via npm.

It is important to note that the gulp team cares deeply about their plugin ecosystem and spends a lot of time making sure they eliminate plugins that duplicate the functionality that has already been created. To enforce these plugin standards, they have implemented a blacklisting system that only shows the approved plugins. You can search for the approved plugins and modules by visiting plugin list.

Additionally, you can run gulp with the –-verify flag to make it check whether any of your currently installed plugins and modules are blacklisted. The plugins will be installed in the same way we installed gulp.

The styles task

The first task we are going to add to our gulpfile will be our styles task. Our goal with this task is to combine all of our CSS files into a single file and then run those styles through a preprocessor such as Sass, Less, or Myth. In this example, we will use Myth, but you can simply substitute any other preprocessor that you would prefer to use.

Installing gulp plugins

For this task, we will be using two plugins: gulp-concat and gulp-myth. As mentioned in the preceding section, we will install both of these tasks at the same time using the shortcut syntax. In addition to these plugins, we need to install gulp as well since this is the first task that we will be writing. For the remaining tasks, it won't be necessary to install gulp again, as it will already be installed locally in our project.

The command for installing gulp plugin is as follows:

npm install -g gulp gulp-concat gulp-myth

Including gulp plugins

Once complete, you will need to include references to those plugins at the beginning of your gulpfile. To do this, simply open gulpfile.js and add the following lines to it:

var gulp = require('gulp');
var concat = require('gulp-concat');
var myth = require('gulp-myth');

Writing the styles task

With these references added, we can now begin to write our styles task. We will start off with the main task method and pass a string of styles to it as its identifier. This is the main method that will wrap all of the tasks we will be creating. The code for the task() method is as follows:

gulp.task('styles', function() {
    // Code Goes Here
});

Next, you will need to tell gulp where it can find the source files that you wish to process. You instruct gulp by including a path to the file, but the path can contain globbing wildcards such as * to reference multiple files within a single directory. To demonstrate this, we will target all of the files that are inside of our css directory in our project.

gulp.task('styles', function() {
    return gulp.src('app/css/*.css')
        // Pipes Coming Soon
});

We have used the * globbing pattern to tell gulp that our source is every file with a .css extension inside of our css folder. This is a very valuable pattern that you will use throughout the writing of your tasks. Once our source has been set up, we can begin piping in our plugins to modify our data. We will begin by concatenating our source files into a single CSS file named all.css:

gulp.task('styles', function() {
    return gulp.src('app/css/*.css')
        .pipe(concat('all.css'))
        // More Pipes Coming Soon
});

In the preceding code, we added our concat reference that we included at the top of our gulpfile and passed it in a filename for the concatenated CSS file. In similar build systems, this would create a file and place it in a temporary location; however, with gulp, we can send this newly created file to the next step in our pipechain without writing out to any temporary files. Next, we will pipe in our concatenated CSS file into our preprocessor:

gulp.task('styles', function() {
    return gulp.src('app/css/*.css')
        .pipe(concat('all.css'))
        .pipe(myth())
});

Finally, to finish the task, we must specify where we need to output our file. In our project, we will be outputting the file into a folder named dist that is located inside of our root project directory. To output a file, we will use gulp's .dest()method, This expects only a single argument, namely, the directory where you would like to output your processed file. The code for the dest() function is as follows:

gulp.task('styles', function() {
    return gulp.src('app/css/*.css')
        .pipe(concat('all.css'))
        .pipe(myth())
        .pipe(gulp.dest('dist'));
});

Reviewing the styles task

Our styles task will first take in our CSS source files and then concatenate them into a single file that we have called all.css. Once they have been concatenated, we are going to pass our new all.css file into our pipe that will then preprocess it using Myth (again, you can substitute any preprocessor you prefer to use). Finally, we will save that concatenated and preprocessed file in our dist directory where we can finally include it in our website or application.

The scripts task

The second task will be to handle all of the JavaScript files in the project. The goal with this task is to concatenate the code into a single file, minify that code into a smaller file size, and check the code for any errors that may prevent it from running properly.

Installing gulp plugins

For this task, we will use three plugins: gulp-concat, gulp-uglify, and gulp-jshint to accomplish our goals. Like before, we will install these tasks using the shortcut syntax to save time. Since we installed gulp and gulp-concat locally while we were writing the styles task, it is not necessary to install them again. The command for installinguglify and jshint is as follows:

npm install -g gulp-uglify gulp-jshint

Including gulp plugins

At the top of our gulpfile, we need to add in the new gulp plugins that we have installed for this task. Once added, the top of your gulpfile should look like this:

var gulp = require('gulp');
var concat = require('gulp-concat');
var myth = require('gulp-myth');
var uglify = require('gulp-uglify'); // Newly Added
var jshint = require('gulp-jshint'); // Newly Added

Writing the scripts task

Once the references to the new gulp plugins have been added, we can begin writing the scripts task. Like with the styles task, we will begin by writing out the task wrapper; only this time, we will provide it with the string, 'scripts', as the name for the task:

gulp.task('scripts', function() {
    // Code Goes Here
});

Like before, we will need to tell gulp where the JavaScript source files are located using the .src method. We will be using the same * globbing pattern that we used before to target all of the JavaScript source files in our project directory:

gulp.task('scripts', function() {
    return gulp.src('app/js/*.js')
        // Pipes Coming Soon
});

Next, we can begin adding in the pipes and plugins that we will be using in this task. The first plugin that we will use for the scripts task is gulp-jshint. JSHint is a tool that is used to analyze JavaScript files and report any errors that could potentially break an application. The JSHint plugins also require an additional pipe that it can use to report when errors take place. For this example, we are going to use the default reporter. If any errors are found, they will be output into the command-line application from where gulp is being run:

 gulp.task('scripts', function() {
       return gulp.src('app/js/*.js')
           .pipe(jshint())
           .pipe(jshint.reporter('default'))
           // More Pipes Coming Soon
});

The next pipe we will use is gulp-concat. As you might recall, this is the same plugin we started with while building the styles task. As with CSS, we will concatenate all of the JavaScript files into a single file to reduce the number of requests that are needed to load our website:

 gulp.task('scripts', function() {
       return gulp.src('app/js/*.js')
           .pipe(jshint())
           .pipe(jshint.reporter('default'))
           .pipe(concat('all.js'))
           // More Pipes Coming Soon
});

The next plugin we will use is gulp-uglify, which will minify the code to reduce the file size of the concatenated JavaScript file. This is also an important and very valuable optimization:

 gulp.task('scripts', function() {
       return gulp.src('app/js/*.js')
           .pipe(jshint())
    .pipe(jshint.reporter('default'))
           .pipe(concat('all.js'))
    .pipe(uglify())
           // Another Pipe Coming Soon
});

Finally, like the styles task, the final pipe will use gulp's built-in .dest method to place the processed file in the project's dist directory:

gulp.task('scripts', function() {
       return gulp.src('app/js/*.js')
           .pipe(jshint())
           .pipe(jshint.reporter('default'))
    .pipe(concat('all.js'))
           .pipe(uglify())
           .pipe(gulp.dest('dist'));
});

Reviewing the scripts task

The scripts task will take in all of the JavaScript files in the js directory inside the project and then check each file for errors using the JSHint plugin. If any errors are found, they would be displayed in the command-line application using the default JSHint reporter. Next, our JavaScript files will be concatenated into a single all.js file and handed off to the minification plugin, UglifyJS, to reduce the overall size of the file. Finally, we will output the concatenated and minified file to the project's dist directory.

The images task

The third task will handle all of the image processing. This task will be a bit smaller than the first two as it will only use a single plugin. The goal for this task is to optimize our images by minifying them, which will help reduce the load times of the project.

Installing gulp plugins

To install gulp plugins, we will use only one plugin: gulp-imagemin. Like each task before it, you will need to install this locally and save it to your development dependencies.

The command for installing the imagemin plugin is as follows:

npm install -g gulp-imagemin

Including gulp plugins

With the new plugin installed, we can now add it to the top of the gulpfile along with the other code:

var gulp = require('gulp');
var concat = require('gulp-concat');
var myth = require('gulp-myth');
var uglify = require('gulp-uglify');
var jshint = require('gulp-jshint');
var imagemin = require('gulp-imagemin'); // Newly Added

Writing the images task

As you're probably now used to, we will start off the images task by including the main task wrapper and then using gulp's .src method to target all of the images in the project:

gulp.task('images', function() {
    return gulp.src('app/img/*')
        // Pipes Coming Soon
});

The only difference here is that we have not specified a file name; we are including every file that resides in the img folder. The reason for this is that throughout the course of development, it is likely that the project will use more than a single image file type. We already know that there will only be images in that directory, so by targeting all of the files, we are proactively bypassing future limitations for this task.

All that is left is to pipe in the newly added plugin followed by gulp's .dest method, which will save the optimized images into a new img folder alongside the optimized CSS and JavaScript files:

gulp.task('images', function() {
    return gulp.src('app/img/*')
        .pipe(imagemin())
        .pipe(gulp.dest('dist/img'));
});

Reviewing the images task

The images task is the smallest task yet and performs only a single action on our data. It first supplies gulp with all of the images in our project and then runs them through our imagemin plugin to minify each file and reduce their file sizes. After this is complete, the optimized files are then passed into gulp's .dest method where they are saved inside a new img folder, inside of the project's dist directory.

The watch task

So far, all of the tasks that we have written are actually only capable of running once. Once they complete, their job is considered done. However, this isn't very helpful as we would end up having to go back to our command line to run them again every time we make a change to our files. This is where gulp's .watch method comes into play. The watch method's job is to specifically look for changes to files and then respond by running tasks in relation to those changes. Since we will be focusing on CSS, JavaScript, and images independently, we will need to specify three separate watch methods as well. To better organize these watch methods, we will create an additional watch task that will serve as a reference and an easy way to organize them within our gulpfile.

Writing the watch task

Since the watch method is built into gulp as a core feature, no new plugins are needed. So we can move straight to actually writing the task itself. Additionally, we will not use the .src or .dest methods in this task as they have already been specified in the previous tasks.

As always, the first step in creating a task is to write out the main task method and provide it with a name. This task will be named watch, which is shown in the following code:

gulp.task('watch', function() {
    // Code Goes Here
});

The .watch method accepts two arguments. The first is the path to the files that we want to monitor for changes, and the second is the name of the task that you wish to run if any of those files are changed. If you wish to run multiple tasks upon changes to your watched files, you can use the .parallel and .series tasks.These methods will allow you to run the tasks together at the same time or in the order that they are specified.

For our example, this won't be necessary as we only need to run a single task for each set of watched files.With this in mind, we can now create each of our watch methods.

To watch and run a single task upon a change, you will use the following syntax:

*for Gulp 4.0 + *

gulp.task('watch', function() {
       gulp.watch('app/css/*.css', 'styles');
       gulp.watch('app/js/*.js', 'scripts');
       gulp.watch('app/img/*', 'images');
});

for Gulp 3.9

gulp.task('watch', function() {
       gulp.watch('app/css/*.css', ['styles']);
       gulp.watch('app/js/*.js', ['scripts']);
       gulp.watch('app/img/*', ['images']);
});

If your project requires you to run multiple tasks upon a change, you will use one of the following syntaxes:

for Gulp 4.0 +

gulp.watch('app/css/*.css', gulp.parallel('firstTask', 'secondTask'));
gulp.watch('app/js/*.js', gulp.series('thirdTask', 'fourthTask'));

for Gulp 3.9

gulp.watch('app/css/*.css', ['firstTask', 'secondTask']);
gulp.watch('app/js/*.js', ['thirdTask', 'fourthTask']);

Simply replace the task string with the method that you need to use for your project and then pass in all tasks that need to be ran as arguments.

The method that you use will depend on your project. If any of your tasks require another task to finish completely before moving to the next, then you must use the series method. The series method will tell gulp that each task must execute in the order that they are specified. This gives you far more control over how you execute tasks and structure your gulpfile.

In the preceding code, we created three .watch methods: one for our CSS, one for our JavaScript, and one for our images. In each of these, we provide the method with the path to those files and follow that up with the name of the task we want to run if those files are modified. When this task is run, gulp will continuously look for changes to the files located in those paths, and if any of those files change, gulp will run the task that is specified in the second argument. This will continue to happen until gulp is manually stopped.

The default task

Our final task is the default task, and it is best considered as the entry point for our gulpfile. The purpose of this task is to gather and execute any tasks that gulp needs to run by default.

Writing the default task

The default task is the smallest and the most simple task in our gulpfile and will only take up a single line of code. For this task, we only need to provide it with the name default and the name of a single task or the parallel or series methods containing the multiple tasks that we wish to run.

for Gulp 4.0+

gulp.task('default', gulp.parallel('styles', 'scripts', 'images', 'watch'));

for Gulp 3.9

gulp.task('default', ['styles', 'scripts', 'images', 'watch']);

This code will run each of our tasks once, including our watch task. The watch task will continuously check for changes to our files after the initial round of processing is complete and re-run each of our tasks when the related files change.

Completed gulpfile

Congratulations! You have written your very first gulpfile. However, this is only the beginning. Before we move on, let's take a moment to review the completed file that we created This is a great opportunity to compare your file with the code given and ensure that your code matches with what we have written so far. This may save your debugging time later!

The completed gulpfile would be as follows:

// Modules & Plugins
var gulp = require('gulp');
var concat = require('gulp-concat');
var myth = require('gulp-myth');
var uglify = require('gulp-uglify');
var jshint = require('gulp-jshint');
var imagemin = require('gulp-imagemin');
// Styles Task
gulp.task('styles', function() {
    gulp.src('app/css/*.css')
        .pipe(concat('all.css'))
        .pipe(myth())
        .pipe(gulp.dest('dist'));
});
// Scripts Task
gulp.task('scripts', function() {
       gulp.src('app/js/*.js')
           .pipe(jshint())
           .pipe(jshint.reporter('default'))
    .pipe(concat('all.js'))
           .pipe(uglify())
           .pipe(gulp.dest('dist'));
});
// Images Task
gulp.task('images', function() {
    gulp.src('app/img/*')
        .pipe(imagemin())
        .pipe(gulp.dest('dist/img'));
});
// Watch Task,  for Gulp 4.0+
gulp.task('watch', function() {
       gulp.watch('app/css/*.css', 'styles');
       gulp.watch('app/js/*.js', 'scripts');
       gulp.watch('app/img/*', 'images');
});
// Default Task, for Gulp 4.0 +
gulp.task('default', gulp.parallel('styles', 'scripts', 'images', 'watch'));

Running tasks

Now that our gulpfile is complete, it is now time to learn how to run each of the tasks that we have written. In this section, we will learn more about our default task and how to target and run any of our tasks independently.

Running the default task

In most cases, gulpfiles are created to be ran with a single one word command, gulp. Upon running this command, gulp will run the task with the name default in our gulpfile. As you may recall from the previous section, that is why it is considered to be the entry point. When running gulp like this, without any parameters, it is built to always run the default task that can be used to run any number of tasks that we wish to include.

Running a single task

Some projects may require that a task be run independently and manually as a certain step in the workflow process. If you need to run any of the tasks manually, you can do so by simply separating your gulp command with a single space and then listing the name of the task that you wish to run. For example, the following command will only run our styles task:

gulp styles

You can do this with any of the tasks that you have included in your gulpfile, even your watch or default tasks. The important thing to remember is that if you don't specify a task, then gulp will automatically choose to run the default task for you.

So, consider that you run the following code:

gulp default

This is the same as running the following:

gulp

Stopping a watch task

Tasks are designed to run through their process and once they are completed, gulp will exit and return you to your command prompt. However, using the .watch method instructs gulp to continue listening for changes to your files beyond the initial execution. So, once a task is executed that uses a .watch method, gulp will not stop unless it runs into an error or until you specifically instruct it to stop.

Reference