gulp是一個自動化構建工具,開發者可以用它來自動執行一些常見的任務。這裡以我之前做的一個demo為例,簡要介紹如何使用gulp實現前端工程自動化。
專案結構
其中src
目錄下表示的是專案的原始碼,可以看到其中有less、js、html等,而dist
目錄則是儲存的是gulp
編譯後生成的程式碼,相當於生產環境。最後也最重要的是gulpfile.js
,這個檔案用於設定gulp
相關的配置,類似於webpack
中的webpack.config.js
。
安裝
這裡使用的gulp
為v3.9.1,語法和最新的v4.x有所出入,想學習最新的gulp
語法,可以參考gulp.js - The streaming build system 。
3.9.1 安裝如下:
npm install --save-dev gulp
複製程式碼
語法
gulp.task()
用於定義一個gulp
任務,在命令列中可以使用gulp [任務名]
開啟該任務。gulp.src()
會返回符合匹配的檔案流,可以被pipe()
到其他外掛中。gulp.dest()
:輸出所有資料。gulp.watch()
用於監測檔案的變動。
實踐
在這個專案中,有一些常見的需求,這裡使用gulp
來實現自動化:
- less轉css
- css壓縮合並
- js壓縮合並
- 圖片壓縮
在gulpfile.js
中首先需要匯入gulp
和一些常用的外掛,本次demo使用到的外掛如下:
var gulp = require('gulp'),
less = require('gulp-less'), //less 轉 css
csso = require('gulp-csso'), //css壓縮
concat = require('gulp-concat'), //合併檔案
uglify = require('gulp-uglify'), //js 壓縮
jshint = require('gulp-jshint'), //js 檢查
clean = require('gulp-clean'), //清除檔案
imagemin = require('gulp-imagemin'), //圖片壓縮
rev = require('gulp-rev'), //新增版本號
revReplace = require('gulp-rev-replace'), //版本號替換
useref = require('gulp-useref'), //解析html資源定位
gulpif = require('gulp-if'), //if語句
connect = require('gulp-connect'); //建立web伺服器
複製程式碼
圖片壓縮
獲取到src
下所有以.jpg
或.png
結尾的圖片,將其壓縮後輸出到dist
目錄下。
gulp.task('dist:img', () => {
gulp.src(['./src/**/*.jpg', './src/**/*.png'])
.pipe(imagemin())
.pipe(gulp.dest('dist/'))
})
複製程式碼
less壓縮合併為css
先清除已存在的css,然後將src
下以.less
結尾的檔案通過less()
轉為css檔案,再通過csso()
以及concat()
實現對css的壓縮合並。
gulp.task('dist:css', () => {
gulp.src('dist/css/*.css').pipe(clean());
return gulp.src('./src/less/*.less')
.pipe(less())
.pipe(csso())
.pipe(concat('public.css'))
.pipe(gulp.dest('dist/css/'));
});
複製程式碼
js壓縮合並
js壓縮合並的過程大同小異,增加了一個jshint()
程式碼審查的過程,它會將不符合規範的錯誤程式碼輸出到控制檯。
gulp.task('dist:js', () => {
gulp.src('dist/js/*.js').pipe(clean());
return gulp.src('./src/js/*.js')
.pipe(jshint())
.pipe(jshint.reporter('default'))
.pipe(uglify())
.pipe(concat('public.js'))
.pipe(gulp.dest('dist/js/'))
});
複製程式碼
less轉css
在開發過程中,因為html
不能直接引入.less
檔案,因此還需要生成開發環境的.css
。
gulp.task('src:css', () => {
gulp.src('src/css/*.css').pipe(clean());
return gulp.src('./src/less/*.less')
.pipe(less())
.pipe(gulp.dest('src/css/'));
});
複製程式碼
新增版本號
為了防止瀏覽器對檔案進行快取,需要對檔案新增版本號,保證每次獲取到的都是最新的程式碼。
gulp.task('revision', ['dist:css', 'dist:js'], () => {
return gulp.src(["dist/css/*.css", "dist/js/*.js"])
.pipe(rev())
.pipe(gulpif('*.css', gulp.dest('dist/css'), gulp.dest('dist/js')))
.pipe(rev.manifest())
.pipe(gulp.dest('dist'))
})
gulp.task('build', ['dist:img'], () => {
var manifest = gulp.src('dist/rev-manifest.json');
return gulp.src('src/index.html')
.pipe(revReplace({
manifest: manifest
}))
.pipe(useref())
.pipe(gulp.dest('dist/'))
})
複製程式碼
在revision
中,首先通過rev()
對dist
目錄下的.css/.js
生成一個檔名帶版本號的檔案,例如本例中public.css
生成public-5c001c53f6.css
,然後分別輸出到不同的目錄下,最後生成一個rev-manifest.json
檔案,儲存了原檔案和帶版本號檔案之間的對映關係,如下:
{
"public.css": "public-5c001c53f6.css",
"public.js": "public-93c275a836.js"
}
複製程式碼
在build
中,先獲取到rev-manifest.json
中的物件,然後利用revReplace()
來替換版本號,再使用useref()
來進行資源的解析定位,最後輸出即可。
以引入js檔案為例,源html檔案中對檔案的引入則要改寫為以下形式,即以註釋的形式寫入構建後生成的檔案路徑,如下:
<!-- build:js ./js/public.js -->
<script src="./js/jquery-1.12.4.min.js"></script>
<script src="./js/myAlbum.js"></script>
<!-- endbuild -->
複製程式碼
最後生成的html為:
<script src="./js/public-93c275a836.js"></script>
複製程式碼
具體的語法規則可以參見gulp-useref。
建立本地伺服器並實現自動重新整理
使用connet.server()
來建立一個本地伺服器,利用gulp.watch()
來對src
下的檔案進行監測,如果發生變化,則執行編譯less
為css
和重新整理頁面的任務。
gulp.task('connect', () => {
connect.server({
root: 'src',
livereload: true,
port: 8888
})
})
gulp.task('reload', () => {
gulp.src('src/*.html')
.pipe(connect.reload())
})
gulp.task('watch', () => {
gulp.watch('src/**/*', ['src:css', 'reload'])
})
複製程式碼
完整的程式碼可以參見github。
原文地址: