一篇遲到的gulp文章,代碼合併壓縮,less編譯

前言

這篇文章本應該在去年17年寫的,但由於種種緣由沒有寫,其實主要是由於懶(捂臉)。gulp出來的時間已經很早了,16年的時候還很流行,到17年就被webpack
碾壓下去了,不過因爲本人接觸gulp的時候比較晚,16年的時候才據說有這麼個玩意,正真用它是在17年的時候,可是雖然如今webpack已經大行其道,咱們每一個人都
在積極去擁抱它,不過gulp在如今來講也並非一無可取,仍是有用到的地方,因此,這篇文章我以爲還有有必要寫的,就當作是爲gulp寫的最後一篇文章吧 ,作技術就是
這麼辛苦,技術更新太快,2,3年的時間就要換一撥技術,又得學習新的東西,否則面對這麼激烈的市場,就得被淘汰。廢話很少說了,下面開始正文。javascript

gulp是什麼,能作什麼

gulp是一個前端自動化流程構建工具,諸如,css,js,圖片合併壓縮,less,sass編譯,之前咱們須要手工才能完成的工做,如今只要經過gulp並結合gulp插件就能夠輕鬆的處理這些操做,極大的節省了開發時間,優化開發流程,提供生產效率。它跟gruntjs相比,gulpjs無需寫一大堆繁雜的配置參數,提供的API很是簡單,學習起來也很容易,另外,gulp是基於nodejs,是經過stream流的形式來讀取和操做數據,速度方面更快。css

gulp API

一、gulp.src()
輸出(Emits)符合所提供的匹配模式(glob)或者匹配模式的數組(array of globs)的文件。 將返回一個 Vinyl files 的 stream 它能夠被 piped 到別的插件中。html

gulp.src('client/templates/*.jade')
  .pipe(jade())
  .pipe(minify())
  .pipe(gulp.dest('build/minified_templates'));

二、gulp.dest()
能被 pipe 進來,而且將會寫文件。而且從新輸出(emits)全部數據,所以你能夠將它 pipe 到多個文件夾。若是某文件夾不存在,將會自動建立它。前端

gulp.src('./client/templates/*.jade')
  .pipe(jade())
  .pipe(gulp.dest('./build/templates'))
  .pipe(minify())
  .pipe(gulp.dest('./build/minified_templates'));

三、gulp.task()
定義一個使用 Orchestrator 實現的任務(task)。java

gulp.task('somename', function() {
  // 作一些事
});

四、gulp.watch()
監視文件,而且能夠在文件發生改動時候作一些事情。它總會返回一個 EventEmitter 來發射(emit) change 事件。node

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

整理的一些gulp插件

1、必備插件,一些基礎插件webpack

gulp-htmlmin 看到名字就能知道,這個插件是用來壓縮 HTML。PS:註釋啥的均可以去掉哦,看文檔get更多技能哈
gulp-imagemin 除了能壓縮常見的圖片格式,還能壓縮 SVG,叼叼的~
gulp-clean-css 壓縮 CSS。我本來推薦的是 gulp-minify-css,結果其首頁中已建議改用gulp-clean-css...
gulp-uglify 專業壓縮 Javascript
gulp-concat 上面幾個都是壓縮,這插件是管合併的...恭喜,「減小網絡請求」的成就達成:)
gulp-autoprefixer 給 CSS 增長前綴。解決某些CSS屬性不是標準屬性,有各類瀏覽器前綴的狀況,灰常有用
gulp-rename 修改文件名稱。好比有時咱們須要把app.js改爲app.min.js,瞬間高級了
gulp-util 最基礎的工具,但俺只用來打日誌...

2、經常使用插件,一些有用的插件,但使用場景和頻率沒那麼高的好插件git

