給初學(xué)者的Gulp教程(譯)

原文標(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將提示你:

npm-init.png

一旦package.json文件創(chuàng)建后些楣,我們可以使用下面命令行脂凶,在項目中安裝Gulp

$npm install gulp --save-dev

這時候,我們就將Gulp安裝到項目里了愁茁,而不是全局安裝蚕钦,這就是為什么命令行有些不一樣。
你將會看到在這里不需要sudo鹅很,因為我們沒有全局安裝Gulp嘶居,所以-g也是不需要的。我們增加--save-dev,來告訴計算機(jī)增加gulppackage.json到dev依賴。

package-json.png

如果你查看項目文件夾邮屁,在命令執(zhí)行結(jié)束但壮,你應(yīng)該能看到Gulp在node_modules文件夾里僵朗。

node-modules.png

我們差不多可以開始使用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中requireGulp

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!

hello.png

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.destdestination處咳榜。

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挖诸。

second-stylesheet.png

我們現(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)視昔搂。

gulp-watch-start.png

它將自動運行sass任務(wù),當(dāng)你保存一個.scss文件输拇。

watch-compile.gif

讓我們來進(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,我們要requireBrowser 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)在换途,我們需要同時運行watchbrowserSync任務(wù)來進(jìn)行實時加載懊渡。
這個將要笨重的打開兩個命令行窗口以及獨立運行gulp browserSyncgulp 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
})

我們也希望確定sasswatch之前運行姑宽,所以CSS將在我們運行Gulp命令時遣耍,是最新的。

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

現(xiàn)在炮车,如果你在命令行中運行gulp watch,Gulp會同時開啟sassbrowserSync任務(wù)舵变。當(dāng)兩個任務(wù)都完成后酣溃,watch將會運行。

bs-watch.png

同時棋傍,一個顯示app/index.html文件的瀏覽器窗口也將突然彈出救拉。如果你改變了styles.scss文件,你將會看到瀏覽器自動刷新效果瘫拣。

bs-change-bg.gif

在我們結(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è)置typeremove,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.

main-min.png

但是這個文件現(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'.

useref-html.png

很棒是不是!
我們可以使用相同的方法來連接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.srcgulp.dest尚蝌,不需要其他插件。

gulp.task('fonts', function() {
  return gulp.src('app/fonts/**/*')
  .pipe(gulp.dest('dist/fonts'))
})

現(xiàn)在當(dāng)你運行gulp fonts,Gulp將會復(fù)制字體文件到dist中充尉。

font-copy.png

現(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,imagesfonts捶枢。
如果我們有同樣的思路握截,我們能創(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或者甚至fontsclean之前運行完成蒜鸡,這就意味著胯努,最后整個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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末铆帽,一起剝皮案震驚了整個濱河市咆耿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌爹橱,老刑警劉巖萨螺,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異愧驱,居然都是意外死亡慰技,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門组砚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吻商,“玉大人,你說我怎么就攤上這事糟红“剩” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵盆偿,是天一觀的道長柒爸。 經(jīng)常有香客問我,道長事扭,這世上最難降的妖魔是什么捎稚? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上今野,老公的妹妹穿的比我還像新娘葡公。我一直安慰自己,他們只是感情好条霜,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布催什。 她就那樣靜靜地躺著,像睡著了一般蛔外。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上溯乒,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天夹厌,我揣著相機(jī)與錄音,去河邊找鬼裆悄。 笑死矛纹,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的光稼。 我是一名探鬼主播或南,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼艾君!你這毒婦竟也來了采够?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤冰垄,失蹤者是張志新(化名)和其女友劉穎蹬癌,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體虹茶,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡逝薪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蝴罪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片董济。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖要门,靈堂內(nèi)的尸體忽然破棺而出虏肾,到底是詐尸還是另有隱情,我是刑警寧澤欢搜,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布询微,位于F島的核電站,受9級特大地震影響狂巢,放射性物質(zhì)發(fā)生泄漏撑毛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望藻雌。 院中可真熱鬧雌续,春花似錦、人聲如沸胯杭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽做个。三九已至鸽心,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間居暖,已是汗流浹背顽频。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留太闺,地道東北人糯景。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像省骂,于是被迫代替她去往敵國和親蟀淮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 安裝Gulp首先需要安裝Node.js钞澳,并在控制臺輸入$ npm install gulp -gMac端需要寫成$...
    LaBaby_閱讀 909評論 0 1
  • 原文地址:https://css-tricks.com/gulp-for-beginners/原文代碼:https...
    小雨雪smile閱讀 1,471評論 0 2
  • 參照Gulp for Beginners來學(xué)習(xí)Gulp基本內(nèi)容怠惶。以下為學(xué)習(xí)記錄筆記。 安裝Gulp 首先需要安裝N...
    JenniferYe閱讀 2,523評論 1 17
  • 在現(xiàn)在的前端開發(fā)中轧粟,前后端分離甚疟、模塊化開發(fā)、版本控制逃延、文件合并與壓縮览妖、mock數(shù)據(jù)等等一些原本后端的思想開始...
    Charlot閱讀 5,431評論 1 32
  • gulpjs是一個前端構(gòu)建工具,與gruntjs相比揽祥,gulpjs無需寫一大堆繁雜的配置參數(shù)讽膏,API也非常簡單,學(xué)...
    依依玖玥閱讀 3,148評論 7 55