成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

基于 Gulp 的簡(jiǎn)易前端自動(dòng)化工程搭建

Blackjun / 768人閱讀

摘要:生成的文件如下由于給文件添加了哈希值,所以每次編譯出來(lái)的和都是不一樣的,這會(huì)導(dǎo)致有很多冗余文件,所以我們可以每次在生成文件之前,先將原來(lái)的文件全部清空。中也有做這個(gè)工作的插件,因此我們可以在編譯壓縮添加哈希值之前先將原文將清空。

原文鏈接:http://mrzhang123.github.io/2016/09/07/gulpUse/
項(xiàng)目鏈接:https://github.com/MrZhang123/Web_Project_Build/tree/master/gulp

上個(gè)月月底在公司提出關(guān)于前后端分離的想法,并且開(kāi)始研究關(guān)于前后端分離,前端工程化,模塊化的一些東西,上周開(kāi)始我準(zhǔn)備自己開(kāi)始寫基于Gulp流的前端工程文件,這兩天有時(shí)間,著手開(kāi)始實(shí)現(xiàn)這個(gè)想法,但是寫的過(guò)程中,遇到了一些問(wèn)題,正是因?yàn)檫@些問(wèn)題的解決讓我對(duì)Gulp的流式處理有了更深的理解,寫下這篇文章,分享一下這倆天我在寫Gulp的時(shí)候?qū)W到的一些東西。

準(zhǔn)備工作 安裝Node

首先Gulp是基于Nodejs的,所以安裝Nodejs是前提,Node可以說(shuō)是前端神器,基于Node有各種各樣的工具,正是因?yàn)檫@些工具讓我們非常方便的構(gòu)建前端工程。

更改Node插件默認(rèn)安裝位置(非必需)

我自己一般不喜歡在C盤狀太多與系統(tǒng)無(wú)關(guān)的東西,而通過(guò)Node自帶的npm安裝的插件默認(rèn)在C盤,但是我將Node安裝到D盤后,想讓插件就安裝在Nodejs的主目錄下,怎么辦呢?

在Node主目錄下新建"node_global"及"node_cache"兩個(gè)文件夾

啟動(dòng)cmd,輸入

//后面的設(shè)置目錄根據(jù)你的目錄結(jié)構(gòu)自行更改
npm config set prefix "D:Program
odejs
ode_global"
npm config set cache "D:Program
odejs
ode_cache"

關(guān)閉cmd,打開(kāi)系統(tǒng)對(duì)話框,“我的電腦”右鍵“屬性”-“高級(jí)系統(tǒng)設(shè)置”-“高級(jí)”-“環(huán)境變量”。

進(jìn)入環(huán)境變量對(duì)話框,在系統(tǒng)變量下新建"NODE_PATH",輸入"D:Programnodejsnode_globalnode_module"。 由于改變了module的默認(rèn)地址,所以上面的用戶變量都要跟著改變一下(用戶變量"PATH"修改為"D:Programnodejsnode_global"),要不使用module的時(shí)候會(huì)導(dǎo)致輸入命令出現(xiàn)“xxx不是內(nèi)部或外部命令,也不是可運(yùn)行的程序或批處理文件”這個(gè)錯(cuò)誤。

經(jīng)過(guò)這四步的設(shè)置就可以讓安裝的Node插件放在Nodejs的主目錄了。

安裝Gulp
//全局安裝Gulp
npm install -g gulp
//在項(xiàng)目中安裝Gulp
npm install --save-dev gulp

運(yùn)行gulp -v,如果不報(bào)錯(cuò),表示安裝成功

然后在命令行運(yùn)行

npm init

讓項(xiàng)目生產(chǎn)package.json文件

搭建工程

眾所周知,在開(kāi)發(fā)工程中有開(kāi)發(fā)和上線兩個(gè)過(guò)程,在開(kāi)發(fā)中,我們一般需要自動(dòng)刷新以及實(shí)時(shí)編譯,但是如果上線,我們就需要考慮很多優(yōu)化的東西,比如文件編譯壓縮,靜態(tài)資源放緩存處理等等問(wèn)題,我自己搭的這個(gè)工程只涉及到文件編譯壓縮,實(shí)時(shí)刷新,靜態(tài)資源放緩存這三個(gè)基本的流程。

在項(xiàng)目的目錄結(jié)構(gòu)如下

-------------------project
|   |
|   |--------------dist (該文件夾為打包生成的)
|   |   |
|   |   |----------css
|   |   |   |
|   |   |   |------index-9dcc24fe2e.css
|   |   |
|   |   |----------js
|   |   |   |
|   |   |   |------index-9dcc24fe2e.js
|   |   |----------index.html 
|   |
|   |--------------src
|   |   |
|   |   |----------scss
|   |   |   |------index.scss
|   |   |
|   |   |----------js
|   |   |   |
|   |   |   |------index.js
|   |   |
|   |   |----------index.html
|   |--------------gulpfile.js
|   |--------------package.json
開(kāi)發(fā)所用流程 文件編譯

在工程中準(zhǔn)備使用scss作為css的預(yù)編譯,所以需要利用gulp對(duì)scss進(jìn)行編譯,所以首先安裝gulp-sass。

npm install --save-dev gulp-sass

安裝完成之后,直接在gulpfile.js引用配置

const sass = require("gulp-sass"); //scss編譯

gulp.task("scss:dev",()=>{
    gulp.src("src/scss/*.scss")
    .pipe(sass())
    .pipe(gulp.dest("dist/css")); //將生成好的css文件放到dist/css文件夾下
});

這里簡(jiǎn)單介紹下gulp的兩個(gè)api:

gulp.src()輸入符合所提供的匹配模式或者匹配模式的數(shù)組的文件。將返回一個(gè)stream或者可以被piped到別的插件中。讀文件

gulp.dest()能被pipe進(jìn)來(lái),并且將會(huì)寫文件。并重新輸出(emits)所有數(shù)據(jù),因此可以將它pipe到多個(gè)文件夾,如果文件夾不存在則將會(huì)自動(dòng)創(chuàng)建。寫文件

實(shí)時(shí)刷新

實(shí)現(xiàn)實(shí)時(shí)刷新的工具有很多,我自己使用browser-sync,這個(gè)工具的功能非常強(qiáng)大,想了解它更多的用法可以查看官網(wǎng):http://www.browsersync.cn/。

首先我們?cè)陧?xiàng)目中安裝該模塊

npm install --save-dev browser-sync

根據(jù)官網(wǎng)的browser-sync與gulp的配置,得到如下配置:

const browserSync = require("browser-sync").create(); //實(shí)時(shí)刷新
const reload = browserSync.reload;

gulp.task("dev",["scss:dev"],function () {
    browserSync.init({
        server:{
            baseDir:"./"  //設(shè)置服務(wù)器的根目錄
        },
        logLevel: "debug",
        logPrefix:"dev",
        browser:"chrome",
        notify:false //開(kāi)啟靜默模式
    });
    //使用gulp的監(jiān)聽(tīng)功能,實(shí)現(xiàn)編譯修改過(guò)后的文件
    gulp.watch("src/scss/*.scss",["scss:dev"]);
    gulp.watch(("*.html")).on("change",reload);
});

這樣,一個(gè)簡(jiǎn)單的gulp開(kāi)發(fā)流程就出來(lái)了,僅僅只是一個(gè)編譯scss和一個(gè)實(shí)時(shí)刷新。

打包上線所有流程

打包上線,我們更多的是考慮,靜態(tài)資源防緩存,優(yōu)化。對(duì)css,js的壓縮,對(duì)圖片的處理,我寫的這個(gè)簡(jiǎn)單的流程中并沒(méi)有涉及對(duì)圖片的處理,所以這里僅針對(duì)css,js,html處理。

壓縮css我們使用gulp-sass就可以,因?yàn)樗诰幾gscss的時(shí)候有一個(gè)配置選項(xiàng)可以直接輸出被壓縮的css。壓縮js我使用了gulp-uglify,靜態(tài)資源防緩存使用gulp-rev和gulp-rev-collector。

對(duì)css,js的處理
//scss編譯
gulp.task("css",()=> {
    gulp.src("src/scss/*.scss")
        .pipe(sass({
            outputStyle: "compressed"               //編譯并輸出壓縮過(guò)的文件
        }))
        .pipe(rev())                                //給css添加哈希值
        .pipe(gulp.dest("dist/css"))
        .pipe(rev.manifest())                       //給添加哈希值的文件添加到清單中
        .pipe(gulp.dest("rev/css"));
});
//壓縮js
gulp.task("js", ()=> {
    gulp.src("src/js/*js")
        .pipe(uglify())
        .pipe(rev())                                //給js添加哈希值
        .pipe(gulp.dest("dist/js"))
        .pipe(rev.manifest())                       //給添加哈希值的文件添加到清單中
        .pipe(gulp.dest("rev/js"));
});

其中g(shù)ulp-rev是為css文件名添加哈希值,而rev.manifest()會(huì)生成一個(gè)json文件,這個(gè)json文件中記錄了原文件名和添加哈希值后的文件名的一個(gè)對(duì)應(yīng)關(guān)系,這個(gè)對(duì)應(yīng)關(guān)系在最后對(duì)應(yīng)替換html的引用的時(shí)候會(huì)用到。

生成的json文件如下:

{
  "index.css": "index-9dcc24fe2e.css"
}

由于給文件添加了哈希值,所以每次編譯出來(lái)的css和js都是不一樣的,這會(huì)導(dǎo)致有很多冗余文件,所以我們可以每次在生成文件之前,先將原來(lái)的文件全部清空。

gulp中也有做這個(gè)工作的插件---gulp-clean,因此我們可以在編譯壓縮添加哈希值之前先將原文將清空。

清空生成的項(xiàng)目文件
const clean = require("gulp-clean");                 //清空文件夾里所有的文件
//每次打包時(shí)先清空原有的文件夾
gulp.task("clean", ()=> {
    gulp.src(["dist", "rev"], {read: false}) //這里設(shè)置的dist表示刪除dist文件夾及其下所有文件
        .pipe(clean());
});
讓添加哈希編碼的文件自動(dòng)添加到html中

前面提到的gulp-rev實(shí)現(xiàn)了給文件名添加哈希編碼,但是在打包完成后如何讓原來(lái)未添加哈希值的引用自動(dòng)變?yōu)橐呀?jīng)添加哈希值的引用,這里用到gulp-rev的一個(gè)插件gulp-rev-collector,配置如下:

//將處理過(guò)的css,js引入html
gulp.task("reCollector",()=>{
    gulp.src(["rev/**/*.json","src/*.html"])
        .pipe(reCollector({
            replaceReved: true,  //模板中已經(jīng)被替換的文件是否還能再被替換,默認(rèn)是false
            dirReplacements: {   //標(biāo)識(shí)目錄替換的集合, 因?yàn)間ulp-rev創(chuàng)建的manifest文件不包含任何目錄信息,
                "css/": "/dist/css/",
                "js/": "/dist/js/"
            }
        }))
        .pipe(gulp.dest("dist"))
});
并沒(méi)有正常替換?

在我自己寫的時(shí)候,出現(xiàn)這個(gè)問(wèn)題,運(yùn)行完成該任務(wù)后,html中的css和js引用并沒(méi)有發(fā)生變化,網(wǎng)上搜了半天,才知道是由于自己用了gulp-rename插件,然后將文件名都添加了.min(至于為什么添加,僅僅是因?yàn)槭菈嚎s過(guò)的,應(yīng)該寫個(gè))而在自己寫的html里面引用的文件并沒(méi)有.min,由于gulp-rev-collector在替換的時(shí)候根據(jù)生成的json文件替換,在json中,文件都有了.min而在html中沒(méi)有,所以無(wú)法匹配,自然也就不能實(shí)現(xiàn)替換了,所以在替換的時(shí)候一定要注意gulp-rev生成的json文件中的css,js與html中的引用的一樣,否則無(wú)法實(shí)現(xiàn)替換。

在gulp-rev-collector的api中有一個(gè)revSuffix,這個(gè)看起來(lái)可以實(shí)現(xiàn)類似于gulp-rename的功能,但是不知道該怎么用,大家如果知道的話請(qǐng)告訴我...

執(zhí)行所有任務(wù)

