「1. 我爲何使用grunt; 2. 我爲什麼放棄grunt轉投gulp; 3. 我爲什麼放棄gulp與grunt,轉投npm scripts; 4. 我爲什麼放棄前端」 —— 司徒正美javascript
前端(段子)界的發展日新月異,總感受隨時會跟不上技術潮流(其實我已經被甩開了一條街,so sadcss
選擇在這樣一個時機發布一篇 gulp 教程並非個人初衷,第一次用 gulp 是在一年前,而這篇帖子在草稿箱裏躺了一個多月,再不發出來講不定就過期了。html
當我在用 gulp 時我用它作什麼?前端
總之,gulp是前端開發過程當中對代碼進行自動化構建的利器。它不只能對資源進行優化,並且在開發過程當中可以經過配置自動完成不少重複的任務,讓咱們能夠專一於代碼,提升工做效率。java
然而因爲衆所周知的緣由,國內到 npm 服務器的鏈接很不穩定,若是你有V了個PN大可沒必要擔憂,也可經過設置 npm 代理服務器的方式訪問:node
1
2
3
4
|
推薦一個簡單的方案:使用淘寶 npm 鏡像 jquery
「這是一個完整 npmjs.org 鏡像,你能夠用此代替官方版本(只讀),同步頻率目前爲 10分鐘 一次以保證儘可能與官方服務同步。」 —— 淘寶團隊點贊npm
1
2
|
npm config set registry="https://registry.npm.taobao.org"
npm config set disturl https://npm.taobao.org/dist
|
準備工做: 安裝 node.js (推薦 TLS 版),並重啓系統。json
1
|
npm install gulp -g
|
└── src/ 源碼目錄gulp
├── build/ .html 組件
├── sass/ .scss .sass 文件
├── css/ .css 文件
├── js/ .js 文件
└── img/ 圖片
└── dist/ 輸出目錄
└── package.json
└── gulpfile.js
能夠在項目上使用 npm init 配置,推薦直接新建並寫入初始內容:
1
2
3
4
5
6
|
{
"name"
:
"gulp-build"
,
"version"
:
"1.0.0"
,
"description"
:
"Gulp.js"
,
"private"
:
true
}
|
對於完整的 package.json (好比別人的開源項目), 只需對整個項目執行 npm install 便可安裝 package.json 文件中聲明的全部插件模塊。
1
|
npm install gulp --save-dev
|
—save-dev 這個參數會將插件信息自動更新到 package.json 裏,其中的 devDependencies 屬性會隨插件依賴的安裝卸載而改變。
PS. Windows 7及以上,按住 Shift 再右鍵,選擇在此處打開命令窗口。免去 cd 命令定位目錄的煩惱。
PS.可與上一步同時進行
1
|
npm install gulp del gulp-cached gulp-uglify gulp-rename gulp-concat gulp-notify gulp-filter gulp-jshint gulp-ruby-sass gulp-rev-append gulp-cssnano gulp-replace gulp-imagemin browser-sync gulp-font-spider gulp-file-include gulp-autoprefixer --save-dev
|
插件將在配置文件裏介紹,更多用法請參見相應的 GitHub 主頁,或者直接戳這裏: https://www.npmjs.com/package/
以上兩個安裝操做將會在項目目錄下生成 node_modules 文件夾,相應的插件都在這裏。
Windows 用戶請注意,此文件夾可能 沒法刪除 沒法複製 沒法移動,會出現諸如「包含名稱過長且沒法放入回收站」,「源文件名長度大於文件系統支持的長度。請嘗試將其移動到具備較短路徑名稱的位置」 等等問題。使用一個簡單的方式便可刪除,使用 WinRAR 「添加到壓縮文件」,勾選壓縮選項裏的 「壓縮後刪除源文件」 ,肯定以後便可刪除。
別看我,看它:http://www.gulpjs.com.cn/docs/api/
1
2
3
4
5
6
7
8
9
10
|
<!
DOCTYPE
html>
<
html
>
<
head
>
<
meta
charset
=
"utf-8"
/>
<
title
>嘿嘿嘿</
title
>
<
link
href
=
"css/m.base.css?rev=@@hash"
rel
=
"stylesheet"
type
=
"text/css"
/>
<
link
href
=
"css/jquery.fullPage.css?rev=@@hash"
rel
=
"stylesheet"
type
=
"text/css"
/>
<
link
href
=
"css/mobile.css?rev=@@hash"
rel
=
"stylesheet"
type
=
"text/css"
/>
</
head
>
<
body
>
|
1
2
3
4
5
|
<!-- common js -->
<
script
type
=
"text/javascript"
src
=
"js/jquery-2.1.4.min.js"
></
script
>
<
script
type
=
"text/javascript"
src
=
"js/main.js?rev=@@hash"
></
script
>
</
body
>
</
html
>
|
1
2
3
4
5
|
@@include('build/header.html')
<
div
class
=
"wrap"
>內容</
div
>
@@include('build/footer.html')
|
代碼中, ?rev=@@hash 是 gulp-rev-append 插件的指紋標識
@@include(‘build/header.html’) 能夠插入 html 文件,還能夠配合參數生成獨立的頭部。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
/*!
* gulp
* $ npm install gulp gulp-ruby-sass gulp-cached gulp-uglify gulp-rename gulp-concat gulp-notify gulp-filter gulp-jshint gulp-rev-append gulp-cssnano gulp-imagemin browser-sync gulp-file-include gulp-autoprefixer del --save-dev
*/
// Load plugins
var
gulp = require(
'gulp'
),
// 必須先引入gulp插件
del = require(
'del'
),
// 文件刪除
sass = require(
'gulp-ruby-sass'
),
// sass 編譯
cached = require(
'gulp-cached'
),
// 緩存當前任務中的文件,只讓已修改的文件經過管道
uglify = require(
'gulp-uglify'
),
// js 壓縮
rename = require(
'gulp-rename'
),
// 重命名
concat = require(
'gulp-concat'
),
// 合併文件
notify = require(
'gulp-notify'
),
// 至關於 console.log()
filter = require(
'gulp-filter'
),
// 過濾篩選指定文件
jshint = require(
'gulp-jshint'
),
// js 語法校驗
rev = require(
'gulp-rev-append'
),
// 插入文件指紋(MD5)
cssnano = require(
'gulp-cssnano'
),
// CSS 壓縮
imagemin = require(
'gulp-imagemin'
),
// 圖片優化
browserSync = require(
'browser-sync'
),
// 保存自動刷新
fileinclude = require(
'gulp-file-include'
),
// 能夠 include html 文件
autoprefixer = require(
'gulp-autoprefixer'
);
// 添加 CSS 瀏覽器前綴
// sass
gulp.task(
'sass'
,
function
() {
return
sass(
'src/sass/**/*.scss'
, {style:
'expanded'
})
// 傳入 sass 目錄及子目錄下的全部 .scss 文件生成文件流經過管道並設置輸出格式
.pipe(cached(
'sass'
))
// 緩存傳入文件,只讓已修改的文件經過管道(第一次執行是所有經過,由於尚未記錄緩存)
.pipe(autoprefixer(
'last 6 version'
))
// 添加 CSS 瀏覽器前綴,兼容最新的5個版本
.pipe(gulp.dest(
'dist/css'
))
// 輸出到 dist/css 目錄下(不影響此時管道里的文件流)
.pipe(rename({suffix:
'.min'
}))
// 對管道里的文件流添加 .min 的重命名
.pipe(cssnano())
// 壓縮 CSS
.pipe(gulp.dest(
'dist/css'
))
// 輸出到 dist/css 目錄下,此時每一個文件都有壓縮(*.min.css)和未壓縮(*.css)兩個版本
});
// css (拷貝 *.min.css,常規 CSS 則輸出壓縮與未壓縮兩個版本)
gulp.task(
'css'
,
function
() {
return
gulp.src(
'src/css/**/*.css'
)
.pipe(cached(
'css'
))
.pipe(gulp.dest(
'dist/css'
))
// 把管道里的全部文件輸出到 dist/css 目錄
.pipe(filter([
'**/*'
,
'!**/*.min.css'
]))
// 篩選出管道中的非 *.min.css 文件
.pipe(autoprefixer(
'last 6 version'
))
.pipe(gulp.dest(
'dist/css'
))
// 把處理過的 css 輸出到 dist/css 目錄
.pipe(rename({suffix:
'.min'
}))
.pipe(cssnano())
.pipe(gulp.dest(
'dist/css'
))
});
// styleReload (結合 watch 任務,無刷新CSS注入)
gulp.task(
'styleReload'
, [
'sass'
,
'css'
],
function
() {
return
gulp.src([
'dist/css/**/*.css'
])
.pipe(cached(
'style'
))
.pipe(browserSync.reload({stream:
true
}));
// 使用無刷新 browserSync 注入 CSS
});
// script (拷貝 *.min.js,常規 js 則輸出壓縮與未壓縮兩個版本)
gulp.task(
'script'
,
function
() {
return
gulp.src([
'src/js/**/*.js'
])
.pipe(cached(
'script'
))
.pipe(gulp.dest(
'dist/js'
))
.pipe(filter([
'**/*'
,
'!**/*.min.js'
]))
// 篩選出管道中的非 *.min.js 文件
// .pipe(jshint('.jshintrc')) // js的校驗與合併,根據須要開啓
// .pipe(jshint.reporter('default'))
// .pipe(concat('main.js'))
// .pipe(gulp.dest('dist/js'))
.pipe(rename({suffix:
'.min'
}))
.pipe(uglify())
.pipe(gulp.dest(
'dist/js'
))
});
// image
gulp.task(
'image'
,
function
() {
return
gulp.src(
'src/img/**/*.{jpg,jpeg,png,gif}'
)
.pipe(cached(
'image'
))
.pipe(imagemin({optimizationLevel: 3, progressive:
true
, interlaced:
true
, multipass:
true
}))
// 取值範圍:0-7(優化等級),是否無損壓縮jpg圖片,是否隔行掃描gif進行渲染,是否屢次優化svg直到徹底優化
.pipe(gulp.dest(
'dist/img'
))
});
// html 編譯 html 文件並複製字體
gulp.task(
'html'
,
function
() {
return
gulp.src(
'src/*.html'
)
.pipe(fileinclude())
// include html
.pipe(rev())
// 生成並插入 MD5
.pipe(gulp.dest(
'dist/'
))
});
// clean 清空 dist 目錄
gulp.task(
'clean'
,
function
() {
return
del(
'dist/**/*'
);
});
// build,關連執行所有編譯任務
gulp.task(
'build'
, [
'sass'
,
'css'
,
'script'
,
'image'
],
function
() {
gulp.start(
'html'
);
});
// default 默認任務,依賴清空任務
gulp.task(
'default'
, [
'clean'
],
function
() {
gulp.start(
'build'
);
});
// watch 開啓本地服務器並監聽
gulp.task(
'watch'
,
function
() {
browserSync.init({
server: {
baseDir:
'dist'
// 在 dist 目錄下啓動本地服務器環境,自動啓動默認瀏覽器
}
});
// 監控 SASS 文件,有變更則執行CSS注入
gulp.watch(
'src/sass/**/*.scss'
, [
'styleReload'
]);
// 監控 CSS 文件,有變更則執行CSS注入
gulp.watch(
'src/css/**/*.css'
, [
'styleReload'
]);
// 監控 js 文件,有變更則執行 script 任務
gulp.watch(
'src/js/**/*.js'
, [
'script'
]);
// 監控圖片文件,有變更則執行 image 任務
gulp.watch(
'src/img/**/*'
, [
'image'
]);
// 監控 html 文件,有變更則執行 html 任務
gulp.watch(
'src/**/*.html'
, [
'html'
]);
// 監控 dist 目錄下除 css 目錄之外的變更(如js,圖片等),則自動刷新頁面
gulp.watch([
'dist/**/*'
,
'!dist/css/**/*'
]).on(
'change'
, browserSync.reload);
});
|
1
|
gulp taskname // 如 gulp sass,不指定 taskname 則默認執行 default 任務
|
趕在四年一遇的2月29號,匆忙發表。
PS. 感謝 @合金大聖 訂正錯誤。 16.07.04
更新 Gulp 系列教程,請戳下面