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的引用)