環(huán)境
Centos 7 X86_64(虛擬機(jī))
初始化
# yum install epel -y
# yum install vim nodejs npm -y
安裝gulp
# npm install gulp --global
package.json
創(chuàng)建package.json配置文件(package.json是用來記錄項(xiàng)目依賴組件的配置文件.)
# npm init # 根據(jù)提示一步一步定義最基本的配置文件.
//下面配置完成之后的內(nèi)容.
{
"name": "normandy",
"version": "1.0.0",
"description": "bai yuan web projects",
"main": "index.js",
"scripts": {
"test": "echo \\\"Error: no test specified\\\" && exit 1"
},
"author": "",
"license": "ISC",
}
維護(hù)package.json
常規(guī)的維護(hù)可以通過vim或者直接用編輯器對package.json文件進(jìn)行編輯塌西,只有當(dāng)需要為項(xiàng)目固化依賴組建時才會使用到下面這個命令來更新package.json.
# npm install npm install gulp gulp-buffer gulp-clean-css --save-dev
// 下面是配置更新后的內(nèi)容.
{
"name": "normandy",
"version": "1.0.0",
"description": "bai yuan web projects",
"main": "index.js",
"scripts": {
"test": "echo \\\"Error: no test specified\\\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.24.0",
"babel-preset-es2015": "^6.24.0",
"gulp": "^3.9.1",
"gulp-buffer": "0.0.2",
"gulp-clean-css": "^3.0.3",
}
}
Gulp編程
Gulp可以將指定目錄下的文件或者正則匹配到的文件進(jìn)行讀取,然后以數(shù)據(jù)流形式通過管道可以與其他命令協(xié)作完成對項(xiàng)目文件的定制。官方明確表示它僅僅是一個基礎(chǔ)的任務(wù)管理系統(tǒng)伊脓。這段話讀起來有點(diǎn)繞口沟绪,gulp將它拆成了四個命令(gulp.task割卖、gulp.src疙驾、gulp.dest杠河、gulp.watch)氢架,下面單獨(dú)對著四個命令進(jìn)行簡單描述(另外在延伸gulp的pipe屬性方法和through插件庫)傻咖。
Gulp.task
Gulp.task只負(fù)責(zé)執(zhí)行命令, 其他的什么都不管, 運(yùn)行Gulp.task不需要有任何準(zhǔn)備, 不對任何文件和目錄結(jié)構(gòu)有要求。它僅僅是一個命令執(zhí)行方法岖研。
javascript的寫法: gulpfile.js
var gulp = require('gulp');
gulp.task('hello_javascript', function() {
console.log('hello JavaScript!')
})
ECMAScript的寫法: gulpfile.babel.js
import gulp from 'gulp';
gulp.task('hello_ecmascript', () => {
console.log('hello ECMAScript');
})
# 輸出結(jié)果
[root@localhost ~]# gulp hello_ecmascript
[04:40:30] Requiring external module babel-register
[04:40:30] Using gulpfile ~/gulpfile.babel.js
[04:40:30] Starting 'hello_ecmascript'...
hello ECMAScript
[04:40:30] Finished 'hello_ecmascript' after 324 μs
語法: gulp.task(name [, deps] [, fn])
name和[, fn]著兩個參數(shù)已經(jīng)在上面兩個例子中有使用過了,
[, deps]尚未使用卿操,它主要的作用是控制執(zhí)行順序,
例如:gulp.task('hello_ecmascript', ['hello_javascript'], () => { ... })
這個任務(wù)的意思是說, 在執(zhí)行hello_ecmascript
之前需要先執(zhí)行hello_javascript
孙援。
Gulp.pipe
管道(pipe)用于傳輸文件字節(jié)流(數(shù)據(jù)流)害淤,gulp默認(rèn)采用了vinyl-fs來處理文件對象,而vinyl-fs采用through2來處理數(shù)據(jù)流拓售;在處理多文件的數(shù)據(jù)流這件事情上gulp一般都脫離不了through2窥摄。參考網(wǎng)址
through2會將gulp.src指定的多個文件(例如: gulp.src('src/*.js')),通過回調(diào)的方式挨個挨個將文件對象傳遞給through2础淤,下面舉兩個例子來介紹pipe屬性方法和through2的工作原理崭放。
文件合并(gulp-concat)
# 創(chuàng)建一個案例目錄
[root@localhost ~]# mkdir -p simple_merge/src
[root@localhost ~]# cd simple_merge/
# 安裝gulp和react
[root@localhost simple_merge]# cnpm install gulp gulp-concat vue react --save-dev
# 將react.js和vue復(fù)制到src目錄
[root@localhost simple_merge]# cp node_modules/react/dist/react.js node_modules/vue/dist/vue.js src/
# 撰寫gulpfile.js文件
[root@localhost simple_merge]# vim gulpfile.js
var gulp = require('gulp'),
concat = require('gulp-concat')
gulp.task('compress', function() {
return gulp.src('src/*.js')
.pipe(concat('bundle.js'))
.pipe(gulp.dest('dist/'))
})
# 構(gòu)建(文件合并)
[root@localhost simple_merge]# ./node_modules/gulp/bin/gulp.js compress
[20:13:51] Using gulpfile ~/fron_end/simple_merge/gulpfile.js
[20:13:51] Starting 'compress'...
[20:13:51] Finished 'compress' after 51 ms
# 查看當(dāng)前目錄結(jié)構(gòu)
[root@localhost simple_merge]# ls
dist gulpfile.js node_modules package.json src
# 查看dist目錄結(jié)構(gòu)
[root@localhost simple_merge]# ls -lah dist/
total 364K
drwxr-xr-x 2 root root 23 Mar 26 20:13 .
drwxr-xr-x 5 root root 88 Mar 26 20:13 ..
-rw-r--r-- 1 root root 364K Mar 26 20:13 bundle.js
首先gulp.src框定了讀取src目錄下的所有文件名后綴為.js的文件,并通過.pipe屬性方法將數(shù)據(jù)流傳遞給concat插件鸽凶,而concat運(yùn)行時根據(jù)制定的文件生成名稱(bundle.js)將多個文件對象逐一進(jìn)行讀取以及寫入到該制定的文件生成名稱的對象中币砂,并通過this關(guān)鍵字寫入到當(dāng)前實(shí)例,最終gulp.dest會根據(jù)標(biāo)準(zhǔn)接口去完成寫入的行為(創(chuàng)建目錄玻侥、寫入文件)决摧。
理解數(shù)據(jù)流轉(zhuǎn)發(fā)過程(through2)
上面這個例子從代碼層面來看,就一行有效代碼凑兰,但是從文字描述來看可能過于復(fù)雜和帶有不確定性掌桩,所以我這里將采用through2來打印一些日志來觀察它的運(yùn)行原理和過程(請注意:這個例子并沒有做文件合并。)票摇;其實(shí)通過查看gulp-concat插件的源代碼就可以發(fā)現(xiàn)它也是采用through2來完成文件對象的獲取拘鞋。
# 創(chuàng)建一個案例目錄
[root@localhost ~]# mkdir -p simple_pipeline/src
[root@localhost ~]# cd simple_pipeline/
# 安裝gulp和react
[root@localhost simple_pipeline]# cnpm install gulp vue react through2 --save-dev
# 將react.js和vue復(fù)制到src目錄
[root@localhost simple_pipeline]# cp node_modules/react/dist/react.js node_modules/vue/dist/vue.js src/
# 撰寫gulpfile.js文件
[root@localhost simple_merge]# vim gulpfile.js
var gulp = require('gulp'),
through = require('through2')
gulp.task('displayDetails', function() {
return gulp.src('src/*.js')
.pipe(through.obj(function(file, encode, callback) {
console.log(file);
console.log(encode);
console.log(callback);
callback();
}))
.pipe(gulp.dest('dist/'))
})
# 觀察運(yùn)行過程
[root@localhost simple_gulppipe]# ./node_modules/gulp/bin/gulp.js displayDetails
[20:39:24] Using gulpfile ~/fron_end/simple_gulppipe/gulpfile.js
[20:39:24] Starting 'displayDetails'...
<File "react.js" <Buffer 20 2f 2a 2a 0a 20 20 2a 20 52 65 61 63 74 20 76 31 35 2e 34 2e 32 0a 20 20 2a 2f 0a 28 66 75 6e 63 74 69 6f 6e 28 66 29 7b 69 66 28 74 79 70 65 6f 66 ... >>
utf8
[Function]
<File "vue.js" <Buffer 2f 2a 21 0a 20 2a 20 56 75 65 2e 6a 73 20 76 32 2e 32 2e 35 0a 20 2a 20 28 63 29 20 32 30 31 34 2d 32 30 31 37 20 45 76 61 6e 20 59 6f 75 0a 20 2a 20 ... >>
utf8
[Function]
[20:39:24] Finished 'displayDetails' after 55 ms
Gulp.src
語法:
gulp.src(globs[, options])
根據(jù)提供的參數(shù)來讀取文件源,并返回一個基于Vinyl風(fēng)格的文件對象(流數(shù)據(jù))矢门,這種文件對象可以通過pipe管道以一個文件對象傳遞給其他程序繼續(xù)完成整合的行為盆色。
globs
支持兩種類型的數(shù)據(jù)灰蛙,分別是字符串(glob)和列表(array of globs)。
glob支持字符串形式以通配符的方式來匹配文件集合隔躲。
// src/*.js標(biāo)識匹配src目錄下的所有后綴名為.js的文件摩梧,
// 并將它們逐一轉(zhuǎn)換成Vinyl風(fēng)格的文件對象。
gulp.src('src/*.js')
array of globs支持列表形式以通配符的方式來匹配文件集合宣旱。
gulp.src(['src/*.js', 'server/*.js', 'client/*.js'])
options
options選項(xiàng)是可選的仅父,因?yàn)槌绦蚰J(rèn)會給它賦值,除非有特定需求浑吟,否則一般不需要配置options笙纤;默認(rèn)情況下程序會這樣在程序內(nèi)部幫你實(shí)現(xiàn)賦值。
gulp.src('src/*.js', { buffer: true, read: true, base: null })
還有另外一個options要單獨(dú)進(jìn)行處理(那就是base)组力,默認(rèn)情況下base是一個null的值(也可以在glob處通配符'**'或指定一個明確的指)省容,意思是說,當(dāng)所有程序處理完之后燎字,最終交付給gulp.dest生成文件時腥椒,是否在指定的目錄下生成有子目錄結(jié)構(gòu)的存放;例如:
樣例1: 通配符
# 查看目錄結(jié)構(gòu)
[root@localhost simple_gulpsrc]# ls
node_modules package.json src
[root@localhost simple_gulpsrc]# tree src
src
└── client
└── js
├── jianshu
│ ├── react-with-addons.js
│ ├── react-with-addons.min.js
│ ├── react.js
│ └── react.min.js
└── youdao
├── vue.common.js
├── vue.common.min.js
├── vue.esm.js
├── vue.js
├── vue.min.js
├── vue.runtime.common.js
├── vue.runtime.esm.js
├── vue.runtime.js
└── vue.runtime.min.js
# 創(chuàng)建通配符版本gulpfile_wildcard.js
[root@localhost simple_gulpsrc]# vim gulpfile_wildcard.js
var gulp = require('gulp')
gulp.task('build', functioin () {
return gulp.src('src/client/js/**/*.js')
.pipe(gulp.dest('dist'))
})
# 生成目標(biāo)文件
[root@localhost simple_gulpsrc]# ./node_modules/gulp/bin/gulp.js --gulpfile gulpfile_wildcard.js build
[10:40:13] Using gulpfile ~/zhengtong/gulp_srcbase/gulpfile_wildcard.js
[10:40:13] Starting 'build'...
[10:40:13] Finished 'build' after 72 ms
# 查看目標(biāo)目錄
[root@localhost simple_gulpsrc]# tree dist
dist
├── jianshu
│ ├── react-with-addons.js
│ ├── react-with-addons.min.js
│ ├── react.js
│ └── react.min.js
└── youdao
├── vue.common.js
├── vue.common.min.js
├── vue.esm.js
├── vue.js
├── vue.min.js
├── vue.runtime.common.js
├── vue.runtime.esm.js
├── vue.runtime.js
└── vue.runtime.min.js
樣例2:通配符 + base
# 刪除dist目錄
[root@localhost simple_gulpsrc]# rm -rf dist/
# 創(chuàng)建通配符+base版本的gulpfile_wildcardBase.js
[root@localhost simple_gulpsrc]# vim gulpfile_wildcardBase.js
var gulp = require('gulp')
gulp.task('build', function () {
return gulp.src('src/client/js/**/*.js', {base: 'src'})
.pipe(gulp.dest('dist'))
})
# 生成目標(biāo)文件
[root@localhost simple_gulpsrc]# ./node_modules/gulp/bin/gulp.js --gulpfile gulpfile_wildcardBase.js build
[10:45:18] Using gulpfile ~/zhengtong/gulp_srcbase/gulpfile_wildcardBase.js
[10:45:18] Starting 'build'...
[10:45:18] Finished 'build' after 65 ms
# 查看目標(biāo)目錄
[root@localhost simple_gulpsrc]# tree dist
dist
└── client
└── js
├── jianshu
│ ├── react-with-addons.js
│ ├── react-with-addons.min.js
│ ├── react.js
│ └── react.min.js
└── youdao
├── vue.common.js
├── vue.common.min.js
├── vue.esm.js
├── vue.js
├── vue.min.js
├── vue.runtime.common.js
├── vue.runtime.esm.js
├── vue.runtime.js
└── vue.runtime.min.js