原文標(biāo)題:Gulp for Beginners
作者: Zell Liew
翻譯:治電小白菜
原文地址:https://css-tricks.com/gulp-for-beginners/
原文代碼:https://github.com/zellwk/gulp-starter-csstricks
譯者注:發(fā)現(xiàn)這篇文章很棒鼠冕,所以就翻譯了,能力有限穴亏,有錯誤可以指出。
我的學(xué)習(xí)代碼https://github.com/klren0312/gulp_begin
如果覺得npm很慢可以使用cnpm典鸡。
Gulp是一個在你開發(fā)web時,幫助你完成幾個任務(wù)的工具啼肩。它經(jīng)常用來進(jìn)行一些前端任務(wù)净当,比如:
- 生成一個Web服務(wù)器
- 當(dāng)一個文件保存時,瀏覽器自動刷新
- 編譯像Sass或者LESS一樣的預(yù)處理器
- 優(yōu)化資源文件栋猖,像CSS,JavaScript和圖片等
這些并不是Gulp的全部功能净薛。如果你足夠瘋狂,你甚至可以使用Gulp創(chuàng)造一個靜態(tài)頁面生成器(我已經(jīng)做到了F牙)肃拜。所以,Gulp是非常強(qiáng)大的雌团,但是如果你想創(chuàng)建你自己的構(gòu)建流程爆班,你就要去學(xué)習(xí)如何使用Gulp。
所以這就是這篇文章所要做的辱姨。它將幫助你入門Gulp,你就可以自己探索其他任何東西戚嗅。
在我們投入Gulp的學(xué)習(xí)之前雨涛,讓我們來討論一下,為什么你可能希望使用Gulp懦胞,而不是其他相似的工具替久。
為什么選擇Gulp?
類似Gulp的工具通常被人稱作“構(gòu)建工具”躏尉,因為它們是運行任務(wù)來構(gòu)建網(wǎng)頁的工具蚯根。兩個最流行的構(gòu)建工具是Gulp和Grunt(Chris 有一篇文章關(guān)于學(xué)習(xí)Grunt)。但是這兒還有其他工具胀糜,broccoli聚焦于資源文件的編譯颅拦,是一個最常見的構(gòu)建工具之一。
這兒已經(jīng)有大量文章覆蓋Grunt和Gulp的區(qū)別以及為什么你可能使用其中一個教藻。如果你想了解更多距帅,你可以查看這篇文章,這一篇括堤,或者這篇碌秸。brunch式一個相似的工具,聚焦于資源文件以及它捆綁在一些常用的任務(wù)上悄窃,像服務(wù)器和文件監(jiān)視器讥电。
最主要的區(qū)別是你如何使用他們配置工作流。Gulp配置傾向于更短和更簡單轧抗,相對于Grunt恩敌。Gulp也傾向于運行更快。
現(xiàn)在讓我們繼續(xù)向前鸦致,以及學(xué)習(xí)如何使用Gulp配置一個工作流
我們要配置什么
在看完這篇文章后潮剪,你將擁有一個工作流涣楷,來進(jìn)行我們文章開始所說的一些任務(wù):
- 生成一個Web服務(wù)器
- 當(dāng)一個文件保存時,瀏覽器自動刷新
- 編譯像Sass或者LESS一樣的預(yù)處理器
- 優(yōu)化資源文件抗碰,像CSS,JavaScript和圖片等
你也將學(xué)習(xí)如何使用容易理解和執(zhí)行的命令行,將不同的任務(wù)捆綁在一起狮斗。
讓我們開始在你的電腦上安裝Gulp吧。
安裝Gulp
在你安裝Gulp之前弧蝇,需要安裝Node.js(Node)環(huán)境碳褒。
如果你沒有安裝,你可以在這個網(wǎng)頁來獲取安裝包看疗。
當(dāng)你安裝好Node后沙峻,你可以通過使用下列命令行來安裝Gulp。
$sudo npm install gulp -g
提示:只有Mac用戶需要sudo(看Pawel Grzybek的評論两芳,如果你不想使用sudo)摔寨。上面的“$"只是代表命令行,沒有特殊意義怖辆。
npm install
命令是复,使用Node Package Manager(npm)來安裝Gulp。
-g
標(biāo)志代表這個安裝時全局安裝到你的電腦上竖螃,這就運行你在電腦的任何地方都能使用gulp淑廊。
Mac用戶需要額外的sudo
,因為他們需要管理員權(quán)限來全局安裝Gulp。
現(xiàn)在你已經(jīng)安裝好了Gulp特咆,讓我們使用Gulp來創(chuàng)建一個項目吧季惩。
創(chuàng)建一個Gulp項目
第一步,本次教程腻格,我們要創(chuàng)建一個叫project
文件夾作為我們的根目錄画拾。在目錄里運行npm init
命令行來初始化項目。
npm init
命令行創(chuàng)建一個package.json
文件菜职,用來保存關(guān)于項目的信息碾阁,比如一些在項目中使用的依賴(Gulp就是一個依賴)。
npm init
將提示你:
一旦package.json
文件創(chuàng)建后些楣,我們可以使用下面命令行脂凶,在項目中安裝Gulp
$npm install gulp --save-dev
這時候,我們就將Gulp安裝到項目里了愁茁,而不是全局安裝蚕钦,這就是為什么命令行有些不一樣。
你將會看到在這里不需要sudo
鹅很,因為我們沒有全局安裝Gulp嘶居,所以-g
也是不需要的。我們增加--save-dev
,來告訴計算機(jī)增加gulp
到package.json
到dev依賴。
如果你查看項目文件夾邮屁,在命令執(zhí)行結(jié)束但壮,你應(yīng)該能看到Gulp在node_modules文件夾里僵朗。
我們差不多可以開始使用Gulp來工作了,在我們做這個之前,我們還要了解我們?nèi)绾卧陧椖恐惺褂肎ulp博杖,以及確定項目的目錄結(jié)構(gòu)粒竖。
決定項目文件夾結(jié)構(gòu)
Gulp對于很多文件夾結(jié)構(gòu)都可以足夠靈活的使用宏赘。在對項目結(jié)構(gòu)進(jìn)行調(diào)整之前蒋荚,你只需要理解內(nèi)部工作原理。
對于這篇文章戈钢,我們將使用以下結(jié)構(gòu)來構(gòu)建項目:
|- app/
-----|- css/
-----|- fonts/
-----|- images/
-----|- index.html
-----|- js/
-----|- scss/
|- dist/
|- gulpfile.js
|- node_modules/
|- package.json
在這個結(jié)構(gòu)里痹仙,我們將使用app
文件夾用于開發(fā)目的,當(dāng)dist
文件夾內(nèi)包括了優(yōu)化后的文件殉了,用于生產(chǎn)時候的頁面开仰。
自從app
被用來開發(fā)目的后,我們所有的代碼都要放到app
文件夾中薪铜。
我們將不得不保持目錄結(jié)構(gòu)當(dāng)我們運行我們的Glup配置《端現(xiàn)在,讓我們開始在gulpfile.js
中痕囱,創(chuàng)建我們第一個Gulp任務(wù)。
編寫你的第一個Gulp任務(wù)
第一步是在gulpfile中require
Gulp
var gulp = require('gulp');
這個require聲明告訴Node在node_modules
中尋找名為gulp
的包暴匠。一旦包被找到鞍恢,我們就將它里面內(nèi)容賦值到變量gulp
中。
我們現(xiàn)在可以開始使用gulp
變量寫一個gulp任務(wù)每窖。一個gulp任務(wù)的基本語法是:
gulp.task('task-name',function(){
//stuff here
})
task-name
指的是任務(wù)的名稱帮掉,當(dāng)你在Gulp中運行這個任務(wù)時,將會使用這個名稱窒典。你也可以在命令行中運行相同的任務(wù)蟆炊,通過gulp task-name
為了測試它,讓我們創(chuàng)建一個hello
任務(wù)瀑志,來說Hello Zell!
gulp.task('hello', function(){
console.log('Hello Zell!');
});
我們可以在命令行中通過gulp hello
來運行這個任務(wù)
$gulp hello
命令行將會返回一個日志涩搓,打印出Hello Zell!
Gulp任務(wù)通常要比這個復(fù)雜一點。它通常包括兩個附加的Gulp時間劈猪,加上各種各樣的Gulp插件昧甘。
這兒是一個真實任務(wù)的樣子
gulp.task('task-name',function(){
return gulp.src('source-files')
.pipe(aGulpPlugin())
.pipe(gulp.dest('destination'))
});
正如你能看到的,一個真實的任務(wù)有兩個額外的事件gulp.src'和
gulp.dest战得。
gulp.src告訴Gulp任務(wù)充边,所要使用的文件。
gulp.dest`告知當(dāng)任務(wù)完成后常侦,Gulp輸出文件的地址浇冰。
讓我們來嘗試構(gòu)造一個真實的任務(wù)贬媒,將Sass文件編譯成CSS文件。
Gulp預(yù)處理
在Gulp中肘习,我們可以將Sass編譯成CSS际乘,使用一個叫做gulp-sass的插件。你可以安裝gulp-sass到你的項目中井厌,通過使用以下命令
$ npm install gulp-sass --save-dev
在我們使用插件之前蚓庭,我們需要從node_moudles
文件夾中require
gulp-sass,就像我們引入gulp一樣
var gulp = require('gulp');
// Requires the gulp-sass plugin
var sass = require('gulp-sass');
我們可以使用gulp-sass通過將aGulpPlugin()
替換成sass()
,因為任務(wù)用來將Sass編譯成CSS仅仆,所以讓我們將他命名為'sass'
gulp.task('sass', function(){
return gulp.src('source-files')
.pipe(sass())
.pipe(gulp.dest('destination'));
});
我們需要提供給sass
任務(wù)原始文件以及目標(biāo)路徑器赞,來使任務(wù)工作。所以讓我們在app/scss
文件夾中創(chuàng)建一個styles.scss
文件墓拜。這個文件將會被加入到sass
任務(wù)中的gulp.src
中港柜。
我們想輸出最后的styles.css
文件到app/css
文件夾,我們就要將其加入到gulp.dest
的destination
處咳榜。
gulp.task('sass',function(){
return gulp.src('app/scss/styles.scss')
.pipe(sass())
.pipe(gulp.dest('app/css'))
})
我們想測試sass
任務(wù)是否能像我們預(yù)想的工作夏醉。我們可以在styules.scss
中增加一個Sass函數(shù)
.testing{
width:percentage(5/7;
}
如果你在命令行中運行gulp sass
,你應(yīng)該就能看到app/css
中會有一個styles.css
文件被創(chuàng)建涌韩。此外畔柔,它代碼中的percentage(5/7)
被計算出來了71.42857%
/* styles.css */
.testing{
width: 71.42857%;
}
我們知道了sass
任務(wù)是如何工作。
有時我們需要能夠編譯多個.scss
文件成CSS文件臣樱。我們可以在Node globs的幫助下完成(globs參數(shù)是文件匹配模式靶擦,類似正則表達(dá)式,用來匹配文件路徑包括文件名)。
供參考:Gulp-sass使用LibSass來將Sass轉(zhuǎn)換成CSS雇毫。這比基于Ruby的方法要快玄捕。如果你希望Ruby方法,你也可以使用gulp-ruby-sass或者gulp-compass插件來代替棚放。
Node的Globbing
Globs是匹配文件模式枚粘,允許你在gulp.src
中增加多個文件。它就像正則表達(dá)式一樣飘蚯,但是只用來表示文件路徑馍迄。
當(dāng)你使用glob,計算機(jī)檢查文件名和路徑以特定的特征局骤。如果特征存在柬姚,文件就會被匹配。
大部分Gulp工作流傾向于只要求4個不同的匹配模式庄涡。
1.*.scss
:*
特征是一個通配符量承,用來匹配當(dāng)前路徑中的一些特征文件。倘若這樣,我們將匹配根路徑下撕捍,所有以.scss
為后綴名的文件
2.**/*.scss
:這是一個更極端版本的*
特征拿穴,匹配在根路徑和一些子路徑的以.scss
結(jié)尾的文件
3.!not-me.scss
:!
表明,Gulp應(yīng)該排除這個匹配的特征忧风,當(dāng)你要在匹配的文件中默色,排除一個文件,是非常有用的狮腿。倘若這樣腿宰,not-me.scss
將被排除出匹配。
4.*.+(scss|sass)
:加號+
和括號()``允許Gulp匹配大量的特征缘厢,不同的特征使用
|分隔開吃度。倘若這樣,Gulp將匹配根目錄下所有以
.scss或者
.sass`結(jié)尾的文件贴硫。
在我們現(xiàn)在知道glob之后椿每,我們可以將app/scss/styles.scss
替換成scss/**/*.scss
,這樣可以匹配app/scss
或者子路徑下的.scss
文件。
gulp.task('sass', function(){
return gulp.src('app/scss/**/*.scss)
.pipe(sass())
.pipe(gulp.dest('app/css'))
})
其他在app/scss
文件夾下找到的Sass文件英遭,將自動被包括到sass
任務(wù)中间护。如果你增加一個print.scss
文件到項目中,你將看到print.css
被創(chuàng)建到app/css
挖诸。
我們現(xiàn)在可以通過一個命令汁尺,管理所有Sass文件編譯成CSS文件。但是問題是多律,有什么可以讓我們不用每次都手動運行gulp sass
痴突,將Sass編譯成CSS?
監(jiān)視Sass文件更改
Gulp提供我們一個watch
方法菱涤,監(jiān)視是否有文件更改。watch
文件的語法是:
//Gulp watch syntax
gulp.watch('files-to-watch',['tasks','to','run']);
如果我們希望監(jiān)視多個Sass文件以及運行sass
任務(wù)洛勉,當(dāng)一個Sass文件被保存粘秆,我們只要將files-to-watch
替換成app/scss/**/*.scss
,將['task','to','run']
替換成[
sass]
:
//Gulp watch syntax
gulp.watch('app/scss/**/*.scss',['sass']);
雖然更多時候,我們希望同時監(jiān)視多種類型文件收毫。為了實現(xiàn)攻走,我們可以將多個監(jiān)視進(jìn)程加入到一個組里,放到一個watch
任務(wù):
gulp.task('watch',function(){
gulp.watch('app/scss/**/*.scss',['sass']);
//other watchers
});
如果你在命令行中運行gulp watch
此再,你將立即看到看Gulp的監(jiān)視昔搂。
它將自動運行sass
任務(wù),當(dāng)你保存一個.scss
文件输拇。
讓我們來進(jìn)行下一步摘符,以及讓Gulp重新加載瀏覽器,當(dāng)我們保存一個.scss
文件,通過Browser Sync逛裤。
Browser Sync的實時加載
Browser Sync使開發(fā)Web更加容易瘩绒,通過創(chuàng)建一個Web服務(wù)器,幫助我們更容易的實時加載带族。它有其他的特性锁荔,比如跨多設(shè)備同步操作。
我們首先要安裝Browser Sync:
$ npm install browser-sync --save-dev
你或許會注意到蝙砌,當(dāng)我們安裝Browser Sync時阳堕,沒有gulp-
前綴。這是因為Browser Sync與Gulp兼容择克,所以我們不需要用到插件恬总。
要使用Browser Sync,我們要require
Browser Sync
var browserSync = require('browser-sync').create();
我們需要創(chuàng)建一個browserSync
任務(wù)祠饺,讓Gulp生成一個服務(wù)器用于Browser Sync越驻。因此我們運行一個服務(wù)器,我們需要讓Browser Sync 知道服務(wù)器的根目錄道偷。在我們的例子中缀旁,就是app
文件夾:
gulp.task('browserSync',function(){
browserSync.init({
server: {
baseDir:'app'
},
})
})
我們也需要稍微改變我們的sass
任務(wù),讓Browser Sync能夠注入新的CSS樣式(更新CSS)到瀏覽器勺鸦,當(dāng)sass
任務(wù)運行時并巍。
gulp.task('sass',function(){
return gulp.src('app/scss/**/*.scss')
.pipe(sass())
.pipe(gulp.dest('app/css'))
.pipe(browserSync.reload({
stream: true
}))
});
我們已經(jīng)配置好了Browser Sync。現(xiàn)在换途,我們需要同時運行watch
和browserSync
任務(wù)來進(jìn)行實時加載懊渡。
這個將要笨重的打開兩個命令行窗口以及獨立運行gulp browserSync
和gulp watch
,所以军拟,讓我們使用Gulp來讓他們一起運行剃执,通過告知watch
任務(wù),browserSync
必須在watch
之前完成后懈息,watch
才能運行肾档。
我們能做到,通過給watch
任務(wù)添加第二參數(shù)辫继。語法如下:
gulp.task('watch', ['array', 'of', 'tasks', 'to', 'complete','before', 'watch'], function (){
// ...
})
在這種情況下怒见,我們添加了browserSync任務(wù)。
gulp.task('watch',['browserSync'],function(){
gulp.watch('apjp/scss/**/*.scss',['sass']);
//other watchers
})
我們也希望確定sass
在watch
之前運行姑宽,所以CSS將在我們運行Gulp命令時遣耍,是最新的。
gulp.task('watch',['browserSync','sass'],function(){
gulp.watch('app/scss/**/*.scss',['sass']);
// other watchers
});
現(xiàn)在炮车,如果你在命令行中運行gulp watch
,Gulp會同時開啟sass
和browserSync
任務(wù)舵变。當(dāng)兩個任務(wù)都完成后酣溃,watch
將會運行。
同時棋傍,一個顯示app/index.html文件的瀏覽器窗口也將突然彈出救拉。如果你改變了styles.scss文件,你將會看到瀏覽器自動刷新效果瘫拣。
在我們結(jié)束這個實時更新小節(jié)之前亿絮,還有一個件事情。既然我們已經(jīng)監(jiān)視了.scss
文件麸拄,并重新加載派昧,為什么不更進(jìn)一步,當(dāng)HTML文件和JavaScript文件保存后拢切,重新加載瀏覽器呢蒂萎?
我們可以通過增加兩個監(jiān)視進(jìn)程,以及當(dāng)一個文件保存后淮椰,喚起browserSync.reload
函數(shù)五慈。
gulp.task('watch',['browserSync','sass'], function(){
gulp.watch('app/scss/**/*.scss',['sass']);
//Reloads the browser whenever HTML or JS files changes
gulp.watch('app/*.html',browserSync.reload);
gulp.watch('app/js/**/*.js', browserSync.reload);
});
到目前為止,在這個教程中主穗,我們已經(jīng)處理了三件事:
1.創(chuàng)建一個開發(fā)用的WEB服務(wù)器
2.使用Sass編譯器
3.當(dāng)文件改變后泻拦,自動重新加載瀏覽器
讓我們進(jìn)入下一屆,討論優(yōu)化資源文件的部分忽媒。我們將從優(yōu)化CSS和JavaScript文件開始争拐。
優(yōu)化CSS和JavaScript文件
當(dāng)我們嘗試優(yōu)化CSS和JavaScript文件給生產(chǎn)使用,開發(fā)者有兩個任務(wù)來執(zhí)行:壓縮和串聯(lián)晦雨。
開發(fā)者面對一個問題是架曹,當(dāng)自動化運行這個進(jìn)程時,很難將你的腳本串聯(lián)成正確的順序闹瞧。
比如說我們在index.html
有三個腳本標(biāo)簽
<body>
<script src="js/lib/a-library.js"></script>
<script src="js/lib/another-library.js"></script>
<script src="js/main.js"></script>
</body>
這些腳本在兩個不同的路徑绑雄。這將很難使用傳統(tǒng)的插件(比如gulp-concatenate)來鏈接他們。
很感激奥邮,這兒有一個有用的Gulp插件万牺,gulp-useref解決了這個問題。
Gulp-useref 連接一定數(shù)量的CSS和JavaScript文件在一個單獨的文件里漠烧,通過尋找一個注釋杏愤,以“”.他的語法是:
<!-- build:<type> <path> -->
<!-- endbuild -->
<type>
可以為js
,css
或者remove
靡砌。最好設(shè)置type
為你試圖連接的文件的類型已脓。如果你設(shè)置type
為remove
,Gulp將移除整個構(gòu)件塊,而不生成文件通殃。
<path>
指的是生成文件的目標(biāo)地址度液。
我們希望最終生成的js文件在js
文件夾厕宗,名為main.min.js
.因此標(biāo)記應(yīng)為:
<!-- 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 -->
現(xiàn)在讓我們在gulpfile中配置gulp-useref插件。我們將安裝這個插件堕担,然后在gulpfile中引入它已慢。
$ npm install gulp-useref --save-def
var useref = require('gulp-useref');
設(shè)置useref
任務(wù)和我們到目前為止設(shè)置的其他任務(wù)相似。這兒是代碼:
gulp.task('useref',function(){
return gulp.src('app/*.html')
.pipe(useref())
.pipe(gulp.dest('dist'))
});
現(xiàn)在如果你運行這個useref
任務(wù)霹购,Gulp將貫穿三個腳本標(biāo)簽佑惠,以及連接他們到dist/js/main.min.js
.
但是這個文件現(xiàn)在并沒有被壓縮。我們將使用gulp-uglify插件齐疙,來壓縮JavaScript文件膜楷。我們也需要另一個插件,叫gulp-if贞奋,但是我們只能試圖去壓縮JavaScript文件赌厅。
$ npm install gulp-uglify --save-dev
var uglify = require('gulp-uglify');
var gulpIf = require('gulp-if');
gulp.task('useref', function(){
return gulp.src('app/*.html')
.pipe(useref())
.pipe(gulpIf('*.js',uglify()))
.pipe(gulp.dest('dist')
});
Gulp現(xiàn)在應(yīng)該自動壓縮main.min.js
文件,當(dāng)你運行useref
任務(wù)轿塔。
還有一件有關(guān)Gulp-useref的使沒有透露特愿,就是它自動改變所有在 ""中的標(biāo)簽成'js/main.min.js'.
很棒是不是!
我們可以使用相同的方法來連接CSS文件(如果你打算增加多個)勾缭。我們將遵循相同的進(jìn)程以及增加一個build
注釋揍障。
<!--build:css css/styles.min.css-->
<link rel="stylesheet" href="css/styles.css">
<link rel="stylesheet" href="css/another-stylesheet.css">
<!--endbuild-->
我們也要壓縮連接后的CSS文件。我們需要使用一個叫做gulp-cssnano的插件來幫助我們壓縮漫拭。
$ npm install gulp-cssnano
var cssnano = require('gulp-cssnano');
gulp.task('useref',function(){
return gulp.src('app/*.html')
.pipe(useref())
.pipe(gulpIf('*.js',uglify()))
.pipe(gulpIf('*.css',cssnano()))
.pipe(gulp.dest('dist'))
});
現(xiàn)在當(dāng)你運行useref
任務(wù)亚兄,你將得到一個優(yōu)化后的CSS文件以及一個優(yōu)化后的JavaScript文件。
讓我們繼續(xù)來優(yōu)化圖片采驻。
優(yōu)化圖片
你可能已經(jīng)猜到了审胚;我們需要使用gulp-imagemin來幫助我們壓縮圖片。
$ npm install gulp-imagemin --save-dev
var imagemin = require('gulp-imagemin');
通過gulp-imagemin的幫助礼旅,我們能壓縮png
,jpg
,gif
甚至使svg
膳叨。讓我們創(chuàng)建一個images
任務(wù)來完成這個壓縮進(jìn)程。
gulp.task('images',function(){
return gulp.src('app/images/**/*.+(png|jpg|gif|svg)')
.pipe(imagemin())
.pipe(gulp.dest('dist/iamges'))
}
由于不同文件類型要使用不同的方式壓縮痘系,你或許要在imagemin
中增加選項菲嘴,來自定義如何壓縮文件。
比如你可以通過設(shè)置interlaced
選項為true汰翠,來創(chuàng)建 interlacedGIFs
gulp.task('images', function(){
return gulp.src('app/images/**/*.+(png|jpg|jpeg|gif|svg)')
.pipe(imagemin({
// Setting interlaced to true
interlaced: true
}))
.pipe(gulp.dest('dist/images'))
});
你可以玩玩其他選項龄坪,如果你希望的話。
壓縮圖片复唤,是一個極其緩慢的進(jìn)程健田,除非必要,你是不會想重復(fù)的佛纫。為了做好這個妓局,我們可以使用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'))
});
我們幾乎完成了優(yōu)化進(jìn)程。這兒有多個文件夾好爬,我們需要從app
文件夾編譯到dist
文件夾中局雄,比如字體文件夾。讓我們來做這件事存炮。
將字體文件夾賦值到Dist文件夾
由于字體文件已經(jīng)壓縮了炬搭,所以我們不需要做額外的事。我們需要做的就是將字體復(fù)制到dist
穆桂。
我們可以使用Gulp復(fù)制文件通過gulp.src
和gulp.dest
尚蝌,不需要其他插件。
gulp.task('fonts', function() {
return gulp.src('app/fonts/**/*')
.pipe(gulp.dest('dist/fonts'))
})
現(xiàn)在當(dāng)你運行gulp fonts
,Gulp將會復(fù)制字體文件到dist
中充尉。
現(xiàn)在我們有六個不同的任務(wù)在gulpfile中飘言,以及他們每個都需要單獨調(diào)用一個命令行,這是有點麻煩的驼侠,所以我們希望把所有都放到一個命令中姿鸿。
在我們做那個之前,讓我們來看看如何自動清理生成的文件倒源。
自動清理生成的文件
由于我們自動生成文件苛预,我們希望確定那些不再使用的文件不保留在我們不知道的地方。
這個進(jìn)程被叫做清理(或者用更簡單的術(shù)語來說笋熬,刪除文件)
我們將使用del幫助我們完成清理热某。
$ npm install del --save-dev
var del = require('del');
del
函數(shù)接受一組node globs數(shù)組,告知那些文件夾需要刪除胳螟。
在Gulp任務(wù)中設(shè)置它就和我們第一個“hello”的示例一樣昔馋。
gulp.task('clean:dist',function(){
return del.sync('dist');
})
現(xiàn)在當(dāng)你運行gulp clean:dist
時,Gulp將刪除dist
文件夾糖耸。
提示:我們不必?fù)?dān)心刪除dist/images
文件夾秘遏。因為gulp-cache已經(jīng)存儲了圖片的緩存在你本地系統(tǒng)里。
要在你本地系統(tǒng)中刪除緩存嘉竟,你要創(chuàng)建一個單獨的任務(wù)邦危,叫做cache:clear
gulp.task('cache:clear',function(callback){
return cache.clearAll(callback)
})
Phew, that's a mouthful(真繞口?)∩崛牛現(xiàn)在讓我們把所有任務(wù)都組合到一起吧倦蚪。
組合Gulp任務(wù)
讓我們總結(jié)一下我們做的吧。到目前為止边苹,我們創(chuàng)建了兩個不同Gulp任務(wù)集陵且。
第一個任務(wù)集是一個開發(fā)進(jìn)程,我們可以用它編譯Sass到CSS勾给,監(jiān)視文件的修改滩报,從而重新加載瀏覽器。
第二個任務(wù)集是壓縮進(jìn)程播急,我們?yōu)樯a(chǎn)網(wǎng)站準(zhǔn)備了所有文件脓钾。我們壓縮資源文件,像CSS,JavaScript和圖片在這個進(jìn)程以及從app
文件夾復(fù)制字體文件到dist
文件夾桩警。
我們已經(jīng)將第一個任務(wù)集集合到一個簡單的工作流可训,通過gulp watch
命令:
gulp.task('watch',['browserSync','sass'], function(){
//...watchers
})
第二個任務(wù)集包括我們需要運行來生成生產(chǎn)用的網(wǎng)頁的任務(wù)。這包括了clean:dist
,sass
,useref
,images
和fonts
捶枢。
如果我們有同樣的思路握截,我們能創(chuàng)建一個build
任務(wù)來聯(lián)系所有。
gulp.task('build', ['clean:dist','sass','useref','images','fonts'], function(){
console.log('building files');
})
不幸的是烂叔,我們這樣構(gòu)建build
任務(wù)谨胞,因為這樣會導(dǎo)致Gulp將第二個參數(shù)全部同時運行。
這可能會使useref
,images
或者甚至fonts
在clean
之前運行完成蒜鸡,這就意味著胯努,最后整個dist
文件夾被刪除。
所以要確定刪除任務(wù)要在所有任務(wù)之前完成逢防,我們需要使用一個額外的插件叶沛,叫做Run Sequence。
$ npm install run-sequence --save-dev
這是一個使用run-sequence的任務(wù)隊列的語法:
var runSequence = require('run-sequence');
gulp.task('task-name',function(callback){
runSequence('task-one','task-two','task-three',callback);
});
當(dāng)task-name
被喚起忘朝,Gulp將先運行task-one
.當(dāng)task-one
結(jié)束后灰署,Gulp將自動啟動task-two
.最后當(dāng)task-two
完成后,Gulp將運行task-three
Run Requence 也允許你同時運行任務(wù)局嘁,如果你把他們放在一個數(shù)組里:
gulp.task('task-name',function(callback){
runSequence('task-one',['tasks','two','run','in','parallel'],'task-three',callback);
})
在這種情況下溉箕,Gulp第一個運行task-one
.當(dāng)task-one
完成后,Gulp同時運行第二個參數(shù)里每個任務(wù)悦昵。第二個參數(shù)中所有任務(wù)運行完成后约巷,task-three
才能運行。
所以我們現(xiàn)在能創(chuàng)建一個任務(wù)旱捧,確定clean:dist
第一個運行独郎,然后其他任務(wù)運行:
gulp.task('build',function(callback){
runSequence('clean:dist',['sass','useref','images','fonts'],
callback
);
});
為了保持事情的一致性,我們也構(gòu)建相同的隊列在第一組枚赡。讓我們使用default
作為任務(wù)名:
gulp.task('default',function(callback){
runSequence(['sass','browserSync','watch'],
callback
);
})
為什么用default
?因為當(dāng)你有個任務(wù)叫default
,你就可以很簡單的使用gulp
命令運行氓癌,會省去鍵盤的敲擊次數(shù)。贫橙。贪婉。
最后這里是一個Github repo,里面都是我們所做的工作卢肃。
結(jié)束
我們已經(jīng)經(jīng)過了Gulp的基礎(chǔ)以及創(chuàng)建了一個工作流疲迂,可以將Sass編譯成CSS才顿,同時監(jiān)測HTML和JS文件發(fā)生改變。我們可以在命令行通過gulp
命令運行這個任務(wù)尤蒿。
我們也構(gòu)建了第二個任務(wù)郑气,build
,創(chuàng)建一個dist
文件夾給生產(chǎn)用網(wǎng)頁。我們編譯Sass為CSS腰池,壓縮我們所有的資源文件以及復(fù)制必要的文件夾到dist
文件夾尾组。我們可以在命令行中運行gulp build
來運行這個任務(wù)。
最后示弓,我們有一個clean
任務(wù)讳侨,用來清理生成的dist
文件夾和一些創(chuàng)建的圖片緩存,允許我們移除一些沒注意的留在dist
文件夾里的舊的文件奏属。
我們已經(jīng)創(chuàng)建了一個強(qiáng)健的工作流跨跨,到目前為止,這個已經(jīng)有足夠能力來進(jìn)行大多數(shù)WEB開發(fā)囱皿。這兒有一些Gulp和工作流歹叮,你可以探索來是這個進(jìn)程更加完美。這里有一些資源:
For development:
- Using Autoprefixer to write vendor-free CSS code
- Adding Sourcemaps for easier debugging
- Creating Sprites with sprity
- Compiling only files that have changed with gulp-changed
- Writing ES6 with Babel or Traceur
- Modularizing Javascript files with Browserify, webpack, or jspm
- Modularizing HTML with template engines like Handlebars or Swig
- Splitting the gulpfile into smaller files with require-dir
- Generating a Modernizr script automatically with gulp-modernizr
For optimization:
- Removing unused CSS with unCSS
- Further optimizing CSS with CSSO
- Generating inline CSS for performance with Critical