run-sequence gulp 的 task 都是並行(異步)執行,若是碰見須要串行的場景,那麼這個插件就是必備了。偶的使用場景是:處理(壓縮、合併等等) CSS/JS、再gulp-rev、再上傳 CDN;而後使用 CDN的地址替換 HTML 中的 CSS/JS 地址,再壓縮 HTML。那麼替換 HTML 這步須在以前的工做處理完後再執行。 ** 最後要說,gulp4.0發佈後,不須要RS也能夠搞定串行任務了 **
del / gulp-clean 刪除。俺的使用場景是:JS/CSS 文件都會在壓縮後使用gulp-rev,即文件名被hash,而後再上傳到 CDN,最後俺再使用 刪除插件 把本地壓縮後的文件刪除掉,不用多餘保存。
gulp-rev 把靜態文件名改爲hash的形式。
gulp-rev-replace 配合 gulp-rev 使用,拿到生成的 manifest。json 後替換對應的文件名稱。
gulp-rev-collector 到線上環境前,我會用來配合gulp-rev使用,替換 HTML 中的路徑
gulp-rev-append 給頁面引用的靜態文件增長hash後綴,避免被瀏覽器緩存...固然,若是是使用 CDN,這個套路就不行了
gulp-connect / gulp-livereload LiveReload 的倆款插件都值得擁有,不過都各稍有學習成本,看看文檔就明白鳥
gulp-sourcemaps 處理 JavaScript 時生成 SourceMap;若是你不瞭解 SourceMap,能夠看看這篇阮一峯大神的《Source Map 詳解》
gulp-load-plugins 幫忙偷懶用的,能夠幫咱們加載插件,不用require或者import...固然,俺我的感受用了這個插件後,閱讀gulpfile.js的可讀性差了,魚和熊掌不可兼得:(
gulp-jshint JavaScript 代碼校驗
gulp-sass / gulp-less 寫 CSS 的同窗都懂哈

3、進階插件,根據業務場景的不一樣,咱們可能會用到這些插件github

babel JS 語法新特性用起來。這個插件可讓咱們用新的 標準/特性/提案 寫 JavaScript 代碼,而後再向下 轉換編譯,最終生成隨處可用的 JavaScript 代碼。更通俗的說話就是:能夠用新的規範寫代碼,通過 babel 編譯後生成沒有兼容問題的代碼。
gulp-flatten 移動指定文件,不想壓縮或者合併的時候,直接用這個插件把對應文件移動到指定文件夾。俺偶爾在內部項目會偷懶用上,圖方便:)
gulp-coffee CoffeeScript 值得去了解
gulp-markdown-pdf 把 Markdown 編譯爲 PDF
gulp-markdown 寫手的福音,能夠把 Markdown 轉成 HTML
gulp-html2md 把 HTML 編譯爲 Markdown
gulp-tinypng 超屌的圖片壓縮工具,使用 Tinypng 引擎。PS:由於 Tinypng 免費賬號有月限制,因此使用使需注意。
sprity 生成雪碧圖。稍有點學習成本,仔細閱讀文檔便可。
gulp-if 能夠在 pipe 裏面寫點邏輯了,屌不屌。舉例:好比處理 ./pub/*.js,若是文件名稱是 xxx.js,那麼不處理;更能夠用來區分當前是開發環境仍是生產環境。
gulp-file-include 俺搞內部項目的時候會用到,讓 HTML 組件化的第一小步
gulp-git 直接在 Build 時把代碼都提交到 git上了...特麼勞資懶起來連我本身都懼怕
gulp-qiniu 用於把指定文件上傳至七牛的指定路徑下(PS:首先,你得有本身的七牛帳號和空間)
gulp-notify 在控制檯中加入文字描述,build 的時候更高級有木有。固然,當須要的時候把錯誤信息也展現出來會頗有幫助。更高級的功能就須要你查看其文檔了~
gulp-plumber gulp 的錯誤處理有點坑,假如發生錯誤進程就掛了。相對的解決辦法很多,可是這個是我我的比較推薦的,比特麼在容易出錯的地方寫錯誤監聽靠譜。因此這個插件能夠阻止 gulp 插件發生錯誤致使進程退出並輸出錯誤日誌。

gulp的使用

一、在項目根目錄下建立一個名爲 gulpfile.js 的文件web

var gulp = require('gulp');
gulp.task('default', function() {
     console.log("執行第一個gulp任務")
});

輸入gulp命令執行該任務,不指定任務名稱 則默認執行default任務

二、同時執行多個任務

gulp.task('n1',function(){
    console.log("執行任務n1")
});
gulp.task('n2',function(){
    console.log("執行任務n2")
});
gulp.task('N',['n1','n2']);

三、若是有2個任務存在依賴關係,如任務A依賴任務B,在B任務執行完成以後再執行A任務

gulp.task('B',function(){
    console.log("執行任務B")
});
gulp.task('A',['B'],function(){
    console.log("任務B執行完成以後,開始執行任務A")
});

四、經過gulp.watch監聽文件變化,這裏新建一個watch task任務,用gulp.watch來監聽index.html文件,執行該task任務

gulp.task('watch',function(){
    gulp.watch('./src/index.html').on('change', function(event) {
      console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
    });
});

修改index.html文件,能夠看到控制檯輸出如下內容,event.type輸出的是changed,除此以外還有added, deleted類型

五、編譯less
這裏使用gulp-less插件

安裝  npm install --save-dev gulp-less

var less = require("gulp-less");
gulp.task('less',function(){
    console.log("開始編譯less...")
    gulp.src('./src/less/index.less')
        .pipe(less())
        .pipe(gulp.dest('./src/css'));
    console.log("less編譯完成");
});


能夠看到自動爲咱們生成了一個index同名css文件

使用gulp-postcss和autoprefixer 插件處理瀏覽器前綴,解決瀏覽器兼容性問題,沒必要手動添加css前綴,而且支持soucemap

安裝
npm install gulp-postcss --save-dev
npm install autoprefixer --save-dev
npm install gulp-sourcemaps --save-dev 

var less = require("gulp-less");
var postcss = require('gulp-postcss');
var sourcemaps   = require('gulp-sourcemaps');
var autoprefixer = require('autoprefixer');
gulp.task('less',function(){
    console.log("開始編譯less...")
    gulp.src('./src/less/index.less')
        .pipe(less())
        .pipe(sourcemaps.init())
        .pipe(postcss([autoprefixer()]))
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('./src/css'));
    console.log("less編譯完成");
});

修改less文件添加如下樣式:

.win{transform: translateX(-50%);}

執行編譯less任務,能夠看到index.css文件自動爲transform添加了瀏覽器前綴


同時也爲咱們生成了一個map格式文件

六、watch監聽less文件變化,自動執行less編譯任務

gulp.task('watch',function(){
    gulp.watch(['./src/less/index.less'],['less']);
});

當修改less文件並保存時,看到less文件已經編譯完成了

七、使用broswer-sync自動刷新瀏覽器

安裝
npm install browser-sync --save-dev
// 靜態服務器 + 監聽 less/html 文件
var browserSync = require('browser-sync').create();
gulp.task('browser-sync',['less'],function(){
    browserSync.init({
        server: {
            baseDir: "./src"   // 從這個項目的src目錄啓動服務器
        }
    });
    gulp.watch(['./src/less/index.less'],['less']);//監聽less文件
    gulp.watch("src/*.html").on('change', browserSync.reload);//監聽html文件變化 自動刷新瀏覽器
});

最後,修改html文件並保存,能夠看到瀏覽器自動刷新了
less+css瀏覽器注入
在less任務後面添加如下代碼,將less編譯後的css注入到瀏覽器裏實現更新,換句話說就是咱們修改less文件後編譯完成後的css反應到瀏覽器頁面中
.pipe(browserSync.reload({stream: true}));
添加以上代碼後,但發現仍是沒法實現刷新 ,這裏若是咱們編譯less使用了sourcemap,則沒法刷新,能夠經過gulp-filter來解決。

安裝:
npm install gulp-filter --save-dev

修改編譯less的任務,添加紅色部份內容便可

八、使用gulp-clean-css壓縮css文件並重命名

安裝:
npm install gulp-clean-css --save-dev
npm install gulp-rename --save-dev

// 壓縮css文件並重命名
var cleanCSS = require('gulp-clean-css');
var rename = require("gulp-rename");
gulp.task('minify-css',function(){
    gulp.src('./src/css/*.css')
        .pipe(rename({suffix: '.min'})) //suffix添加後綴   其餘的還有prefix , extname等
        .pipe(cleanCSS())
        .pipe(gulp.dest('./src/css'));
});

執行該task,能夠看到生成了index.min.css壓縮文件

九、爲咱們的css文件MD5命名 而且在引用的文件路徑替換
主要用到 gulp-rev 和gulp-rev-collector這兩個插件

安裝
npm install gulp-rev --save-dev
npm install gulp-rev-collector --save-dev

// 壓縮css文件並重命名
// md5文件命名  引用路徑替換
var cleanCSS = require('gulp-clean-css');
var rename = require("gulp-rename");
var rev = require('gulp-rev');         //- 對文件名加MD5後綴
var revCollector = require('gulp-rev-collector');               //- 路徑替換
gulp.task('minify-css',function(){
    console.log('開始壓縮css文件')
    return gulp.src('./src/css/*.css')
        .pipe(rename({suffix:'.min'})) //文件重命名  suffix添加後綴   其餘的還有prefix , extname等
        .pipe(cleanCSS())   //壓縮處理
        .pipe(rev())         //- 文件名加MD5後綴
        .pipe(gulp.dest('./src/css'))  //- 輸出文件本地
        .pipe(rev.manifest())          //- 生成一個rev-manifest.json    後面的文件路徑替換依據此文件內容
        .pipe(gulp.dest('./rev'));      //- 將 rev-manifest.json 保存到 rev 目錄內
    console.log('css壓縮完成...')
});

gulp運行 minify-css任務,能夠看到生成了md5命名的css壓縮文件

執行壓縮以前先刪除文件
del和gulp-clean插件 都是用於清空文件,del能夠用於替代gulp-clean,不推薦使用gulp-clean了

安裝
npm install del --save-dev

// clean任務:在執行壓縮以前先clean
var del  = require('del');
gulp.task('clean',function(cb){
  return del(['./dist']);
})

十、使用gulp-sequence插件處理同步任務
run-sequence gulp 的 task 都是並行(異步)執行,若是碰見須要串行的場景,那麼這個插件就是必備了。偶的使用場景是:處理(壓縮、合併等等) CSS/JS、再gulp-rev、再上傳 CDN;而後使用 CDN的地址替換 HTML 中的 CSS/JS 地址,再壓縮 HTML。那麼替換 HTML 這步須在以前的工做處理完後再執行。 ** 最後要說,gulp4.0發佈後,不須要RS也能夠搞定串行任務了 **

執行前端代碼自動構建,通常會分爲如下幾個步驟
1. 清理目標目錄(任務:clean)
2. 代碼壓縮打包,這其中包括對JS,CSS,HTML以及圖片的處理(任務:minify:js,minify:css,minify:html,minify:image)
3. 監控(任務:watch)

安裝
npm install --save-dev run-sequence

// 同步執行任務
var runSequence = require('run-sequence');
gulp.task('build', function() {
  runSequence('rev');
});

十一、javascript代碼壓縮
gulp-uglify

安裝
npm install gulp-uglify --save-dev
var uglify = require('gulp-uglify'); 
gulp.task('minify-js',function(){
     gulp.src('src/js/*.js')
        .pipe(uglify())  
        .pipe(gulp.dest('dist/js'));
});

壓縮以後代碼:

十二、html代碼壓縮
gulp-htmlmin

安裝
npm install gulp-htmlmin --save-dev
var htmlmin = require('gulp-htmlmin');
gulp.task('minify-html', function() {
  return gulp.src('src/*.html')
    .pipe(htmlmin({collapseWhitespace: true}))
    .pipe(gulp.dest('dist'));
});

壓縮以後代碼:

1三、圖片壓縮(包括PNG、JPEG、GIF和SVG圖片)
gulp-imagemin

安裝
npm install gulp-imagemin --save-dev
gulp.task('minify-img', function() {
  return gulp.src('src/images/*.{png,jpg,gif,ico}')
    .pipe(imagemin())
    .pipe(gulp.dest('dist/images'));
});

壓縮以前大小

壓縮以後大小

其餘參數

var imagemin = require('gulp-imagemin');
gulp.task('minify-img', function() {
  return gulp.src('src/images/*.{png,jpg,gif,ico}')
    .pipe(imagemin({
            optimizationLevel: 5, //類型:Number  默認:3  取值範圍:0-7(優化等級)
            progressive: true, //類型:Boolean 默認:false 無損壓縮jpg圖片
            interlaced: true, //類型:Boolean 默認:false 隔行掃描gif進行渲染
            multipass: true //類型:Boolean 默認:false 屢次優化svg直到徹底優化
        }))
    .pipe(gulp.dest('dist/images'));
});

1四、js代碼合併,減小http請求數量
gulp-concat

安裝
npm install gulp-concat --save-dev
var concat = require('gulp-concat');
gulp.task('jsconcat', function () {
    gulp.src('src/js/*.js')
        .pipe(concat('main.js'))//合併後的文件名
        .pipe(gulp.dest('dist/js'));
});

坑記錄

一、在編寫less文件時報如下這個錯誤,發現是由於我sublime安裝了less2css這個插件

首選項-》pageage setting找到less2css,發現default設置autocompile是true自動編譯
修改user設置將autoCompile設置爲false便可

{
  "autoCompile": true
}

二、在壓縮css文件時,生成格式有問題

在壓縮以前先清空目標文件

三、關於gulp的gulp-clean-css壓縮插件參數問題

這是告訴cleancss壓縮時要不要保留IE8及如下兼容寫法,寫compatibility:'ie7'就是保留ie7兼容寫法。。好比zoom:1;這些,不保留它就給你刪除了。。
壓縮插件不只僅是壓縮,還能優化,若是你用gulp-cssnano,還能幫你把多餘的類名和屬性合併。。等等

四、gulp中的return
在gulp這裏,返回的是gulp.src這個對象,以便接下來的回調(若是有的話)能繼續調用這個gulp.src對象,完成其餘的事情。

task的回調函數必須得有返回值
return a promise or event stream。不然程序就至關於同步的
當任務有返回以上返回值時,則任務會按必定的順序執行。

5.在開啓靜態服務器模式下,監聽文件變化,若是執行clean刪除任務會報如下錯誤

在開發環境,靜態服務器模式下,不要執行clean任務

六、gulp.watch監聽

gulp.task('watch',function(){
    gulp.watch('./stylesheets/**/*.scss',['sass']);
})

