A comprehensive and detailed gulp workflow

Source: Internet
Author: User
Development Dev

Gulp-load-plugins
Using the Gulp-load-plugins module, you can load all the Gulp modules in the Package.json file, instead of loading them one by one.

var gulp = require (' Gulp '),
    gulploadplugins = require (' Gulp-load-plugins '),
    $= gulploadplugins ();

Gulp.task (' JS ', function () {return
   gulp.src (' js/*.js ')
      . Pipe ($.jshint ())
      . Pipe ($.jshint.reporter (' Default ').
      pipe ($.uglify ()).
      Pipe ($.concat (' app.js '))
      . Pipe (Gulp.dest (' build ');
});

Generally at the beginning of the gulpfile we all gulp-load-plugins to load all the Gulp modules in.
Then we're going to define the various gulp tasks.

Gulp.task (' Default ', function (CB) {
    $.runsequence (' dev:local ', ' dev:connect ', ' Dev:watch ', CB);
});

run-sequence
The tasks in gulp are executed asynchronously, and sometimes we need a series of tasks to execute sequentially, and then we need run-sequence.

Runsequence (' Task1 ', ' task2 ', [' task3 ', ' task4 '], ' task5 ')
The Task1 is completed before the Task2 is executed, and so on.
Note that TASK3 and TASK4 are placed in brackets, which indicates that TASK3 and TASK4 can be executed concurrently, but the two are executed before the TASK5 is executed.

the point here is that each task either returns a stream, or return gulp.src (). pipe (). pipe (), or support callback functions, that is, Gulp.task (' Task1 ', function (done) { Action1 (done); To meet these two points to ensure a normal order of execution, because this is the basic requirement of gulp for asynchronous tasks.

Here we define the tasks to be executed sequentially when the Gulp command is issued, by defining the default task.

Generally in the development phase we need to complete the following several tasks: Some compile work, can be synchronized
Less/sass compile-template precompilation open Local Development Server listening for file changes

Here's a detailed note. Less/sass Compilation

The first thing to do is to compile the Less/sass source file into a CSS file so that the page can be used.

Gulp.task (' dev:less ', function () {return
    gulp.src ('/less/*.less '). Pipe ($.plumber ())
        . Pipe ($.less (
        ))
        . Pipe ($.connect.reload ())
        . Pipe (Gulp.dest ('/styles '))
}

Gulp-plumber
Prevent pipe break caused by Gulp plug-in error, generally used at the beginning of the stream.
You can pass in a function to handle errors

gulp-less
Compiling a less file into a CSS file

gulp-connet
Start a webserver, which is explained in detail later. This is used to refresh the browser every time the less is compiled

Finally we put the compiled CSS file into the target folder, the page can be referenced. Template pre-compilation

Sometimes we use templates that need to be compiled before they can be displayed on the page.
This is the use of different templates to select the appropriate gulp compiler plug-ins to use. open Local Development Server

Gulp-connect not only can start a Web server automatically, but also can monitor the changes in the file automatically refresh the browser, the liberation of F5.

Easiest to start a Web server:

Gulp.task (' webserver ', function () {
    $.connect.server ();
})

Without any configuration, you can see the index.html in the Gulpfile.js sibling directory at localhost:8080.

In order to automatically refresh the browser, we want to configure Livereload, typically the following two steps: When starting the server to run Livereload:

Gulp.task (' webserver ', function () {
    $.connect.server ({
        livereload:true
    });
})
In a task, notify Livereload when a file is updated to refresh the browser.
Here, as seen in the less mission:
Gulp.task (' dev:less ', function () {return
    gulp.src ('/less/*.less '). Pipe ($.plumber ())
        . Pipe ($.less (
        ))
        . Pipe ($.connect.reload ())
        . Pipe (Gulp.dest ('/styles '))
}

After the intermediate less compilation is complete, call $.connect.reload () to notify Livereload to refresh the browser.

In addition to Livereload, Webserver has some other basic configuration options: Root: Root directory, default to Gulpfile directory port: Ports middleware: Middleware
Sometimes we need some middleware to do some additional work.
For example, now that I use SSI in my project, I need a middleware to get the online files that SSI introduces, so I need to gulp-connect-ssi such a gulp-connect middleware.

Gulp.task (' webserver ', function () {
    $.connect.server ({
        root: _.app,
        port:80,
        livereload:true,
        middleware:function () {return
           [$.connectssi ({
                baseDir: __dirname + '/app ',
                ext: '. html '
                , Domain: ' http://example.com/', method
                : ' Readonlineifnotexist '  
                onlineencoding: ' GBK ',
                localencoding: ' UTF8 '
            }];});

We use Gulp-connect-ssi in the middleware configuration of connect to download the referenced page slices. Monitor file Changes

The Gulp.watch command allows you to perform tasks when a file changes.
Generally in a project, all want to listen to Less/sass, HTML and JS changes:

Gulp.task (' Dev:watch ', function () {
    gulp.watch (['/less/**/*.less '], [' dev:less ']);  Monitor less
    gulp.watch (['/**/*.htm? L) ', '! ' + _.app + '/tpls/**/*.html '], [' dev:html ']);
    Gulp.watch (['/tpls/**/*.html '], [' Dev: ' + _.templatepreprocessor]);
    Gulp.watch (['/scripts/**/*.js '], [' Dev:js ']);
};

For example, if we change the less file, we will execute dev:less, and the task will perform a series of operations, such as compiling, browser refresh, and so on.
And like JS and HTML file, also do not need to compile, directly refresh the browser is good.

Binding HTML Listener Callback
gulp.task (' dev:html ', function () {return
    gulp.src ('/**/*.htm? L))
        . Pipe ($.plumber (swallowerror))
        . Pipe ($.connect.reload ());
});

Binding JS Listener callback
gulp.task (' Dev:js ', function () {return
    gulp.src ('/scripts/**/*.js ')
        . PIPE ( Swallowerror))
        . Pipe ($.connect.reload ());
Compile Build

In the compile phase, we need to do further packaging and compression of the code to facilitate the use of the production environment.

What to do in the compile phase: first of all, include some compilation work in the development phase
Less/sass compilation Template precompiled empty build directory next some packaging and compression work can be synchronized, specific to see what the project used, such as:
Requirejs packaging CSS compression, sprite merging and compressing image compression processing HTML
CSS JS img Inline Open build directory webserver Requirejs package

Requirejs has an optimization tool that merges related scripts into the build layer and shrinks them by UGLIFYJS (default). Optimize CSS by @import the CSS file referenced by inline and removing annotations.

The Optimizer optimizer is part of the R.js, designed to run as part of the build or package step after development and to deploy code for the user.

Gulp.task (' Build:requirejs ', function (CB) {
    require (' Requirejs '). Optimize ({
        BaseURL: _.app + '/scripts/'),
        optimize: ' None ',
        include: [' config '],
        Mainconfigfile:_.app + '/scripts/config.js '
        , excludeshallow:[' jquery ', out
        : _.build + '/scripts/main.js ',
        preservelicensecomments:true,
        usestrict : True,
        wrap:true
    }, function () {
        CB ();   Success, notify Gulp task end
    }, function () {
        CB ();   Failure, notify Gulp task End
    });

Here we use the Requirejs optimize method and make some configuration.
The final result is the build directory under the '/scripts ' path to generate a packaged JS file, that is main.js. Sprite picture Merge, compress CSS and sprite chart

Gulp-sprite-generator
A versatile gulp Sprite, you can create a sprite based on CSS style content, and update the picture in the CSS reference.

Gulp.task (' Sprites ', function () {
    var spriteoutput;

    Spriteoutput = Gulp.src ("./src/css/*.css")
        . Pipe (Sprite ({
            baseurl:         "./src/image",
            Spritesheetname: "Sprite.png",
            spritesheetpath: "/dist/image"
        });

    SpriteOutput.css.pipe (Gulp.dest ("./dist/css"));
    SpriteOutput.img.pipe (Gulp.dest ("./dist/image"));

Here is a simple example, by configuring the path of the picture sprite generation, and finally the resulting CSS and sprite map into the compiled directory.

In practical applications, we may add some actions, such as compressing CSS and pictures:

gulp.task (' build:sprites ', function () {var spriteoutput = gulp.src (_.app + '/styles/main.css '). Pipe ($.spritegenerator ({baseurl: _.app + '/images/sprites '), Spritesheetname: ' Sprite. PNG ', Spritesheetpath: '. /images/sprites ', algorithm: ' Binary-tree ',//layout algorithm can refer to: Https://github.com/twolfson/layout filter   : [function (image) {return image.url.indexOf ('/sprites/')!==-1;

    Only process sprites directory picture}]); var spritecss = SpriteOutput.css.pipe ($.cleancss ({compatibility: ' IE7 '})//compress CSS. Pipe (gulp.dest (_.build + '/s
    Tyles/')); var spriteimg = SpriteOutput.img.pipe ($.imagemin ({//compressed Sprite progressive:true,//for JPG use: [$.imagemin
    Pngquant ({quality: ' 65-80 ', speed:4})]//png}). Pipe (Gulp.dest (_.build + '/images/sprites/'));
Return $.mergestream (Spritecss, spriteimg); });

Here again used to compress CSS, compressed pictures of some plug-ins, do not add to the details.
The final mergestream is used to merge multiple stream streams into one and return them for use by the following processes. Picture Compression

In addition to the sprite map to do processing, other than the use of Sprite pictures are also to be compressed, the use of gulp-imagemin this plug-in. working with HTML

After all the material and resources have been packaged and compressed, HTML will also be processed. Compresses all of the inline properties that contain the

<!--located at src/html/index.html-->
Src/js/inlinescript.js 

function Test () {
  var foo = ' Lorem ipsum ';
  return foo;
}

Final output:

 
Open Build directory under webserver 

There is no difference between starting the server and the development phase, except that the root directory is the compile directory build. Publish Publish

In fact, the general compiled works can already be used, but depending on how the different company deployment methods may have to do some final work. Increase the hash of these materials (JS, IMG, CSS) to change the path of the reference material in HTML will be used to upload the material to the CDN to increase the file hash

We deploy every time, JS, CSS and other files may have updates, but in the customer side because the cached relationship may not be able to see the effect of the update, we can not force users to clear cache refresh.
Adding a hash value to the online file solves this problem, and the user accesses a page that references a different material name than before, so it is certain to refer to the updated footage.

Gulp-rev
Static asset revisions by attaching content hashes to file names

Add img file hash
gulp.task (' rev:img ', function () {return
    gulp.src (_.build + '/images/**/*.png ')
        . Pipe ($. Rev ())
        . Pipe (Gulp.dest (_.dist + '/images ')). Pipe ($.rev.manifest ()) pipe (Gulp.dest (
        _.dist + '/rev/ Images '));

First $.rev () is the hash.
$.rev.manifest () maps the original path to the revision path, and the specific mapping relationship is written in a JSON file, like this:

{
    "css/unicorn.css": "Css/unicorn-d41d8cd98f.css",
    "js/unicorn.js": "Js/unicorn-273c2c123f.js"
}

Sometimes we do a compression of JS in this step, which is to use to gulp-sourcemaps.
What is Sourcemap.
Simply put, the Source map is an information file that stores location information. That is, each position of the converted code, corresponding to the position before the conversion.
With it, the debugger will display the original code directly, not the converted code, when the error occurs. This has undoubtedly brought great convenience to the developer. (We don't want to see a bunch of compressed code at the time of debugging.)
So we can insert the process of sourcemap and compression in the hash process:

Gulp.task (' Rev:js ', function () {return
    gulp.src (_.build + '/scripts/*.js ')
        . Pipe ($.sourcemaps.init ()
        ) . Pipe ($.rev ())
        . Pipe ($.uglify ({output: {ascii_only:true}}))  //Compression JS (temporarily uncompressed, etc after rev)
        . Pipe ($. Sourcemaps.write ('./')).
        Pipe (gulp.dest (_.dist + '/scripts ')).
        Pipe ($.rev.manifest ())
        . PIPE ( Gulp.dest (_.dist + '/rev/scripts '));
change the path of a reference material in HTML

We hashed the files, and we're going to change the paths in the HTML that reference them. At the same time, we can change the relative path directly to the absolute path of CDN.

Gulp-rev-collector
Replaces a link in HTML that references a static resource based on a mapping relationship in the manifest file that was previously generated by Rev.manifest ()

Gulp.task (' rev ', function () {return
    gulp.src ([' Rev/**/*.json ', ' templates/**/*.html '])
        . PIPE (Revcollector ({
            replacereved:true,
            dirreplacements: {
                ' css ': ' www.cdn.com/dist/css ', '
                /js/': ' Www.cdn.com/dist /js/',

            }
        })
        . Pipe (Gulp.dest (' dist ')
);

Where the dirreplacements option explicitly replaces the directory path. Gulp-rev generated manifest file does not have directory information and we need to configure it here. You can then refer to static resources in the correct directory when you replace them:

"/css/style.css" => "Www.cdn.com/dist/css/style-1d87bebe.css"
"/js/script1.js" => "www.cdn.com/dist/" Script1-61e0be79.js "
upload the used material to the CDN

This step will need to achieve their own spicy ~ Not much to say summary

The above is a more comprehensive and detailed gulp workflow.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.