1. 程式人生 > >gulp自動化構建工作流——專案例項

gulp自動化構建工作流——專案例項

gulp自動化構建工作流——專案常用配置

寫在最前

在專案中,除了使用Mvvm框架開發一個完整的app外,往往還有在原生app內部嵌入多個靈散H5頁面的需求。
在MVVM框架中,因為有vue-cli來實現專案結構的搭建,其中搭配webpack進行了開發的自動化構建配置,使開發過程中能過專注於業務邏輯,而不用多去考慮程式碼壓縮,圖片壓縮,及替換等。
對於靈散的H5頁面應用,使用gulp進行自動化構建,可以儘可能的壓縮程式碼,壓縮資源大小,從而使用使用者能快速的訪問到內容,並節省請求頻寬。
gulp是一款成熟的自動化構建工具,也有很多好用的外掛。以下總結在專案中通過gulp配置自動化工作流來提升工具效率的過程及注意點。

開發前準備

以一個新的需求為例(如:在app內部的不同入口嵌入多個互不相關的H5應用頁面,包括靜態的,也包括前後互動的)

工具準備

使用gulp,定當先安裝gulp(兩次安裝:1. 全域性安裝,2.所在專案中以開發依賴安裝)

# 1. 先全域性安裝
npm i -g gulp

# 專案最最開始(從0到1),建立一個專案檔案並初始化
npm init 

# 2. 在專案中以開發依賴安裝(-D  為--save-dev縮寫)
npm i -D gulp  