以上代碼,**是指全部深度的文件夾,包括varible和mixin

最後

總結一下,本文從gulp是什麼,gulp能作什麼出發,對gulp簡單的介紹了一下,包括gulp提供的一些API,而後整理並羅列了一些開發中經常使用到的gulp插件,
最後,就是從gulp安裝到使用詳細介紹了gulp的用法,以及使用gulp插件來構建前端自動化的開發流程。

以上在介紹gulp的使用時,我也準備了一個gulp的demo,demo代碼我已經上傳到github中,你們能夠自行下載。另外,我創建了一個gulp自動化構建工程模板,支持less編譯,html、css、js文件及圖片壓縮,自動添加瀏覽器前綴,本地開發環境下文件監聽瀏覽器自動刷新等,不須要再從新搭建gulp工程,就能夠輕鬆構建你的前端gulp自動化工做流程,代碼已上傳到github,地址https://github.com/fozero/template-gulp,若是喜歡的話,歡迎star哦~ ,若有問題也能夠在上面提issues

相關資料

https://www.gulpjs.com.cn/
http://www.javashuo.com/article/p-fyagyqmm-w.html
https://www.cnblogs.com/Darren_code/p/gulp.html
http://www.javashuo.com/article/p-fyagyqmm-w.html
https://blog.csdn.net/mjzhang1993/article/details/68485085

做者:fozero
聲明:原創文章,轉載請註明出處,謝謝!http://www.cnblogs.com/fozero/p/8994464.html 標籤:gulp

相關文章
相關標籤/搜索