天天看點

Gulp安裝+使用

Gulp-基于流的自動化建構工具

利用gulp,可以快速建構項目,并減少IO操作

gulp在項目開發過程中自動執行任務,友善對目标檔案内容進行IO

官網使用指南http://www.gulpjs.com.cn/docs/getting-started/

Stream流

node.js

安裝

  1. 安裝node, node -v 檢測安裝成功
  2. (推薦cnmp) npm install cnpm -g –registry=https://registry.npm.taobao.org, cnmp -v顯示版本号
  3. cnpm install gulp -g, gulp -v顯示版本号
  4. 項目檔案根目錄建立package.json,

    package.json是基于nodejs項目必不可少的配置檔案,它是存放在項目根目錄的普通json檔案重點内容

  5. 進入項目檔案夾

    d:

    cd cperson

  6. cnpm init, 建立package.json,也可以自己手動建立
  7. 本地安裝gulp插件,全局安裝gulp是為了執行gulp任務,本地安裝gulp則是為了調用gulp插件的功能
  8. 建立gulpfile.js,gulpfile.js是gulp的配置檔案,放于根目錄
  9. 運作gulp,執行認為

    常用插件

    sass的編譯(gulp-sass)

    less編譯 (gulp-less)

    重命名(gulp-rename)

    自動添加css字首(gulp-autoprefixer)

    壓縮css(gulp-clean-css)

    js代碼校驗(gulp-jshint)

    合并js檔案(gulp-concat)

    壓縮js代碼(gulp-uglify)

    壓縮圖檔(gulp-imagemin)

    自動重新整理頁面(gulp-livereload,谷歌浏覽器親測,谷歌浏覽器需安裝livereload插件)

    圖檔緩存,隻有圖檔替換了才壓縮(gulp-cache)

    更改提醒(gulp-notify)

gulp是基于任務的

var gulp = require("gulp");

gulp.task("sync", function() {
    console.log("同步");
});

gulp.task("async", function() {
    setTimeout(function () {
        console.log("異步");
        done();
    }, 2000);
});
           

運作gulp sync, gulp async

D:\Cperson\front-end\gulp>gulp sync1
[18:32:50] Using gulpfile D:\Cperson\front-end\gulp\gulpfile.js
[18:32:50] Starting 'sync1'...
同步
[18:32:50] Finished 'sync1' after 394 μs

D:\Cperson\front-end\gulp>gulp async
[18:35:01] Using gulpfile D:\Cperson\front-end\gulp\gulpfile.js
[18:35:01] Starting 'async'...
[18:35:01] Finished 'async' after 838 μs
異步
D:\Cperson\front-end\gulp\gulpfile.js:10
        done();
        ^
           

gulp.task可以有依賴,第二個參數傳入數組,數組裡會*并行處理* gulp.task(“sync”, [“async”, “sync1”, “sync2”], function() { console.log(“done”); });

處理檔案内容

從源src到目的dest,将檔案内容和内聯樣式、腳本進行壓縮,完成.html的優化

優化

  • 頁面 js 存放在 ./static/js 下,公共的庫放在 ./static/js/lib 下,公共庫隻壓縮不合并,頁面 js 壓縮并合并。
  • 頁面 css 存放在 ./static/css 下,公共的css放在 ./static/css/common 下,公共 css 隻壓縮不合并,頁面 css 壓縮并合并。
  • 圖檔資源中小于3kb的圖檔以 base64 方式内聯,圖檔放在 ./static/img 下。

    壓縮 js

function minifyAndComboJS(name, encode, files){
  var fs = require("fs");
  var UglifyJS = require("uglify-js");
  var content = "";

  files.forEach(function(js){
    var minified = UglifyJS.minify(js).code;
    content += minified;
  });

  if(content){
    var combo = "static/js/" + name;
  }
  fs.writeFileSync(combo, content);

  gulp.src(combo)
      .pipe(gulp.dest("./dist/static/js"));
}
           

壓縮

js gulp.task("build-js-lib", function(){
  gulp.src("./static/js/lib/**/*.js")
      .pipe(through.obj(function(file, encode, cb) {
        var UglifyJS = require("uglify-js");
        var contents = file.contents.toString(encode);
        var minified = UglifyJS.minify(contents, 
          {fromString:true}).code;

        file.contents = new Buffer(minified, encode);
        cb(null, file, encode);
      }))
      .pipe(gulp.dest("./dist/static/js/lib"));
});
           

css

function minifyAndComboCSS(name, encode, files){
  var fs = require("fs");
  var CleanCSS = require("clean-css");
  var content = "";

  files.forEach(function(css){
    var contents = fs.readFileSync(css, encode);
    var minified = new CleanCSS().minify(contents).styles; 
    content += minified;
  });

  if(content){
    var combo = "static/css/" + name;
  }
  fs.writeFileSync(combo, content);

  gulp.src(combo)
      .pipe(gulp.dest("./dist/static/css"));
}
           

壓縮公共 css

