使用Gulp構建前端自動化解決方案

Creabine發表於2016-08-11

前一篇部落格寫了Gulp入門,這裡詳細的介紹一下如何用Gulp構建適合自己的前端工作流。

我在學習的時候看了挺多資料,最後在kelsen大大的部落格學會了,感覺通俗易懂,一步步做過去就好了。

實際中每個人的需求不用,通過gulp以及其他相關外掛進行搭配,都能夠滿足不同的需求,所以我最後的流程也跟上邊那位kelsen大大的不太一樣。我在這裡會詳細註釋每個語句,因為在我自己學習的過程中,由於對node.js理解有限,所以時不時遇到很多困惑。希望通過我詳盡的註釋,能夠讓初次接觸Gulp的同學們能夠一目瞭然,瞭解他的工作原理之後,就可以很容易的按照自己的思路來搭建適合自己的前端工作流。

這裡預設你已經安裝好了node.js 和 gitbash。

首先在你需要的地方建立工程目錄,好的目錄就是工程的骨架,讓結構一目瞭然,便於維護管理,這方面我木有經驗,直接借用上邊kelsen大大部落格中的結構:

myproject/
├── app/
│   ├── sass/
│   │   └─ main.scss
│   ├── scripts/
│   │   └─ javascript.js
│   └── index.html
├── dist/
└── release/

初始化npm

在myproject目錄下開啟gitbash,執行npm init,建立一個package.json檔案,這樣其他人瀏覽工程的時候,只要看這個檔案,就知道工程的各種基本資訊以及依賴的模組了。
下面是我最終的package.json:

{
  "name": "daren",
  "version": "1.0.0",
  "description": "Daren Official website",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Creabine",
  "license": "ISC",
  "devDependencies": {
    "browser-sync": "^2.14.0",
    "browsersync-ssi": "^0.2.4",
    "gulp": "^3.9.1",
    "gulp-clean": "^0.3.2",
    "gulp-compass": "^2.1.0",
    "gulp-concat": "^2.6.0",
    "gulp-minify": "0.0.14",
    "gulp-minify-css": "^1.2.4",
    "gulp-plumber": "^1.1.0",
    "gulp-run-sequence": "^0.3.2",
    "gulp-uglify": "^2.0.0",
    "gulp-zip": "^3.2.0",
    "plumber": "^0.4.8"
  }
}

在你剛做完第一步的時候是沒有devDependencies這一項的,因為你還沒有安裝任何依賴模組。

安裝所需的模組

通過npm installpackageName –save-dev 命令來安裝上邊devDependencies中顯示的各個依賴模組。
在安裝或刪除博快的時候帶上–save-dev是個好習慣,他會同時改變你的package.json中的devDependencies對應的值。來保證資訊的準確性。
由於牆的存在,安裝模組可能會很慢或者很久不響應,國內可以使用cnpm映象安裝,但是我在使用cnpm的時候遇到了其他奇怪的麻煩(安裝時莫名的多出了許多其他檔案),所以這裡建議直接掛個VPN好了。

構建Gulp任務

Gulp用來協調指揮其他模組的工作。首先在myproject資料夾下新建gulpfile.js檔案,gulp會執行這個檔案中的js,我的檔案最終內容如下:

//使用嚴格模式的js。保證js的嚴謹,作為一個好習慣。
'use strict';

//使用require引入所有需要的模組,這是node.js語法,不瞭解的話記住就行了。
    //gulp
var gulp        = require('gulp'),
    //多瀏覽器多裝置同步&自動重新整理
    browserSync = require('browser-sync').create(),
    SSI         = require('browsersync-ssi'),
    //整合檔案
    concat      = require('gulp-concat'),
    //混淆js   暫時沒用到
    uglify = require('gulp-uglify'),
    //壓縮js
    minify      = require('gulp-minify'),
    //錯誤處理外掛plumber
    plumber     = require('gulp-plumber'),
    //compass 用來編譯sass
    compass     = require('gulp-compass'),
    //clean 用來刪除檔案
    clean       = require('gulp-clean'),
    //壓縮檔案
    zip         = require('gulp-zip');
    //控制task中的序列和並行。這個很重要,它能夠嚴格規定task的執行順序,否則gulp預設並行,有些時候會產生問題。如先清空再重建檔案,可能重建過程中又清空了。
    runSequence = require('gulp-run-sequence');
//上邊引入模組之後,下面開始編寫任務:

//建立一個名為serve的任務,該任務的內容就是匿名函式中的內容。
gulp.task('serve', function() {
    //使用browserSync建立伺服器,自動開啟瀏覽器並開啟./dist資料夾中的檔案(預設為index.html)
    browserSync.init({
        server: {
            baseDir:["./dist"],
            middleware:SSI({
                baseDir:'./dist',
                ext:'.shtml',
                version:'2.10.0'
            })
        }
    });
    //監聽各個目錄的檔案,如果有變動則執行相應的任務操作檔案
    gulp.watch("app/sass/**/*.scss", ['compass']);
    gulp.watch("app/javascript/**/*.js", ['js']);
    gulp.watch("app/**/*.html", ['html']);
    //如果有任何檔案變動,自動重新整理瀏覽器
    gulp.watch("dist/**/*.html").on("change",browserSync.reload);
});

//下面來分別看看處理各個部分的任務:

//compass任務,將scss編譯為css
gulp.task('compass', function() {
        //首先取得app/sass下的所有字尾為.scss的檔案(**/的意思是包含所有子資料夾)
  return gulp.src('app/sass/**/*.scss')
        .pipe(compass({
          //設定生成sourcemap,在偵錯程式中顯示樣式在scss檔案中的位置,便於除錯
          sourcemap: 'true',
          //輸出格式設定為compressed就不需要壓縮css了
          style: 'compressed',
          //檔案目錄
          css: 'dist/stylesheets',
          sass: 'app/sass',
          image: 'app/images'
        }))
        //如果有錯誤輸出錯誤提示
        .on('error', function(error) {
          // Would like to catch the error here
          console.log(error);
          this.emit('end');
        })
        //編譯後的檔案放入dist/stylesheets下
        .pipe(gulp.dest('dist/stylesheets'))
        //自動重新整理瀏覽器
        .pipe(browserSync.stream());
});


//js任務,將js壓縮後放入dist。該任務要在clean-scripts任務完成後再執行
gulp.task('js', function(){
        //首先取得app/javascript下的所有字尾為.js的檔案(**/的意思是包含所有子資料夾)
    return gulp.src('app/javascript/**/*.js')
        //錯誤管理模組
        .pipe(plumber())
        //目前沒用混淆,不方便除錯
        //.pipe(uglify())    
        //js壓縮
        .pipe(minify())
        //輸出到dist/javascript
        .pipe(gulp.dest("dist/javascript"))
        //自動重新整理瀏覽器
        .pipe(browserSync.stream());
});



//html任務,目前什麼都沒做。只是單純的把所有html從開發環境app複製到測試環境dist
gulp.task('html', function() {
    return gulp.src("app/*.html")
        .pipe(plumber())        
        .pipe(gulp.dest("dist/"))
        .pipe(browserSync.stream());
});

//publish任務,需要的時候手動執行,將dist中的檔案打包壓縮放到release中。
gulp.task('publish', function(){
        //取得dist資料夾中的所有檔案
    return gulp.src('dist/**/*')
        //錯誤處理模組
        .pipe(plumber())
        //壓縮成名為publish.zip的檔案
        .pipe(zip('publish.zip'))
        //放入release資料夾
        .pipe(gulp.dest('release'))
});
//clean任務:清空dist資料夾,下邊重建dist的時候使用
gulp.task('clean', function () {
  return gulp.src('dist/*', {read: false})
    .pipe(clean());
});

//redist任務:需要時手動執行,重建dist資料夾:首先清空,然後重新處理所有檔案
gulp.task('redist',function(){
    //先執行clean,然後並行執行html,js,compass
    runSequence('clean',['html','js','compass']);
});
//建立一個名為default的預設任務。當你在gitbash中執行gulp命令的時候,就會
gulp.task('default', function(){
    //先執行redist,啟動伺服器
    runSequence('redist','serve');
});

使用

執行gulp,會自動開啟瀏覽器,並顯示index.html檔案。當改動任意檔案,自動編譯到dist資料夾並且自動重新整理瀏覽器。

如果有改動檔名,編譯新檔案後,舊檔案依然保留。此時可以直接執行gulp redist來重建dist資料夾。

寫在最後

經過詳細的註釋,應該很簡明易懂了,希望能幫到跟我一樣曾經糾結過的小夥伴。花點時間熟悉搭建起來,能夠大幅提高工作效率,光是不用狂按ctrl+F5,就爽的沒邊兒啦,哈哈哈,共勉~

相關文章