前端打包構建工具gulp快速入門

来源:http://www.cnblogs.com/chuaWeb/archive/2016/04/15/gulp.html
-Advertisement-
Play Games

因為之前一直有人給我推薦gulp,說他這裡好哪裡好的。實際上對我來說夠用就行。grunt熟悉以後實際上他的配置也不難,說到效率的話如果真是要完整打包上線也不在乎那麼幾秒時間,對於項目來說線上效率關鍵,但是線下效率只要不是讓人無法忍受頁沒有太多問題。不過不管怎麼說,需要親自用過gulp之後才能品評他和 ...


  因為之前一直有人給我推薦gulp,說他這裡好哪裡好的。實際上對我來說夠用就行。grunt熟悉以後實際上他的配置也不難,說到效率的話如果真是要完整打包上線也不在乎那麼幾秒時間,對於項目來說線上效率關鍵,但是線下效率只要不是讓人無法忍受頁沒有太多問題。不過不管怎麼說,需要親自用過gulp之後才能品評他和grunt之間的優劣。不廢話,直接上實例。

  本人自建了一個前端目錄結構,後續的例子都是以這個目錄結構為準。dest是我們打包壓縮結果保存目錄,現在是空的。以後每完成一個實例,我們就會清空一下dest目錄,保證下一個實例的結果和實例代碼對應。

  

 

1. 第一個簡單的gulp打包


  1)需要安裝nodejshttp://www.cnblogs.com/chuaWeb/p/nodejs-npm.html

  本人的nodejs工程目錄為F:\chuaNodejs(後續所有相對路徑都是相對於這個目錄)

  2) 創建package.json文件,可以使用npm init命令來創建。然後在其中的devDependencies中包含gulp相關的插件依賴。我的package.json是這樣的

 1 {
 2   "name": "my-gulp",
 3   "version": "1.0.0",
 4   "description": "demo",
 5   "dependencies": {
 6     "express": "3.x"
 7   },
 8   "devDependencies": {
 9     "gulp-clean": "^0.3.2",
10     "gulp": "^3.9.1",
11     "gulp-concat": "^2.6.0",
12     "gulp-mini-css": "^0.0.3",
13     "gulp-uglify": "^1.5.3",
14     "gulp-requirejs-optimize": "^0.3.2"
15   },
16   "scripts": {
17     "test": "echo \"Error: no test specified\" && exit 1"
18   },
19   "author": "chua",
20   "license": "ISC"
21 }

  隨著我們使用npm安裝的插件添加,裡面的內容隨之更改。

  命令行到nodejs目錄(需要系統管理員許可權,不然後續過程中會報錯)安裝gulp作為項目的開發依賴(devDependencies,當然也可以用其他方式安裝):npm install --save-dev gulp

  gulp有很多官方插件可以去查看安裝http://gulpjs.com/plugins/

  但是下麵的幾個插件基本上都要用到,可以先安裝

  gulp:這個是必須安裝的,沒有它,其它組件都用不了(註意watch組件直接集成在gulp中了,無需額外安裝watch組件)

  gulp-mini-css :壓縮css使用的

  gulp-uglify:壓縮、混淆js文件用的

  3) 在nodejs工程目錄下建一個gulpfile.js,內容為

 1 var gulp = require('gulp'),
 2     mincss = require('gulp-mini-css'),
 3     uglify = require('gulp-uglify');
 4 
 5 var src_css = './src/css',
 6     dest_css = './dest/css',
 7     src_js = './src/js',
 8     dest_js = './dest/js';
 9 
10 gulp.task('mincss', function () {
11     gulp.src(src_css+'/**/*.css')
12         .pipe(mincss())
13         .pipe(gulp.dest(dest_css));
14 });
15 
16 gulp.task('minjs', function () {
17     gulp.src(src_js+'/**/*.js')
18         .pipe(uglify())
19         .pipe(gulp.dest(dest_js));
20 });
21 
22 gulp.task('watch', function () {
23     gulp.watch(src_css+'/**/*.css',['mincss']);
24     gulp.watch(src_js+'/**/*.js',['minjs']);
25 });
26 
27 gulp.task('default',function(){
28     gulp.run('minjs','mincss');
29     gulp.run('watch');
30 });

  可以看到裡面和nodejs代碼寫法類似。

  4)命令行運行:gulp

  執行結果

  

  可以看到我們將src的js/css都壓縮打包到了對應的dest文件夾下

  註意:gulp命令和gulp default等價。而且這個時候監聽任務是一直執行著的,每當有相應的文件改動那麼就會執行相應的任務。

  5)源碼分析:

1 //註冊一個叫做mincss的任務,命令行gulp mincss可以運行這個任務
2 //需要說明的是代碼中”*”代表的是一層文件,而”**”代表要遞歸其子文件夾
3 gulp.task('mincss', function () {
4     gulp.src(src_css+'/**/*.css')//返回了src/css/下的全部(包含子文件夾里的).css文件流;gulp.src(str)返回了一個可讀的stream
5         .pipe(mincss())//執行gulp-mini-css組件任務,壓縮所有css文件流
6         .pipe(gulp.dest(dest_css));//將文件流寫入到 COMPRESS/css 里的對應路徑下;gulp.dest(str)返回一個可寫的stream
7 });

 

1 //註冊名為watch的任務
2 gulp.task('watch', function () {
3     gulp.watch(src_css+'/**/*.css',['mincss']);//監聽src/css/下的全部.css文件,若有改動則執行名為'mincss'任務
4     gulp.watch(src_js+'/**/*.js',['minjs']);//監聽src/css/下的全部.js文件,若有改動則執行名為'minjs'任務
5 });

 

1 //每個gulpfile.js里都應當有一個dafault任務,它是預設任務入口,運行gulp的時候實際只是調用該任務(從而來調用其它的任務)
2 gulp.task('default',function(){
3     gulp.run('minjs','mincss');//立刻執行'minjs','mincss'這兩個任務;gulp.run(tasks)表示運行對應的任務
4     gulp.run('watch');//立刻執行'watch'任務
5 });

  比較grunt而言,確實更容易上手。

 

2. 合併壓縮


  有些時候為了減少請求需要合併多個文件,且需要壓縮。使用uglifyconcat即可做到這一點。所以還要下載concat插件:npm install gulp-concat --save-dev

  gulpfile.js代碼

 1 var gulp = require('gulp'),
 2     uglify = require('gulp-uglify'),
 3     concat = require('gulp-concat');
 4 
 5 var src_js = './src/js',
 6     dest_js = './dest/js';
 7 
 8 gulp.task('minjs', function () {
 9     gulp.src(src_js+'/**/*.js')
10         .pipe(uglify())//壓縮
11         .pipe(concat("all.min.js"))//合併
12         .pipe(gulp.dest(dest_js));
13 });
14 
15 gulp.task('watch', function () {
16     gulp.watch(src_js+'/**/*.js',['minjs']);//監聽src/css/下的全部.js文件,若有改動則執行名為'minjs'任務
17 });
18 
19 gulp.task('default',['minjs','watch']);

  這裡文件會壓縮的順序按照字母順序並層層深入的順序壓縮到all.min.js中。

  這裡我們看到gulp.task的用法有多種,gulp.task(name[, deps], fn),deps是一個包含任務列表的數組,這些任務會在你當前任務運行之前完成。詳情參考:http://www.gulpjs.com.cn/docs/api/

 

  如果要按照指定的順序壓縮的話,你需要為gulp.src執行文件列表才行,gulp會按照文件列表數組中元素的順序壓縮。

  gulpfile.js源碼

 1 var gulp = require('gulp'),
 2     uglify = require('gulp-uglify'),
 3     concat = require('gulp-concat');
 4 
 5 var src_js = './src/js',
 6     dest_js = './dest/js';
 7 
 8 gulp.task('minjs', function () {
 9     gulp.src([src_js+'/bootstrap.min.js',src_js+'/jquery.js'])//先壓縮bootstrap,然後再壓縮jquery
10         .pipe(uglify())
11         .pipe(concat("all.min.js"))
12         .pipe(gulp.dest(dest_js));
13 });
14 
15 gulp.task('watch', function () {
16     gulp.watch(src_js+'/**/*.js',['minjs']);//監聽src/css/下的全部.js文件,若有改動則執行名為'minjs'任務
17 });
18 
19 gulp.task('default',['minjs','watch']); 

 

3. watch事件監聽


  watch組件包含在gulp中,不許另行下載。

  我們在最開始的實例中已經用過了watch的基本用法:gulp.watch(glob,tasks)

  現在來看一下另一種用法:gulp.watch(glob,callback)

  gulpfile.js源碼

 1 var gulp = require('gulp'),
 2   uglify = require('gulp-uglify'),
 3   notify = require("gulp-notify");
 4 
 5 gulp.task('minjs', function () {
 6   gulp.src('src/main.js')
 7     .pipe(uglify())
 8     .pipe(gulp.dest("dest/"));
 9 });
10 
11 gulp.task('watch', function () {
12   gulp.watch('src/main.js',function(e){
13     //e有兩個屬性type/path
14     if(e.type == "changed"){//added, changed, or deleted
15       gulp.run("minjs");
16       console.log(e.type + ": " + e.path);
17     }
18   });
19 });
20 
21 gulp.task('default',["minjs",'watch']);

  可以看到函數的參數(事件)e有兩個屬性typepath。我們可以根據他們的值去做一些定製服務。

  

  Gulp.watch()的另一個非常好的特性是返回watcher對象。利用watcher來監聽額外的事件或者向watch中添加文件。

  來看另一份gulpfile.js代碼

 1 var gulp = require('gulp'),
 2   uglify = require('gulp-uglify'),
 3   notify = require("gulp-notify");
 4 
 5 gulp.task('minjs', function () {
 6   gulp.src('src/main.js')
 7     .pipe(uglify())
 8     .pipe(gulp.dest("dest/"));
 9 });
10 
11 gulp.task('watch', function () {
12   var watcher = gulp.watch('src/main.js',["minjs"]);
13   watcher.on('change',function(e){
14     if(e.type == "changed"){
15       console.log(e.type + ": " + e.path);
16     }
17   });
18 });
19 
20 gulp.task('default',["minjs",'watch']);

  除了change事件,還可以監聽很多其他的事件:

  end 在watcher結束時觸發(這意味著,在文件改變的時候,任務或者回調不會執行)

  error 在出現error時觸發

  ready 在文件被找到並正被監聽時觸發

  nomatch 在glob沒有匹配到任何文件時觸發

  Watcher對象也包含了一些可以調用的方法:

  watcher.end() 停止watcher(以便停止執行後面的任務或者回調函數)

  watcher.files() 返回watcher監聽的文件列表

  watcher.add(glob) 將與指定glob相匹配的文件添加到watcher(也接受可選的回調當第二個參數)

  watcher.remove(filepath) 從watcher中移除個別文件

 

4. 一些gulp重要的插件


  gulp:這個是必須安裝的,沒有它,其它組件都用不了(註意watch組件直接集成在gulp中了,無需額外安裝watch組件)

  gulp-mini-css :壓縮css使用的

  gulp-uglify:壓縮、混淆js文件用的

  gulp-clean:清空文件夾

1 gulp.src(globs)
2   .pipe(clean());

  gulp-clean-css:壓縮css文件(原gulp-minify-css捨棄)

1 gulp.src('src/css/t1.css')
2   .pipe(cssmin())
3   .pipe(gulp.dest("dest/css/"));

  gulp-less:將less文件編譯成css

1 gulp.src('src/css/t.less')
2   .pipe(less())
3   .pipe(gulp.dest("dest/css/"))

  gulp-notify:加控制台描述

1 gulp.src("./src/test.ext")
2   .pipe(notify("Found file: <%= file.relative %>!"));

  gulp-autoprefixer:自動為css樣式添加相容瀏覽器的首碼

1 gulp.src('src/css/t1.css')
2         .pipe(autoprefixer({
3             browsers: ['last 2 versions', 'Android >= 4.0'],
4             cascade: true, //是否美化屬性值 預設:true 像這樣:
5             //-webkit-transform: rotate(45deg);
6             //        transform: rotate(45deg);
7             remove:true //是否去掉不必要的首碼 預設:true 
8         }))
9         .pipe(gulp.dest('dist/css'));

  gulp-template://替換變數以及動態html

  src/greeting.html

<h1>Hello <%= name %></h1>

  gulpfile.js處理

1 gulp.src('src/greeting.html')
2   .pipe(template({name: 'Sindre'}))
3   .pipe(gulp.dest('dist'))

  gulp-rename: //更改名稱

1 gulp.src('src/css/**/*.css')
2   .pipe(concat('all.css'))
3   .pipe(gulp.dest('dest/css/'))
4   .pipe(rename({ suffix: '.min' }))//添加尾碼
5   .pipe(gulp.dest('dest/css'));

  gulp-if: 邏輯判斷

 1 gulp.task('cssmin', function () {
 2   gulp.src('src/css/**/*.css')
 3     .pipe(concat('all.css'))
 4     .pipe(cssmin())
 5     .pipe(gulp.dest('dest/css'));
 6 });
 7 gulp.task('main', function () {
 8   gulp.src('src/css/**/*.css')
 9     .pipe(gif(true,cssmin()))
10     .pipe(gulp.dest('dest/css'));
11 });

  del: 刪除指定文件

del('dest/css/**/*.css')

  gulp-htmlmin: 壓縮html

1 gulp.src('src/html/*.html')
2   .pipe(htmlmin())
3   .pipe(gulp.dest('dist/html'));

  gulp-jshint : 檢查js 

1 gulp.src('src/js/*.js')
2   .pipe(jshint());

  browser-sync: 這個實際不算是gulp的一個插件,但是他實現了在發現文件被修改時會實時更新網頁的功能,很有意思,有興趣的童鞋可以研究一下

  gulp-connect:在本地啟動一個Web Server。一般來說寫前端界面代碼時想要調試都需要一個伺服器,這個伺服器解決了以往後端伺服器的問題。

