Gulp入門學(xué)習(xí)筆記

Gulp是基于流的自動化構(gòu)建工具,它不僅能對網(wǎng)站資源進(jìn)行優(yōu)化,而且在開發(fā)過程中能避免很多重復(fù)的工作,比如對相關(guān)文件的操作,還有自動監(jiān)視一些文件的變化等功能。

基本的常用API(gulp v3.X)

  • gulp.src(globs[, options])

    輸出符合所提供的匹配模式或者匹配模式的數(shù)組的文件。 將返回一個stream文件流它可以被 piped 到別的插件中。
    glob 相當(dāng)于文件的路徑,或者文件路徑數(shù)組。

  • gulp.dest(path[, options])
    // 把上一步處理的數(shù)據(jù)輸出到指定的目錄path中,如果某文件夾不存在,將會自動創(chuàng)建它。

  • gulp.task(name[, deps], fn)

    例子:

    gulp.task('mytask', ['array', 'of', 'task', 'names'], function() {
         // 做一些事
    });
    

異步、同步、規(guī)定執(zhí)行順序執(zhí)行任務(wù)

  • 異步執(zhí)行任務(wù)

    const gulp = require('gulp');    
    // 壓縮js代碼
        gulp.task('js', function () {
            return gulp.src('src/js/*.js')   // 匹配參數(shù)內(nèi)的文件,并且將文件讀到gulp內(nèi)存中
                .pipe(concat('bundle.js'))   // 合并文件代碼
                .pipe(gulp.dest('dist/js/'))   // 輸出文件到指定目錄
                .pipe(uglify())    // 壓縮當(dāng)前的js文件
                .pipe(rename({      // 重命名文件
                    suffix: '.min'
                }))
                .pipe(gulp.dest('dist/js/'))
        })
    
    // 壓縮css代碼
    gulp.task('css', function () {
        return gulp.src('src/css/*.css')
            .pipe(concat('bundle.css'))
            .pipe(cleanCss())   // 壓縮css文件
            .pipe(gulp.dest('dist/css/'))
    })
    
    // 執(zhí)行數(shù)組內(nèi)的任務(wù)
    gulp.task('default', ['js', 'css'])
    
當(dāng)運行命令 gulp 后,我們發(fā)現(xiàn)輸出的是
    [11:31:43] Using gulpfile E:\練習(xí)\Gulp\4-12\gulpfile.js
    [11:31:43] Starting 'css'...
    [11:31:43] Starting 'js'...
    [11:31:44] Finished 'js' after 72 ms
    [11:31:44] Finished 'css' after 70 ms
    [11:31:44] Finished 'default' after 33 μs
可以看到此時的任務(wù)是異步執(zhí)行的,應(yīng)用官方的一句話就是

默認(rèn)的,task 將以最大的并發(fā)數(shù)執(zhí)行,也就是說,gulp 會一次性運行所有的 task 并且不做任何等待。

但是如果我們想要它同步執(zhí)行任務(wù)呢?應(yīng)該怎么做?看代碼
  • 同步執(zhí)行任務(wù)
    const gulp = require('gulp');
    // 壓縮css代碼
    gulp.task('css', function () {
        gulp.src('src/css/*.css')
            .pipe(concat('bundle.css'))
            .pipe(cleanCss())   // 壓縮css文件
            .pipe(gulp.dest('dist/css/'))
    })
    // 解析less代碼并且壓縮css代碼
    gulp.task('less', function () {
        gulp.src('src/less/*.less')
            .pipe(concat('bundle_less.less'))
            .pipe(less())
            .pipe(cleanCss())
            .pipe(rename({
                suffix: '.min'
            }))
            .pipe(gulp.dest('dist/less'))
    })
    // 執(zhí)行數(shù)組內(nèi)的任務(wù)
    gulp.task('default', ['js', 'css'], 'less')

輸出結(jié)果

[11:44:22] Using gulpfile E:\練習(xí)\Gulp\4-12\gulpfile.js
[11:44:22] Starting 'css'...
[11:44:22] Finished 'css' after 7.24 ms
[11:44:22] Starting 'less'...
[11:44:22] Finished 'less' after 3.01 ms
[11:44:22] Starting 'default'...
[11:44:22] Finished 'default' after 35 μs

可以看到,我們只需要把return去掉即可實現(xiàn)同步進(jìn)行編譯輸出,也就是說,在task中只要不返回任何值即可實現(xiàn)同步執(zhí)行任務(wù)

如果想特定安排任務(wù)的執(zhí)行順序呢?(同步異步都執(zhí)行)

  • 按規(guī)定順序執(zhí)行任務(wù)
    const gulp = require('gulp');
    // 返回一個 callback,因此系統(tǒng)可以知道它什么時候完成
    gulp.task('one', function(cb) {
        // 做一些事 -- 異步的或者其他的
        cb(err); // 如果 err 不是 null 或 undefined,則會停止執(zhí)行,且注意,這樣代表執(zhí)行失敗了
    });
    // 定義一個所依賴的 task 必須在這個 task 執(zhí)行之前完成
    gulp.task('two', ['one'], function() {
        // 'one' 完成后
    });
    gulp.task('default', ['one', 'two']);

解析:運行時,gulp會執(zhí)行task one,當(dāng)執(zhí)行該函數(shù)的回調(diào)時候,如果 err 不是 null 或 undefined,則會停止執(zhí)行,且注意,這樣代表執(zhí)行失敗了,如果沒有發(fā)生錯誤,那么才回去執(zhí)行task two。也就是說,任務(wù)two必須在任務(wù)one的后面執(zhí)行

了解常用插件

  • gulp-concat 合并文件,減少網(wǎng)絡(luò)請求。基本使用方法:
        const gulp   = require('gulp'),
        concat = require('gulp-concat'),
        pump   = require('pump');
        gulp.task('testConcat', function (cb) {
            pump([
                gulp.src('src/js/*.js'),
                concat('all.js'),//合并后的文件名
                gulp.dest('dist/js')
            ], cb);
        });
    
  • gulp-uglify 壓縮js文件,減少文件體積,去掉沒有引用的代碼?;臼褂梅椒ǎ?
        gulp.task('jsmin',function(){
        gulp.src(['src/js/index.js','src/js/detail.js'])//多個文件以數(shù)組形式傳入
            .pipe(uglify({
                //mangle: true,//類型:Boolean 默認(rèn):true 是否修改變量名
                mangle:{except:['require','exports','module','$']},//排除混淆關(guān)鍵字
                compress:true,//類型:Boolean 默認(rèn):true 是否完全壓縮
                preserveComments:'all'//保留所有注釋
            }))
            .pipe(gulp.dest('dist/js'))
        });
    
  • gulp-rename 修改文件名,例如將demo.css修改為demo.min.css,一般配合gulp-minify-css/gulp-uglify壓縮插件一起使用?;臼褂梅椒?修改輸出的js文件名):
        gulp.task('renamejs',function(){
            return pump([
                gulp.src('src/js/*.js'),
                rename({suffix: '.min'}),   // 輸出文件名修改為帶.min的文件名
                uglify(),
                gulp.dest('dist/js')
            ])
        })
    
  • gulp-clean-css 使用gulp-clean-css壓縮css文件,減小文件大小,并給引用url添加版本號避免緩存。(之前的有同樣功能的gulp-minify-css已被廢棄)?;臼褂梅椒ǎ?
        gulp.task('testCssmin', function () {
            gulp.src('src/css/*.css')
                .pipe(cssmin({
                    advanced: false, //類型:Boolean 默認(rèn):true [是否開啟高級優(yōu)化(合并選擇器等)]
                    compatibility: 'ie7', //保留ie7及以下兼容寫法 類型:String 默認(rèn):''or'*' [啟用兼容模式; 'ie7':IE7兼容模式,'ie8':IE8兼容模式,'*':IE9+兼容模式]
                    keepBreaks: true, //類型:Boolean 默認(rèn):false [是否保留換行]
                    keepSpecialComments: '*'  //保留所有特殊前綴 當(dāng)你用autoprefixer生成的瀏覽器前綴,如果不加這個參數(shù),有可能將會刪除你的部分前綴
                }))
                .pipe(gulp.dest('dist/css'));
        });
    
  • gulp-less 使用gulp-less插件將less文件編譯成css,當(dāng)有l(wèi)ess文件發(fā)生改變自動編譯less,并保證less語法錯誤或出現(xiàn)異常時能正常工作并提示錯誤信息?;臼褂梅椒ǎ?
        gulp.task('testLess', function () {
            gulp.src('src/less/index.less')
                .pipe(less())   // 解析less文件轉(zhuǎn)換為css
                .pipe(gulp.dest('src/css'));
        });
    
  • gulp-htmlmin 使用gulp-htmlmin壓縮html,可以壓縮頁面javascript、css,去除頁面空格、注釋,刪除多余屬性等操作。基本使用方法:
        const htmlMin = require('gulp-htmlmin');
        gulp.task('testHtmlmin', function () {
            gulp.src('src/html/*.html')
                .pipe(htmlMin({
                    removeComments: true,//清除HTML注釋
                    collapseWhitespace: true,//壓縮HTML
                    collapseBooleanAttributes: true,//省略布爾屬性的值 <input checked="true"/> ==> <input />
                    removeEmptyAttributes: true,//刪除所有空格作屬性值 <input id="" /> ==> <input />
                    removeScriptTypeAttributes: true,//刪除<script>的type="text/javascript"
                    removeStyleLinkTypeAttributes: true,//刪除<style>和<link>的type="text/css"
                    minifyJS: true,//壓縮頁面JS
                    minifyCSS: true//壓縮頁面CSS
                }))   // 解析html文件并且壓縮
                .pipe(gulp.dest('dist/html'));
        });
    
  • gulp-livereload 實現(xiàn)項目自動編譯(半自動,頁面不會刷新)?;臼褂梅椒ǎ?
        const livereload = require('gulp-livereload');
        gulp.task('testLess', function () {
            gulp.src('src/less/index.less')
                .pipe(less())   // 解析less文件轉(zhuǎn)換為css
                .pipe(gulp.dest('src/css'))
                .pipe(livereload())
        });
        // 這里要先讓默認(rèn)任務(wù)執(zhí)行一遍后
        gulp.task('watch', ['default'], function () {
            // 開啟監(jiān)聽
            livereload.listen();
            // 確認(rèn)監(jiān)聽的目標(biāo)文件和對應(yīng)所執(zhí)行的task
            gulp.watch('src/less/*.less', ['testLess']);
            gulp.watch('src/html/*.html', ['minHtml']);
        })
    
  • gulp-connect 實現(xiàn)實時編譯和瀏覽器自動刷新(全自動)?;臼褂梅椒ǎ?
        const connect = require('gulp-connect');
        gulp.task('css', function () {
            return pump([
                gulp.src('src/css/*.css'),
                concat('bundle.css'),
                cleanCss(),
                rename({
                    suffix: '.min'
                }),
                gulp.dest('dist/css/'),
                connect.reload()   // 這一句實現(xiàn)修改后會刷新
            ])
        })
        gulp.task('server', ['default'], function () {
            connect.server({
                root: 'dist/',   // 編譯后對應(yīng)映射到哪個文件目錄下
                port: 8080,   // 端口號
                livereload: true   // 使用自動編譯
            });
            gulp.watch('src/css/*.css', ['css']);
            gulp.watch('src/html/*.html', ['minHtml']);
        })
    
  • gulp-autoprefixer 實現(xiàn)版本自動添加前綴?;臼褂梅椒ǎ?
        const autoprefixer = require('gulp-autoprefixer')
        /*自動加前綴*/
        gulp.task('autoprefixer', function () {
            return gulp.src('css/*.css')
                .pipe(autoprefixer({
                    browsers: ["last 2 versions","Firefox >= 20"],
                    /*last 2 versions: 主流瀏覽器的最新兩個版本
                    ● last 1 Chrome versions: 谷歌瀏覽器的最新版本
                    ● last 2 Explorer versions: IE的最新兩個版本
                    ● last 3 Safari versions: 蘋果瀏覽器最新三個版本
                    ● Firefox >= 20: 火狐瀏覽器的版本大于或等于20
                    ● iOS 7: IOS7版本
                    ● Firefox ESR: 最新ESR版本的火狐
                    ● > 5%: 全球統(tǒng)計有超過5%的使用率
                    */
                    cascade: true, //是否美化屬性值 默認(rèn):true 像這樣:
                    //-webkit-trans==>m: rotate(45deg);
                    //        trans==>m: rotate(45deg);
                    remove:true //是否去掉不必要的前綴 默認(rèn):true 
                }))
                .pipe(gulp.dest('css/'));
        });
    
  • gulp-load-plugins 所有的gulp插件都存在這里面。基本使用方法:
        // 必須要先調(diào)用一下這個函數(shù)才能使用
        const $ = require('gulp-load-plugins')();
        // 此時, 這些不在需要引入
        const concat = require('gulp-concat');
        const uglify = require('gulp-uglify');
        const rename = require('gulp-rename');
        const cleanCss = require('gulp-clean-css');
        ...
        // 使用下面的寫法代替上面的插件
        $.concat
        $.uglify
        $.rename
        $.cleanCss
        $.htmlmin
        ...
    
  • gulp-babel 編譯ES6、7轉(zhuǎn)換為ES5?;臼褂梅椒ǎ?
        const babel = require('gulp-babel');
        gulp.task('es', function () {
            return gulp.src('src/js_es6/*.js')
                .pipe(babel({                   // 編譯es6語法
                    presets: ["@babel/env"],
                    plugins: []
                }))
                .pipe(concat('bundle.js'))
                .pipe(gulp.dest('dist/'))
        })
        
        gulp.task('default', gulp.series(['es']))
        
        // 依賴版本
        // "@babel/core": "^7.4.3",
        // "@babel/preset-env": "^7.4.3",
        // "gulp": "^4.0.0",
        // "gulp-babel": "^8.0.0",
    

