gulp入門

覺得此文甚好,轉發(fā)來自[http://w3ctrain.com/2015/12/22/gulp-for-beginners/]
Gulp 是一個自動化工具,前端開發(fā)者可以使用它來處理常見任務:

  • 搭建web服務器
  • 文件保存時自動重載瀏覽器
  • 使用預處理器如Sass、LESS
  • 優(yōu)化資源,比如壓縮CSS、JavaScript、壓縮圖片

當然Gulp能做的遠不止這些。如果你夠瘋狂,你甚至可以使用它搭建一個靜態(tài)頁面生成器。Gulp真的足夠強大,但你必須學會駕馭它。
這是這篇文章的主要目的。幫助你了解Gulp的基礎用法,助你早日完成一統(tǒng)天下的大業(yè)。
在我們深入了解之前,我們先來說說為什么是Gulp。
為什么是Gulp?
類似Gulp的工具,我們通常稱之為構建工具。如今最流行的兩個構建工具是Gulp和Grunt。主要區(qū)別是你如何使用他們構建自動化工作流。與Grunt相比,Gulp更加簡潔,執(zhí)行效率更高。
讓我們繼續(xù)學習Gulp并搭建一個簡單的工作流。
搭建本地web服務器
編譯Sass
每當保存更改,自動刷新瀏覽器
優(yōu)化&壓縮資源

除此之外,你還將學會使用簡單命令鏈式調用多個任務。

安裝Gulp

安裝Gulp之前你需要先安裝Node.js。如果你還沒安裝Node,你可以在 這里 下載。
安裝完Node.js,使用Terminal(終端,win下是cmd)用下面命令安裝Gulp

$ sudo npm install gulp -g

只有mac用戶才需要sudo命令,并且不要把$符號也復制進去,這不是你的菜。

npm install

是指定從Node Package Manager(npm )安裝的命令。-g
表示全局安裝,這樣你在電腦上任何位置都能只用gulp 命令。
Mac 用戶需要管理員權限才能全局安裝,所以需要sudo。
接下來使用Gulp創(chuàng)建項目。

創(chuàng)建Gulp項目

首先,我們新建一個project文件夾,并在該目錄下執(zhí)行npm init
命令:

$ npm init

npm init命令會為你創(chuàng)建一個package.json文件,這個文件保存著這個項目相關信息。比如你用到的各種依賴(這里主要是插件)(終端會自動出現(xiàn)下面內容,這里先隨便填就行)

創(chuàng)建完之后,我們執(zhí)行下面的命令:

$ npm install gulp --save-dev

這一次,我們局部安裝Gulp。使用—save-dev,將通知計算機在package.json中添加gulp依賴。

執(zhí)行完之后,gulp將創(chuàng)建node_modules文件夾,里面有個gulp文件夾。
在這個結構中,我們使用app文件夾作為開發(fā)目錄(所有的源文件都放在這下面),dist文件夾用來存放生產環(huán)境下的內容。
這些文件名,你想怎么起都行,但請務必記住你的目錄結構?,F(xiàn)在我們來創(chuàng)建gulpfile.js。

第一個Gulp任務

(你需要先在根目錄下創(chuàng)建一個gulpfile.js文件)。

var gulp = require(‘gulp‘);

這行命令告知Node去node_modules中查找gulp包,先局部查找,找不到就去全局環(huán)境中查找。找到之后就會賦值給gulp變量,然后我們就可以使用它了。
簡單的任務如下所示:

gulp.task(‘task-name‘, function() { // Stuff here});

task-name 是給你的任務起的名字,稍后在命令行中執(zhí)行gulp task-name,將運行該任務。
寫個HelloWorld,是這樣的:

gulp.task(‘hello‘, function() { console.log(‘Hello World!‘);});

命令行中執(zhí)行:

$ gulp hello

那么將會輸出Hello World!。 夠簡單吧?
Gulp任務通常都會比這難一丁點,就一丁點。通常會包含兩個特定的Gulp方法和一些列Gulp插件。
大概這樣:

gulp.task(‘task-name‘, function () { 
     return gulp.src(‘source-files‘) 
         .pipe(aGulpPlugin()) 
         .pipe(gulp.dest(‘destination‘)) 
})

正如你所見,兩個Gulp方法,src,dest,一進一出。下面用編譯Sass來舉栗子。

Gulp執(zhí)行預處理

我們使用gulp-sass插件來編譯Sass。安裝插件的步驟是這樣的:
使用npm install 命令安裝

$ npm install gulp-sass --save-dev

在gulpfile中引入插件,用變量保存

var gulp = require(‘gulp‘);
// Requires the gulp-sass plugin
var sass = require(‘gulp-sass‘);

在任務中使用

gulp.task(‘sass‘, function(){ 
return gulp.src(‘source-files‘) 
.pipe(sass()) 
// Using gulp-sass
.pipe(gulp.dest(‘destination‘))});

我們需要給sass任務提供源文件和輸出位置。所以我們先在項目中創(chuàng)建app/scss文件夾,里面有個styles.scss文件。這個文件將在gulp.src中用到。
sass處理之后,我們希望它生成css文件并產出到app/css目錄下,可以這樣寫:

gulp.task(‘sass‘, function(){ 
return gulp.src(‘app/scss/styles.scss‘)
 .pipe(sass())
 // Converts Sass to CSS with gulp-sass
 .pipe(gulp.dest(‘app/css‘))});

測試一下:

// styles.scss
.testing { 
width: percentage(5/7);}

使用Terminal執(zhí)行gulp sass,你將看到app/css/styles.css文件下會有下面的代碼:

/* styles.css */
.testing { 
width: 71.42857%;
}

styles.css是gulp智動為我們生成的。percentage 是Sass的方法。
使用Sass就這么簡單。但是通常我們不止有一個scss文件。這時候可以使用Node通配符。

Node中的通配符

通配符是一種匹配模式,允許你匹配到多個文件。不止是Node,很多平臺都有,有點像正則表達式。
使用通配符,計算機檢查文件名和路徑進行匹配。
大部分時候,我們只需要用到下面4種匹配模式:

  • .scss:號匹配當前目錄任意文件,所以這里*.scss匹配當前目錄下所有scss文件
  • */.scss:匹配當前目錄及其子目錄下的所有scss文件。
  • !not-me.scss:!號移除匹配的文件,這里將移除not-me.scss
  • *.+(scss|sass):+號后面會跟著圓括號,里面的元素用|分割,匹配多個選項。這里將匹配scss和sass文件。

那么還是上面的栗子,改造一下:

gulp.task(‘sass‘, function() { 
return gulp.src(‘app/scss/**/*.scss‘) 
// Gets all files ending with .scss in app/scss and children dirs .pipe(sass()) 
.pipe(gulp.dest(‘app/css‘))
})

任何app下的scss文件,在執(zhí)行命令之后將生成對應的css文件存放到相應路徑。

現(xiàn)在我們能處理多個文件了,但是不想每次都要執(zhí)行命令,怎么辦?Gulp就是為懶人而生的,我們可以使用watch命令,自動檢測并執(zhí)行。

監(jiān)聽Sass文件

Gulp提供watch方法給我們,語法如下:

// Gulp watch syntax
gulp.watch(‘files-to-watch‘, [‘tasks‘, ‘to‘, ‘run‘]);

將上面的栗子再改下:

// Gulp watch syntax
gulp.watch(‘app/scss/**/*.scss‘, [‘sass‘]);

通常我們監(jiān)聽的還不只是一個文件,把它變成一個任務:

gulp.task(‘watch‘, function(){ 
gulp.watch(‘app/scss/**/*.scss‘, [‘sass‘]); 
// Other watchers
})

執(zhí)行gulp watch命令。

有了監(jiān)聽,每次修改文件,Gulp都將自動為我們執(zhí)行任務。

還不夠,修改完直接幫我刷新瀏覽器行嗎,我不想每次都要手動按Command + R;

使用Browser Sync自動刷新

Browser Sync 幫助我們搭建簡單的本地服務器并能實時刷新瀏覽器,它還能 [同時刷新多個設備]
新插件?記住!安裝,引入,使用。

$ npm install browser-sync --save-dev

這里沒有gulp-前綴,因為browser-sync支持Gulp,所以沒有人專門去搞一個給Gulp用。

var browserSync = require(‘browser-sync‘);

我們創(chuàng)建一個broswerSync任務,我們需要告知它,根目錄在哪里。

gulp.task(‘browserSync‘, function() { 
browserSync({ 
server:
 { baseDir: ‘app‘ 
},
 })
})

我們稍微修改一下之前的代碼,讓每次css文件更改都刷新一下瀏覽器:

gulp.task(‘sass‘, function() { 
return gulp.src(‘app/scss/**/*.scss‘)
 // Gets all files ending with .scss in app/scss
 .pipe(sass()) 
.pipe(gulp.dest(‘app/css‘)) 
.pipe(browserSync.reload({ stream: true }))});

現(xiàn)在我們配置好Broswer Sync了,我們需要運行這兩個命令。
我們可以在watch任務之前告知Gulp,先把browserSync和Sass任務執(zhí)行了再說。語法如下:

gulp.task(‘watch‘, [‘array‘, ‘of‘, ‘tasks‘, ‘to‘, ‘complete‘,‘before‘, ‘watch‘], function (){ 
// ...
})

應用下來是這樣:

gulp.task(‘watch‘, [‘browserSync‘, ‘sass‘], function (){ gulp.watch(‘app/scss/**/*.scss‘, [‘sass‘]);
 // Other watchers
})

現(xiàn)在你執(zhí)行gulp watch命令,在執(zhí)行完browserSync和Sass,才會開始監(jiān)聽。

并且現(xiàn)在瀏覽器的顯示的頁面為app/index.html。你修改了styles.scss之后,瀏覽器將自動屬性頁面。

不止是scss修改的時候需要刷新瀏覽器吧?再改改:

gulp.task(‘watch‘, [‘browserSync‘, ‘sass‘], function (){ gulp.watch(‘app/scss/**/*.scss‘, [‘sass‘]); 
// Reloads the browser whenever HTML or JS files change gulp.watch(‘app/*.html‘, browserSync.reload); gulp.watch(‘app/js/**/*.js‘, browserSync.reload);
});

到目前為止,我們做了下面三件事:

  • 可運轉的web開發(fā)服務
  • 使用Sass預處理器
  • 自動刷新瀏覽器

接下來說說優(yōu)化方面的技巧

優(yōu)化CSS和JavaScript文件

說到優(yōu)化的時候,我們需要想到:壓縮,拼接。也就是減少體積和HTTP次數(shù)。開發(fā)者面臨的主要問題是很難按照正確的順序合并文件。

<body> 
<!-- other stuff --> 
<script src="js/lib/a-library.js"></script>
 <script src="js/lib/another-library.js"></script>
 <script src="js/main.js"></script></body>

由于文件路徑的的不同,使用 [https://www.npmjs.com/package/gulp-concat]等插件非常困難。慶幸的是,gulp-useref 解決了這個問題。
gulp-useref會將多個文件拼接成單一文件,并輸出到相應目錄。

<!-- build:<type> <path> -->
... HTML Markup, list of script / link tags.
<!-- endbuild -->

可以是js,css,或者remove。如果你設為remove,Gulp將不會生成文件。
指定產出路徑。
我們想最終產出main.min.js??梢赃@樣寫:

<!--build:js js/main.min.js -->
<script src="js/lib/a-library.js"></script>
<script src="js/lib/another-library.js"></script>
<script src="js/main.js"></script>
<!-- endbuild -->

我們來安裝gulp-useref。

$ npm install gulp-useref --save-dev

引用

var useref = require(‘gulp-useref‘);

使用起來非常簡單:

gulp.task(‘useref‘, function(){
 return gulp.src(‘app/*.html‘) 
.pipe(useref())
 .pipe(gulp.dest(‘dist‘));});

(新版的gulp-useref已經不需要寫多余的useref.assets了)
執(zhí)行useref命令,Gulp將合并三個script標簽成一個文件,并保存到dist/js/main.min.js。
合并完之后,我們再來壓縮。使用gulp-uglify插件。
安裝

$ npm install gulp-uglify --save-dev

使用

// Other requires...
var uglify = require(‘gulp-uglify‘);
gulp.task(‘useref‘, function(){ 
return gulp.src(‘app/*.html‘) 
.pipe(uglify()) 
// Uglifies Javascript files 
.pipe(useref())
 .pipe(gulp.dest(‘dist‘))});

搞定!
注意:執(zhí)行完useref后,html中的script路徑將只剩下main.min.js。

gulp-useref同樣可以用在css上。除了壓縮,需要區(qū)分,其它內容同js一樣。所以我們使用gulp-if來做不同處理。使用gulp-minify-css壓縮css。

$ npm install gulp-if gulp-minify-css --save-dev

應用

var gulpIf = require(‘gulp-if‘);
var minifyCSS = require(‘gulp-minify-css‘);
gulp.task(‘useref‘, function(){
 return gulp.src(‘app/*.html‘) 
// Minifies only if it‘s a CSS file
 .pipe(gulpIf(‘*.css‘, minifyCSS())) 
// Uglifies only if it‘s a Javascript file 
.pipe(gulpIf(‘*.js‘, uglify())) 
.pipe(useref()) 
.pipe(gulp.dest(‘dist‘))
});

再說說如何壓縮圖片。同樣easy。

優(yōu)化圖片
使用gulp-imagemin插件。

$ npm install gulp-imagemin --save-dev

引入,使用

var imagemin = require(‘gulp-imagemin‘);
gulp.task(‘images‘, function(){ 
return gulp.src(‘app/images/**/*.+(png|jpg|gif|svg)‘)
 .pipe(imagemin()) 
.pipe(gulp.dest(‘dist/images‘))
});

(所有的gulp插件都是有相關參數(shù)可以配置,如果需要,請自行查看。)壓縮圖片可能會占用較長時間,使用 gulp-cache 插件可以減少重復壓縮。

$ npm install gulp-cache --save-dev

引入、使用

var cache = require(‘gulp-cache‘);
gulp.task(‘images‘, function(){ 
return gulp.src(‘app/images/**/*.+(png|jpg|jpeg|gif|svg)‘) 
// Caching images that ran through imagemin 
.pipe(cache(imagemin({ interlaced: true }))) .pipe(gulp.dest(‘dist/images‘))
});

接下來,我們說說發(fā)布流程。

清理生成文件

由于我們是自動生成文件,我們不想舊文件摻雜進來。使用 del

npm install del --save-dev

引入、使用

var del = require(‘del‘);
gulp.task(‘clean‘, function() { 
del(‘dist‘);
});

但是我們又不想圖片被刪除(圖片改動的幾率不大),啟用新的任務。

gulp.task(‘clean:dist‘, function(callback){ 
del([‘dist/**/*‘, ‘!dist/images‘, ‘!dist/images/**/*‘], callback)});

這個任務會刪除,除了images/文件夾,dist下的任意文件。為了知道clean:dist任務什么時候完成,我們需要提供callback參數(shù)。
在某些時候我們還是需要清除圖片,所以clean任務我們還需要保留。

gulp.task(‘clean‘, function(callback) { 
del(‘dist‘); 
return cache.clearAll(callback);})

組合Gulp任務,我們主要有兩條線路。
第一條是開發(fā)過程,我們便以Sass,監(jiān)聽文件,刷新瀏覽器。
第二條是優(yōu)化,我們優(yōu)化CSS,JavaScript,壓縮圖片,并把資源從app移動到dist。
開發(fā)任務我們上面的watch已經組裝好了。

gulp.task(‘watch‘, [‘browserSync‘, ‘sass‘], function (){
 // ... watchers
})

我們也做一個來執(zhí)行第二條線路。

gulp.task(‘build‘, [`clean`, `sass`, `useref`, `images`, `fonts`], function (){
 console.log(‘Building files‘);
})

但是這樣Gulp會同時觸發(fā)[]
的事件。我們要讓clean在其他任務之前完成。這里要用到 RunSequence 。

$ npm install run-sequence --save-dev

用法如下:

var runSequence = require(‘run-sequence‘);
gulp.task(‘task-name‘, function(callback) { 
runSequence(‘task-one‘, ‘task-two‘, ‘task-three‘, callback);
});

執(zhí)行task-name時,Gulp會按照順序執(zhí)行task-one,task-two,task-thre。RunSequence也允許你同時執(zhí)行多個任務。

gulp.task(‘task-name‘, function(callback) { 
runSequence(‘task-one‘, [‘tasks‘,‘two‘,‘run‘,‘in‘,‘parallel‘], ‘task-three‘, callback);
});

改造我們的代碼:

gulp.task(‘build‘, function (callback) { 
runSequence(‘clean:dist‘, [‘sass‘, ‘useref‘, ‘images‘, ‘fonts‘], callback )})

開發(fā)任務我們也用runSequence:

gulp.task(‘default‘, function (callback) { runSequence([‘sass‘,‘browserSync‘, ‘watch‘], callback )})

default? 如果你的任務名字叫做default,那么只需要輸入gulp命令即可執(zhí)行。
這里是我們最終的 代碼倉庫
總結
上面的的內容搭建了一個基本的Gulp工作流。還有更精彩的內容等著你去開發(fā)。這里提供些插件:
開發(fā)過程:
使用 Autoprefixer,你不再需要寫CSS瀏覽器內核前綴
增加 Sourcemaps,讓你更方便的調試Sass,coffeescript
使用 sprity創(chuàng)建精靈圖
gulp-changed 只允許通過修改的文件
BabelTraceur 寫ES6
Browserify , webpack , jspm 模塊化JavaScript
Handlebars ,Swing 模塊化Html
require-dir 分割gulpfile成多個文件
gulp-moderinizr 自動生成Modernizr腳本

優(yōu)化:
unCSS 移除多余的CSS
CSSO 更深入地優(yōu)化CSS
Critical 生成行內CSS

除了開發(fā)和優(yōu)化過程,你可以使用gulp-jasmine寫JavaScript單元測試,甚至使用gulp-rync直接部署dist文件到生產環(huán)境。
譯者的話
花了點時間去學習Gulp,這篇文章是我找到比較全面的,非常適合新手入門。
Gulp其實非常簡單,多玩一下,你就能完全掌握它了,有能力的話,可以嘗試開發(fā)Gulp插件。
我在 前端收藏夾 以及 使用gulp生成sprites圖片和樣式表 都有實踐過。不過正如作者 Zell Liew 所說,Gulp的強大之處遠不止這些,所以他出了本電子書 automating your workflow ,可以幫助你搭建屬于自己的工作流,剩下時間去喝咖啡,有興趣的可以去購買,支持作者。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Gulp簡介 最近流行前端構建工具,苦于之前使用Grunt,代碼很難閱讀,現(xiàn)在出了Gulp,真是擺脫了痛苦。發(fā)現(xiàn)了...
    小k博客閱讀 883評論 4 19
  • [轉載](https://github.com/zhonglimh/Gulp) Gulp構建前端自動化工作流 Gu...
    Gopal閱讀 438評論 0 1
  • 原文標題:Gulp for Beginners作者: Zell Liew翻譯:治電小白菜原文地址:https://...
    ZZES_ZCDC閱讀 1,682評論 6 18
  • 最近使用gulp自動化構建工具來開發(fā)網站,在此給大家分享一下使用gulp的一些使用教程。 一 gulp安裝 1、安...
    穿越人海遇見你閱讀 13,302評論 2 17
  • 這二天心情特別好,也不怪今年來精神爽自然心情也是不錯的。呵呵,來與大家分享下,真是小事。^^3月25日凌先生主動與...
    傷愛11閱讀 214評論 0 1

友情鏈接更多精彩內容