完成上面幾個(gè)步驟后我們將所有任務(wù)串起來(lái),讓其可以一條命令然后全部執(zhí)行

gulp.task("build",["clean", "css", "js", "reCollector"]);
再次理解gulp
gulp---它的task是順序執(zhí)行嗎?

本以為到這里,就算是寫完了,運(yùn)行,完美,打包生成文件,再運(yùn)行一次,報(bào)錯(cuò)了!?。?!

[19:04:57] Finished "default" after 7.38 μs
stream.js:74
      throw er; // Unhandled stream error in pipe.
      ^

Error: ENOENT: no such file or directory, stat "D:projectdistjsindex-6045b384e6.min.js"
    at Error (native)

提示我找不到這個(gè)文件,這讓我很郁悶啊,然后我分開(kāi)執(zhí)行,很ok,可以確定是執(zhí)行順序有問(wèn)題,很可能在沒(méi)有清理完成就執(zhí)行后面了,查了gulp的官網(wǎng)文檔才知道本身gulp的pipe是一個(gè)一個(gè)任務(wù)進(jìn)行的,是同步的,但是每個(gè)task之間是不同步的,是一起進(jìn)行的,這也驗(yàn)證了我的猜想,所以在網(wǎng)上找如何解決這個(gè)問(wèn)題,找到一個(gè)叫run-sequence的npm插件,配置文件如下:

//進(jìn)行打包上線
gulp.task("build", ()=> {
    runSequence("clean", ["css", "js"], "reCollector");
});

本以為運(yùn)行就ok,結(jié)果,還是報(bào)錯(cuò),這里就涉及到對(duì)gulp的另一個(gè)理解

run-sequence插件對(duì)異步任務(wù)的處理

在用這個(gè)插件讓任務(wù)有序進(jìn)行后,我想進(jìn)一步直觀的看到它對(duì)任務(wù)的序列化,自己寫了一個(gè)demo,如下:

gulp.task("a",function(){
    setTimeout(function () {
        console.log(1);
    },30);
});
gulp.task("b",function() {
    console.log(2);
});
gulp.task("ab",function(){
    runSequence("a","b");
});

但是這里就出現(xiàn)問(wèn)題了,runSequence不管用了,找插件的說(shuō)明和gulp官方文檔,原來(lái)異步任務(wù),像setTimeout,readFile等,需要添加一個(gè)callback的執(zhí)行,這里的callback()就會(huì)返回一個(gè)promise的resolve(),告訴后面的任務(wù),當(dāng)前任務(wù)已經(jīng)完成,后面可以繼續(xù)執(zhí)行了,所以在task a里面執(zhí)行callback。

gulp.task("a",function(cb){
    setTimeout(function () {
        console.log(1);
        cb();
    },30);
});

那為什么前面寫的那些任務(wù)不需要添加一個(gè)callback呢?由于gulp的pipe流讓每一個(gè)task中的小任務(wù)(每一個(gè)pipe)順序執(zhí)行,從而整個(gè)pipe流是同步的,并不是異步任務(wù),所以并不需要手動(dòng)讓其返回promise,run-sequence會(huì)自動(dòng)幫我們管理。

總結(jié)

至此,我們就完成了一個(gè)簡(jiǎn)易的基于gulp的前端工程的搭建,很多東西確實(shí),想著并不難,做起來(lái)會(huì)出現(xiàn)各種各樣意想不到的問(wèn)題,gulp很早就知道,都是單個(gè)任務(wù)在寫,然后用哪個(gè)執(zhí)行哪個(gè)命令,直到自己寫完這個(gè)這個(gè)簡(jiǎn)單的工程,才對(duì)gulp有了更深入的理解。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/90929.html