1 var gulp = require('gulp'),
2   connect = require('gulp-connect');
3  
4 gulp.task('connect', function() {
5   connect.server();
6 });
7  
8 gulp.task('default', ['connect']);

  更多詳情可以參考https://www.npmjs.com/package/gulp-connect

  使用實例可以參考使用Gulp構建本地開發Web伺服器

 

5. 總結


  從速度來說:gulp比grunt要快,gulp不用重覆讀寫文件。特別是對於項目很大的情況,使用gulp打包確實是更好的選擇。

  從使用簡潔方面來說:grunt需要的配置文件,在一些時候配置文件會很多,而gulp是按任務分解的,所有的配置變成了一連串的任務,從代碼上面來說可能會比grunt簡潔一些。

  從學習成本來說:別人說gulp學習成本比grunt低,但是就本人而言,實際上兩者都很容易上手,基礎的都很簡單,更詳細的需要查官網,所以應該是差不多的。

  從成熟程度來說:grunt要比gulp成熟,grunt的插件雖然有些私人寫的導致良莠不齊,但是數量和完備性要比gulp好,甚至很多怪癖的需求都能找到相關的插件。而且一般來說越是簡潔的東西約不適合大型項目,gulp等待檢驗。所以對於大型項目建議使用成熟的grunt。

  現在來說的話,gulp的功能也是比較完備的了,基本構建都不成問題,所以對於中小型項目,按照做程式員就一定用最好的工具的標準的話,比較推薦gulp。

  gulp因為是基於流的構建,而且這個流是vinyl流,和buffer不相容,參考這篇文章http://sentsin.com/web/210.html

  gulp的一些技巧參考http://www.gulpjs.com.cn/docs/recipes/

 

  如果覺得本文不錯,請點擊右下方【推薦】!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 如何讓一個div居於頁面中間,我今天說的是讓一個div水平居中同時垂直居中,而不是簡單的top:50%,left:50%。當然,我們就按一開始的思路寫一下:top,left屬性都設為50%,看一下效果。 從我的截圖可以看出,div的左頂點剛好在頁面的中心點處。現在的思路是,如何移動div然後讓div ...
  • 編輯器載入中...49個jquery代碼經典片段,這些代碼能夠給你的javascript項目提供幫助。其中的一些代碼段是從jQuery1.4.2才開始支持的做法,另一些則是真正有用的函數或方法,他們能夠幫助你又快又好地把事情完成。如果你發現你任何可以做得更好的地方的話,歡迎把你的版本粘貼在評論中! ...
  • 設計是一個很普遍的概念,一般是可以理解為為即將做的某件事先形成一個計劃或框架。 (牛津英語詞典)中,設計是一種將藝術,體系,硬體或者更多的東西編織到一塊的主線。軟體設計,特別是作為軟體設計的次類的API設計,也是一樣的。但是API設計常常很少關註軟體發展,因為為其他程式員寫代碼的重要性要次於應用UI ...
  • position:static(靜態定位) 當position屬性定義為static時,可以將元素定義為靜態位置,所謂靜態位置就是各個元素在HTML文檔流中應有的位置 podisition定位問題。所以當沒有定義position屬性時,並不說明該元素沒有自己的位置,它會遵循預設顯示為靜態位置,在靜態 ...
  • 效果查看:http://hovertree.com/texiao/css3/6/ CSS3畫豬頭: http://hovertree.com/texiao/css3/6/1/ 代碼如下: 轉自:http://hovertree.com/h/bjaf/0pt35qks.htm 推薦:http://ho ...
  • <!DOCTYPE HTML><html><head><meta charset="UTF-8"><title>菜單滾動至頂部後固定-柯樂義</title><style type="text/css">.wrapper{width:1000px;height:2000px;margin-left:a ...
  • 代碼如下: text-overflow屬性僅是註解,當文本溢出時是否顯示省略標記。並不具備其它的樣式屬性定義。我們想要實現溢出時產生省略號的效果。還必須定義:強制文本在一行內顯示(white-space:nowrap)及溢出內容為隱藏(overflow:hidden)。只有這樣才能實現溢出文本顯示省 ...
  • 前言:調試技巧,在任何一項技術研發中都可謂是必不可少的技能。掌握各種調試技巧,必定能在工作中起到事半功倍的效果。譬如,快速定位問題、降低故障概率、幫助分析邏輯錯誤等等。而在互聯網前端開發越來越重要的今天,如何在前端開發中降低開發成本,提升工作效率,掌握前端開發調試技巧尤為重要。 本文將一一講解各種前 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...