Gulp4.0升級了什么

  • gulpgulp.task()中移除了三參數(shù)語法,現(xiàn)在不能使用數(shù)組來指定一個任務(wù)的依賴。gulp 4.0 加入了 gulp.series 和 gulp.parallel 來實現(xiàn)任務(wù)的串行化和并行化。

    gulp.series 用于串行(順序)執(zhí)行

        gulp.task('default', gulp.series(['html', 'css', 'js']))
    

    gulp.parallel 用于并行執(zhí)行,如果你想并行執(zhí)行scripts和styles,你可以這么寫:

        gulp.task('default', gulp.parallel('scripts', 'styles'));
    

    通常gulp.series 和 gulp.parallel我們需要配合來使用。

  • 依賴陷阱

    讓我們看一下這個Gulp3的例子:

        // default任務(wù),需要依賴scripts和styles
        gulp.task('default', ['scripts', 'styles'], function() {});
        // script和styles任務(wù)都依賴clean
        gulp.task('styles', ['clean'], function() {});
        gulp.task('scripts', ['clean'], function() {});
        // clean任務(wù)用來清空目錄
        gulp.task('clean', function() {});
    

    當(dāng)Gulp開始工作,它會創(chuàng)建一個任務(wù)依賴樹

    它發(fā)現(xiàn)clean任務(wù)是另外兩個task的依賴,從而確保clean只執(zhí)行一次。

    但遺憾的是,我們在新版本中將沒辦法運用這個特性。如果你在遷移到Gulp4的過程中只像下面的例子一樣做了簡單的改變,clean任務(wù)將會被執(zhí)行兩次:

        // 任務(wù)直接不再有依賴
        gulp.task('styles', function() {...});
        gulp.task('scripts', function() {...});
        gulp.task('clean', function() {...});
        
        // default任務(wù),需要依賴scripts和styles
        gulp.task('default', gulp.series('clean', gulp.parallel('scripts', 'styles')));
    
  • 異步任務(wù)支持

    如果你執(zhí)行的是同步任務(wù),在Gulp3中不需要寫任何其他代碼,但是在Gulp4中就不能如此輕松了:現(xiàn)在也你必須運行done回調(diào)(這可能是我最早發(fā)現(xiàn)的一個變化)。然后如果你執(zhí)行的是異步任務(wù),你則有三個選擇來確保Gulp能夠檢測到你的任務(wù)真的完成了:

    • 回調(diào)
        const del = require('del');
        // del 模塊用來刪除指定目錄的文件
        gulp.task('clean', function(done) {
            del(['.build/'], done);
        });
    

    • 返回一個流告訴gulp任務(wù)你已經(jīng)處理完成
          gulp.task('somename', function() {
              return gulp.src('client/**/*.js')
                  .pipe(minify())
                  .pipe(gulp.dest('build'));
          });
      
    • Promise
      返回一個Promise來告訴gulp任務(wù)已經(jīng)處理完成
          var promisedDel = require('promised-del');
          gulp.task('clean', function() {
              return promisedDel(['.build/']);
          });
      
  • 使用函數(shù)定義任務(wù)

    具體使用方法:

        // 只需要在`series` 和 `parallel` 中間引用函數(shù)名就能組成一個新任務(wù)
        gulp.task('default', gulp.series(clean, gulp.parallel(scripts, styles)));
        
        // 把單個任務(wù)變成一個函數(shù)
        function styles() {}
        function scripts() {}
        function clean() {}
    

    此處參考了:
    【譯】相對完整的Gulp4升級指南
    Gulp 4: gulp.parallel gulp.series -- 全新的任務(wù)執(zhí)行體系

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

相關(guān)閱讀更多精彩內(nèi)容

  • 我的新作觀點網(wǎng)http://www.guandn.com(觀點網(wǎng)是一個獵獲新奇、收獲知識、重在獨立思考的網(wǎng)站),它...
    pizCat閱讀 2,574評論 1 18
  • gulpjs是一個前端構(gòu)建工具,與gruntjs相比,gulpjs無需寫一大堆繁雜的配置參數(shù),API也非常簡單,學(xué)...
    MC丶逗逼嘿閱讀 717評論 0 3
  • gulpjs是一個前端構(gòu)建工具,與gruntjs相比,gulpjs無需寫一大堆繁雜的配置參數(shù),API也非常簡單,學(xué)...
    井皮皮閱讀 1,393評論 0 10
  • 1、gulp的安裝 首先確保你已經(jīng)正確安裝了nodejs環(huán)境。然后以全局方式安裝gulp: npm install...
    F_imok閱讀 2,474評論 1 11
  • 安裝Gulp首先需要安裝Node.js,并在控制臺輸入$ npm install gulp -gMac端需要寫成$...
    LaBaby_閱讀 1,019評論 0 1

友情鏈接更多精彩內(nèi)容