相關(guān)文章

  • 我用HTML寫簡(jiǎn)歷

    摘要:打印背景色結(jié)語(yǔ)最后寫簡(jiǎn)歷的事情,也被我們工程化了,想想也是省心省力??梢园l(fā)揮我們的想象,加入各種好玩的東西,再也沒(méi)人有跟我一樣的簡(jiǎn)歷樣式了。這里寫了一個(gè)簡(jiǎn)單的項(xiàng)目,僅供參考地址 本文屬于原創(chuàng)文章,轉(zhuǎn)載請(qǐng)注明--來(lái)自桃源小盼的博客 起因 每次換工作寫簡(jiǎn)歷都是有點(diǎn)痛苦的事情,尤其是下載word模板,各種注冊(cè)流程,有的還得買積分,沖會(huì)員,甚是不爽。就算下載好了,修改其中的一些細(xì)節(jié)也不太熟悉各...

    王晗 評(píng)論0 收藏0
  • 從零開(kāi)始搭建Vue組件庫(kù)——VV-UI

    摘要:各個(gè)大廠也相繼宣布開(kāi)源。但是也會(huì)存在一些問(wèn)題,比如每個(gè)公司可能需要的業(yè)務(wù)組件不盡相同,或者我們想自己開(kāi)發(fā)一套屬于自己的組件庫(kù),來(lái)增強(qiáng)對(duì)組件的可控性。 前言: 前端組件化是當(dāng)今熱議的話題之一,也是我們?cè)陂_(kāi)發(fā)單頁(yè)應(yīng)用經(jīng)常會(huì)碰到的一個(gè)問(wèn)題,現(xiàn)在我們有了功能非常完善的Element-UI。各個(gè)大廠也相繼宣布開(kāi)源XXX-UI。但是也會(huì)存在一些問(wèn)題,比如每個(gè)公司可能需要的業(yè)務(wù)組件不盡相同,或者我們...

    BothEyes1993 評(píng)論0 收藏0
  • 從零開(kāi)始搭建Vue組件庫(kù)——VV-UI

    摘要:各個(gè)大廠也相繼宣布開(kāi)源。但是也會(huì)存在一些問(wèn)題,比如每個(gè)公司可能需要的業(yè)務(wù)組件不盡相同,或者我們想自己開(kāi)發(fā)一套屬于自己的組件庫(kù),來(lái)增強(qiáng)對(duì)組件的可控性。 前言: 前端組件化是當(dāng)今熱議的話題之一,也是我們?cè)陂_(kāi)發(fā)單頁(yè)應(yīng)用經(jīng)常會(huì)碰到的一個(gè)問(wèn)題,現(xiàn)在我們有了功能非常完善的Element-UI。各個(gè)大廠也相繼宣布開(kāi)源XXX-UI。但是也會(huì)存在一些問(wèn)題,比如每個(gè)公司可能需要的業(yè)務(wù)組件不盡相同,或者我們...

    wthee 評(píng)論0 收藏0
  • 前端相關(guān)匯總

    摘要:簡(jiǎn)介前端發(fā)展迅速,開(kāi)發(fā)者富有的創(chuàng)造力不斷的給前端生態(tài)注入新生命,各種庫(kù)框架工程化構(gòu)建工具層出不窮,眼花繚亂,不盲目追求前沿技術(shù),學(xué)習(xí)框架和庫(kù)在滿足自己開(kāi)發(fā)需求的基礎(chǔ)上,然后最好可以對(duì)源碼進(jìn)行調(diào)研,了解和深入實(shí)現(xiàn)原理,從中可以獲得更多的收獲隨 showImg(https://segmentfault.com/img/remote/1460000016784101?w=936&h=397)...

    BenCHou 評(píng)論0 收藏0
  • 使用 Gulp 動(dòng)化構(gòu)建工具快速搭建項(xiàng)目

    摘要:通過(guò)本文,我們將學(xué)習(xí)如何使用來(lái)改變開(kāi)發(fā)流程,從而使開(kāi)發(fā)更加快速高效。中文網(wǎng)站詳細(xì)入門教程使用是基于的,需要要安裝為了確保依賴環(huán)境正確,我們先執(zhí)行幾個(gè)簡(jiǎn)單的命令檢查。詳盡使用參見(jiàn)官方文檔,中文文檔項(xiàng)目地址 為了UED前端團(tuán)隊(duì)更好的協(xié)作開(kāi)發(fā)同時(shí)提高項(xiàng)目編碼質(zhì)量,我們需要將Web前端使用工程化方式構(gòu)建; 目前需要一些簡(jiǎn)單的功能: 1. 壓縮HTML 2. 檢查JS 3. 編譯SA...

    glumes 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<