gulp.task("build-common-css", function(){
  gulp.src("./static/css/common/**/*.css")
      .pipe(through.obj(function(file, encode, cb) {
        var CleanCSS = require("clean-css");

        var contents = file.contents.toString(encode);
        var minified = new CleanCSS().minify(contents).styles;  

        file.contents = new Buffer(minified, encode);
        cb(null, file, encode);
      }))
      .pipe(gulp.dest("./dist/static/css/common"));
});
           

處理圖檔

//内聯小圖檔
var imgs = $("img");
for(var i = ; i < imgs.length; i++){
  var img = $(imgs[i]);
  var src = img.attr("src");
  if(/^static\/img/.test(src)){
    var stat = fs.statSync(src);
    var ext = require("path").parse(src).ext;

    if(stat.size <= ){
      var head = ext === ".png" ? "data:image/png;base64," : "data:image/jpeg;base64,";
      var datauri = fs.readFileSync(src).toString("base64");
      img.attr("src", head + datauri);
    }
  }
}
           

壓縮 HTML

contents = $.html();

//壓縮 HTML
var HTMLMinifier = require("html-minifier").minify;

var minified = HTMLMinifier(contents, {
  minifyCSS: true,
  minifyJS: true,
  collapseWhitespace: true,
  removeAttributeQuotes: true
});
           

然後,在處理 index.html 的時候,我們可以使用 cheerio 來解析檔案,将要處理的外鍊從文檔中提取出來。

提取 js 和 css 外鍊處理

var $ = require("cheerio").load(contents, {decodeEntities: false});

//處理外鍊 css
var links = $("link");
var cssToCombo = [];

for(var i = ; i < links.length; i++){
  var link = $(links[i]);
  if(link.attr("rel") === "stylesheet"){
    var href = link.attr("href");
    if(/^static\/css\/(?!common)/.test(href)){
      cssToCombo.push(href);
      if(cssToCombo.length == ){
        link.attr("href", "static/css/index.min.css");
      }else{
        link.remove();
      }
    }
  }
}
minifyAndComboCSS("index.min.css", encode, cssToCombo);
           

//處理外鍊 js

var scripts = $("script");
var jsToCombo = [];
for(var i = ; i < scripts.length; i++){
  var s = $(scripts[i]);

  //判斷script标簽确實是js
  if(s.attr("type") == null 
    || s.attr("type") === "text/javascript"){
    var src = s.attr("src");

    if(src){
      //外鍊的js,預設隻處理以/static/開頭的資源
      if(/^static\/js\/(?!lib)/.test(src)){
        jsToCombo.push(src);
        if(jsToCombo.length == ){
          s.attr("src", "static/js/index.min.js");
        }else{
          s.remove();  
        }   
      }
    }
  }
}
minifyAndComboJS("index.min.js", encode, jsToCombo);
           

API

  1. gulp.src(glob[,options])輸出比對模式的檔案

    gulp.src(‘client/templates/*.jade’)

    .pipe(jade())

    .pipe(minify())

    .pipe(gulp.dest(‘build/minified_templates’));

    glob文法規則

    *比對任意 0 或多個任意字元

    ? 比對任意一個字元

    […] 若字元在中括号中,則比對。若以 ! 或 ^ 開頭,若字元不在中括号中,則比對

    !(pattern|pattern|pattern) 不滿足括号中的所有模式則比對

    ?(pattern|pattern|pattern) 滿足 0 或 1 括号中的模式則比對

    +(pattern|pattern|pattern) 滿足 1 或 更多括号中的模式則比對

    *(a|b|c) 滿足 0 或 更多括号中的模式則比對

    @(pattern|pat*|pat?erN) 滿足 1 個括号中的模式則比對

    ** 跨路徑比對任意字元

  2. gulp.dest(path[,options])
gulp.src('./client/templates/*.jade')
      .pipe(jade())
      .pipe(gulp.dest('./build/templates'))
      .pipe(minify())
      .pipe(gulp.dest('./build/minified_templates'));
           

能被 pipe 進來,并且将會寫檔案。并且重新輸出(emits)所有資料,是以你可以将它 pipe 到多個檔案夾。如果某檔案夾不存在,将會自動建立它

  1. gulp.task(name[, deps], fn)
gulp.task('something',function(){
        })
           

task 将以最大的并發數執行,你可以添加依賴

var gulp = require('gulp');
    // 傳回一個 callback,是以系統可以知道它什麼時候完成
    gulp.task('one', function(cb) {
    // 做一些事 -- 異步的或者其他的
    cb(err); // 如果 err 不是 null 或 undefined,則會停止執行,且注意,這樣代表執行失敗了
    });  
    // 定義一個所依賴的 task 必須在這個 task 執行之前完成
    gulp.task('two', ['one'], function() {
    // 'one' 完成後
    });

    gulp.task('default', ['one', 'two']);
           
  1. 監視檔案,并且可以在檔案發生改動時候做一些事情

gulp.watch(glob[,opts], tasks)

var watcher = gulp.watch('js/**/*.js', ['uglify','reload']);
    watcher.on('change', function(event) {
      console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
    });
           

gulp.watch(glob[,opts, cb])

gulp.watch('js/**/*.js', function(event) {
      console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
    });
           

繼續閱讀