# 3. 專案根目錄建立gulp配置檔案gulpfile.js(gulp工作方式的關鍵)
var gulp = require
('gulp') gulp.task('default',function(){ // 預設任務的程式碼 }) gulp.task('test',function(){...}) # 4. 執行gulp(以CMD命令為例)_直接gulp時,預設是直接名為'default'的任務 gulp test

gulp配置關鍵步驟

通過以上初始化一個專案後並手動建立開發目錄,專案目錄檔案如下:

|_ package.json
|_ gulpfile.js
|_ img
|_ css
|_ js
|_ node_modules
|_ index.html
|_ page2.html
  • 以上為專案目錄結構,下一步需求:1. 通過gulp構建一個本地服務,執行此專案。2. 使用gulp壓縮整合html,css,img,js。使專案變得精簡,執行提速。

gulp常用方法(gulpfile.js為例)
- gulp.task() 建立gulp任務
- gulp.src() gulp任務原始檔查詢
- gulp.pipe() gulp工作流
- gulp.dest() gulp任務輸出

1. 建立第一個gulp任務 (gulp-connect)

# 安裝外掛依賴
npm i -D gulp-connect

# 配置gulpfile.js
// 匯入依賴
var gulp = require('gulp'),
    connect = requiire('gulp-connect');

// dev服務任務
gulp.task('dev',function(){
    connect.server({
        port:8090   //設定服務商品
    })
})

# 命令終端中執行gulp命令
gulp dev

# 結果
[15:03:37] Using gulpfile D:\1-workspace\tempGulp\gulpfile.js
[15:03:37] Starting 'dev'...
[15:03:37] Starting server...
[15:03:37] Finished 'dev' after 19 ms
[15:03:37] Server started http://localhost:8090
[15:03:37] Running server

其他gulp-connect中的配置項說明:
- root: 設定服務的啟動根目錄,當啟動服務時,預設到此目錄檔案中找
- livereload: 熱載入(通過設定,當修改html,或css時,瀏覽器預覽實時重新整理效果)
- port: 服務埠
- host: 服務域名,預設為localhost,可以改為本機ip

2. 構建熱載入服務

  • 需求:當修改專案中的html,或者stylus檔案時,專案能夠自動重新整理瀏覽器,實現實時預覽功能
  • 外掛:gulp-connect(服務),gulp-less
var gulp = require('gulp'),
    connect = require('gulp-connect'),
    less = require('gulp-less');
// 基本服務
gulp.task('dev', function () {
    connect.server({
        port: 8060,
        livereload: true
    })
})
// html熱載入
gulp.task('html', function () {
    gulp.src('./*.html')
    .pipe(gulp.dest('./myproject'))
    .pipe(connect.reload())
})
// less的編譯及載入
gulp.task('less', function () {
    gulp.src('./less/*.less')
        .pipe(less())  //less編譯為css
        .pipe(gulp.dest('./css'))
    .pipe(connect.reload())
})
// 觀察
gulp.task('watch', function () {
    gulp.watch(['./*.html'], ['html'])
    gulp.watch(['./less/*.less'],['less'])
})
gulp.task('default',['dev','watch'])

3.壓縮程式碼,整合檔案引用

  • 需求:將開發中的js,css,html進行壓縮處理,使檔案更小,訪問更快速
  • 外掛:gulp-useref(用於整合引用的資源),gulp-uglify(壓縮js),gulp-clean-css(壓縮css),gulp-if(條件判斷)
# 1.配置gulp
var gulp = require('gulp'),
    connect = require('gulp-connect'),
    less = require('gulp-less'),
    useref = require('gulp-useref'),
    uglify = require('gulp-uglify'),
    minifyCss = require('gulp-clean-css'),
    gulpif = require('gulp-if');

gulp.task('dev', function () {
    connect.server({
        port: 8060,
    })
})

gulp.task('compress', function () {
    return gulp.src('./*.html')
    .pipe(useref())
    .pipe(gulpif('*.js',uglify()))
    .pipe(gulpif('*.css',minifyCss()))
    .pipe(gulp.dest('./dist')) //輸出目錄
})

# 2. 在html中引用位置對應新增整合註釋
<!-- build:js js/main.min.js -->
<script src="js/zepto.js"></script>
<script src="js/main.js"></script>
<!-- endbuild -->

# 3. 最終變為
<script src="js/main.min.js"></script>

gulp-useref的作用?
- gulp-useref 並不會壓縮程式碼,但可以將多個檔案整合為一個(將html中零碎的引入合併成一個檔案)。如下:
- 注意:通過html中的註釋能夠指示合併後的檔案命名。

# 原檔案
<html>
<head>
//如下:將兩個css合併後,成為combined.css
    <!-- build:css css/combined.css -->
    <link href="css/one.css" rel="stylesheet">
    <link href="css/two.css" rel="stylesheet">
    <!-- endbuild -->
</head>
<body>
    <!-- build:js scripts/combined.js -->
    <script type="text/javascript" src="scripts/one.js"></script> 
    <script type="text/javascript" src="scripts/two.js"></script> 
    <!-- endbuild -->
</body>
</html>
# 構建後
<html>
<head>
    <link rel="stylesheet" href="css/combined.css"/>
</head>
<body>
    <script src="scripts/combined.js"></script> 
</body>
</html>

4. 壓縮圖片

  • 需求:將專案中的圖片壓縮後輸出
  • 外掛:gulp-imagemin
var imagemin = require('gulp-imagemin')

gulp.task('img',function(){
    gulp.src(['./img/*'])
    .pipe(imagemin())
    .pipe(gulp.dest('./dist')) 
})

5. 檔案清除 gulp-clean

  • 需求:每次打包專案檔案後會新成新的檔案,舊檔案就應該刪除。
  • 外掛: gulp-clean
var clean = require('gulp-clean')
gulp.task('clean',function(){
    return gulp.src('./myproject')
    .pipe(clean())
})

6. 多工依次執行 gulp-sequence

  • 場景:當需要多個任務依次執行
  • 外掛: gulp-sequence
var gulpSequenc = require('gulp-sequence')
gulp.task('build',gulpSequence(['clean','compress','imagemin']))

7. 給壓縮檔案新增 md5字尾

  • 場景:靜態資源在瀏覽器中往往會有快取,這會導致當更新了靜態資源後,瀏覽器中的呈現效果還是以前一樣(因為快取)。而通過新增MD5字尾,使每次更新的檔名都不一樣,從而實現靜態資源的同步更新。
  • 外掛:gulp-rev,gulp-rev-collector
  • rev :revision的縮寫
  • gulp-rev-collector:用於根據檔名的對應關係(gulp-rev生成的manifest.json檔案中的對應關係),遍歷所有html,替換檔案命名。
# 實現效果
<script src="js/main.min.js"></script>
<script src="js/index.min.js"></script>
# 變為
<script src="js/main-c609966787.min.js"></script>
<script src="js/index-1812ef94a5.min.js"></script>

配置md5簽名,壓縮 ,合併,整合替換的完整流程.

var gulp = require('gulp'),
    connect = require('gulp-connect'),
    less = require('gulp-less'),
    useref = require('gulp-useref'),
    uglify = require('gulp-uglify'),
    minifyCss = require('gulp-clean-css'),
    gulpif = require('gulp-if'),
    imagemin = require('gulp-imagemin'),
    rev = require('gulp-rev'),
    revCollect = require('gulp-rev-collector'),
    clean = require('gulp-clean'),
    gulpSequence = require('gulp-sequence');

gulp.task('dev', function () {
    connect.server({
        port: 8060,
    })
})

// 檔案的清除
gulp.task('clean',function(){
    return gulp.src(['./myproject','./.tmp'],{read:false})
    .pipe(clean())
})
// css,js的壓縮
gulp.task('compress', function () {
    return gulp.src('./*.html')
    .pipe(useref())
    .pipe(gulpif('*.js',uglify()))
    .pipe(gulpif('*.css',minifyCss()))
    .pipe(gulp.dest('./.tmp')) 
})
// 圖片壓縮
gulp.task('imagemin',function(){
    return gulp.src(['./img/*'])
    .pipe(imagemin())
    .pipe(gulp.dest('./myproject/img'))
})
// css md5簽名
gulp.task('css',function(){
    return gulp.src('./.tmp/css/*.css')
    .pipe(rev())  //給檔案加md5簽名字尾
    .pipe(gulp.dest('./myproject/css')) //簽名後輸出目錄
    .pipe(rev.manifest())  //設定md5簽名檔案的sourcemap 
    .pipe(gulp.dest('./.tmp/rev/css')) //設定map檔案存放目錄
})
// js md5簽名
gulp.task('js',function(){
    return gulp.src('./.tmp/js/*.js')
    .pipe(rev())
    .pipe(gulp.dest('./myproject/js'))
    .pipe(rev.manifest())
    .pipe(gulp.dest('./.tmp/rev/js'))
})
// 路徑替換
gulp.task('rev',function(){
    gulp.src(['./.tmp/rev/**/*.json','./.tmp/*.html'])
    .pipe(revCollect())
    .pipe(gulp.dest('./myproject'))
})
gulp.task('build',gulpSequence('clean','compress','js','css','rev','imagemin'))

以上的說明:
1. 通過設定.tmp 資料夾用於快取專案壓縮檔案,放置md5簽名的sourcemap檔案,通過rev-collector在.tmp中快取的manifest.json中對應的檔名關係來替換html中的靜態資源引用目錄
2. manifest.json : 在使用gulp-rev進行靜態資源的md5簽名後,通過rev.manifest()生成了簽名後資源與html中引用位置的對應關係(即從原index.min.js變為index-1812ef94a5.min.js的引用)