基於 node 平台開發的前端構建工具,主要用來設定程序自動處理靜態資源的工作。簡單的說,gulp就是用來打包項目的。
將機械化操作編寫成任務,想要執行機械化操作時執行一個命令行命令任務就能自動執行了。
用機器代替手工,提高開發效率。
中文官網:https://www.gulpjs.com.cn/docs/
Gulp 使用
1.使用 npm install gulp 下載 gulp 庫文件
2.在項目根目錄下建立 gulpfile.js 文件
3.重構項目的文件夾結構 src 目錄放置源代碼文件,dist 目錄放置構建后文件
4.在 gulpfile.js 文件中編寫任務
5.在命令行工具中執行 gulp 任務
Gulp 中提供的方法:
gulp.src(): 獲取任務要處理的文件
gulp.dest(): 輸出文件
gulp.task(): 建立 gulp 任務
gulp.watch(): 監控文件的變化
語法示例:
const gulp = require('gulp'); // 使用 gulp.task() 方法建立任務 gulp.task('first', () => { // 獲取要處理的文件 gulp.src('./src/css/base.css') // 將處理后的文件輸出到 dist 目錄 .pipe(gulp.dest('./dist/css')); })
項目示例:
1.新建 gulp-demo 文件夾,通過命令行工具安裝庫文件:
npm install gulp
2.在項目根目錄下建立 gulpfile.js 文件
3.在項目根目錄下建立 src 文件夾,里面復制粘貼一些文件:
4.在 gulpfile.js 文件中編寫任務:
// 引用 gulp 模塊 const gulp = require('gulp'); // 使用 gulp.task() 方法建立任務 // 1.任務的名出 // 2.任務的回調函數 gulp.task('first', () => { console.log('第一個gulp任務'); // 1.使用 gulp.src() 獲取要處理的文件 gulp.src('./src/css/base.css') // 2.將處理后的文件輸出到 dist/css 目錄 .pipe(gulp.dest('./dist/css')); });
5.在命令行工具中執行 gulp 任務
我們想執行 gulpfile.js 中的 first 任務,需要安裝 gulp 同名的命令行工具:
npm install gulp-cli -g
下面要執行 first 任務,在命令行輸入:
gulp first
輸入結果:
然后會看到項目根目錄下的 dist 目錄,多了一個 css 文件夾,里面有個 base.css 文件。
Gulp 插件
我們要處理文件的合並、壓縮等操作,接口中沒有提供,都放在了插件中。
插件下載:
npm install 插件名 --save
gulp-concat : 合並文件(js/css)
gulp-rename : 文件重命名
gulp-htmlmin:壓縮 html 文件
gulp-csso:壓縮優化css
gulp-clean-css : 壓縮 css
gulp-babel:JavaScrtipt 語法轉化
gulp-less : 編譯 less
gulp-sass:編譯 sass
gulp-uglify : 壓縮混淆 js 文件
gulp-file-include:公共文件包含
browsersync:瀏覽器時間同步
gulp-livereload : 實時自動編譯刷新
gulp-connect:熱加載,配置一個服務器
gulp-load-plugins:打包插件(里面包含了其他所有插件)
下面我們需要做一個任務示例1:
1、先打開命令行工具,安裝 gulp-htmlmin 插件:
npm install gulp-htmlmin --save-dev
2、引用插件
打開 gulpfile.js 文件:
// 引用 gulp-htmlmin 插件 const htmlmin = require('gulp-htmlmin'); // HTML 任務 gulp.task('htmlmin', () => { });
繼續編輯 htmlmin 任務:
// 1.html 文件中代碼的壓縮操作 gulp.task('htmlmin', () => { // 使用 gulp.src() 獲取 src 目錄下的所有 html 文件 gulp.src('./src/*.html') // 壓縮 html 文件中的代碼,collapseWhitespace:壓縮折疊空格 .pipe(htmlmin({ collapseWhitespace: true })) .pipe(gulp.dest('./dist')); });
3、回到命令行工具中執行任務:
gulp htmlmin
然后打開項目下 dist 目錄,可以看到2個壓縮后的 html 文件,再打開該文件,可以看到壓縮后的代碼。
4、使用 gulp-file-includ 插件,抽取 html 中的公共代碼
安裝 gulp-file-includ 插件:
npm install --save-dev gulp-file-include
引用插件:
打開 gulpfile.js 文件:
// 引用 gulp-file-include 插件 const fileinclude = require('gulp-file-include');
添加 fileinclude 代碼使用:
// HTML 任務 // 1.html 文件中代碼的壓縮操作 // 2.抽取 html 文件中的公共代碼 gulp.task('htmlmin', () => { // 使用 gulp.src() 獲取 src 目錄下的所有 html 文件 gulp.src('./src/*.html') // 抽離公共代碼 .pipe(fileinclude()) // 壓縮 html 文件中的代碼,collapseWhitespace:壓縮折疊空格 .pipe(htmlmin({ collapseWhitespace: true })) .pipe(gulp.dest('./dist')); });
抽取公共代碼:
在 src 目錄下新建 common 文件夾,創建 header.html 文件,並把頭部的公共代碼粘貼過來:
<!-- 頭部框架開始 --> <div class="header"> <div class="w1100"> <!-- 網站logo開始 --> <h1 class="logo fl"> <a href="index.html"><img src="images/logo.png" alt="黑馬程序員"></a> </h1> <!-- 網站logo結束 --> <!-- 網站導航開始 --> <ul class="navigation fr"> <li> <a href="index.html">首頁</a> </li> <li> <a href="#">登錄</a> </li> </ul> <!-- 網站導航結束 --> </div> </div> <!-- 頭部框架結束 -->
再把 default.html 和 article.html 的頭部代碼部分刪除掉,修改為:
@@include('./common/header.html')
回到命令行工具中,重新執行 htmlmin 任務:
gulp htmlmin
打開 dist 目錄下的 html 文件,可以查看代碼,發現有 header 部分代碼。
任務示例2:
less 語法轉換為 css 語法、把 css 代碼進行壓縮。
1、打開 gulpfile.js 文件,建立 Css 任務:
// Css 任務 gulp.task('cssmin', () => { // 使用 gulp.src() 獲取 css 目錄下的所有 less 文件 gulp.src('./src/css/*.less') });
2、安裝 gulp-less 插件:
npm install gulp-less
3、gulpfile.js 文件,引用 gulp-less:
// 引用 gulp-less 插件 const less = require('gulp-less'); // Css 任務 gulp.task('cssmin', () => { // 使用 gulp.src() 獲取 css 目錄下的所有 less 文件 gulp.src('./src/css/*.less') // 將 less 語法進行轉換 .pipe(less()) // 將處理后的文件輸出到 dist/css 目錄 .pipe(gulp.dest('./dist/css')) });
4、在 src/css 目錄下,新建 a.less 文件:
.headers { width: 100px; .logo { height: 200px; background-color: red; } }
5、在命令行執行任務:
gulp cssmin
然后就可以在 dist/css 目錄下看到 a.css 文件了。
.headers{ width: 100px } .headers .logo{ height: 200px; background-color: red }
6、把 css 文件進行壓縮
怎么把 css 目錄下的 less 文件和 css 文件同時選中呢?
語法修改為數組,數組里面可以寫多個路徑:
// 使用 gulp.src() 獲取 css 目錄下的所有 less 文件及 css 文件 gulp.src(['./src/css/*.less', './src/css/*.css'])
7、安裝 gulp-csso 插件:
npm install gulp-csso --save-dev
8、在 gulpfile.js 文件,引用 gulp-csso:
// 引用 gulp-csso 插件 const csso = require('gulp-csso');
9、實現 css 代碼的壓縮:
// Css 任務 // 1. less 語法轉換 // 2. css 代碼壓縮 gulp.task('cssmin', () => { // 使用 gulp.src() 獲取 css 目錄下的所有 less 文件及 css 文件 // gulp.src('./src/css/*.less') gulp.src(['./src/css/*.less', './src/css/*.css']) // 將 less 語法進行轉換 .pipe(less()) // 壓縮 css 文件中的代碼 .pipe(csso()) // 將處理后的文件輸出到 dist/css 目錄 .pipe(gulp.dest('./dist/css')) });
回到命令行工具中執行任務:
gulp cssmin
在 dist/css 目錄下,可以發現壓縮后的 css 文件,打開a.css發現代碼已經進行了壓縮:
.headers{width:100px}.headers .logo{height:200px;background-color:red}
任務示例3:
實現 es6 代碼的轉換、js 代碼的壓縮
1、打開 gulpfile.js 文件,建立 Js 任務:
// Js 任務 gulp.task('jsmin', () => { // 使用 gulp.src() 獲取 js 目錄下的所有 js 文件 gulp.src('./src/js/*.js') });
2、安裝 gulp-babel 插件:
npm install --save-dev gulp-babel @babel/core @babel/preset-env
gulp-babel 后面@部分,表示它所依賴的插件。
3、在 gulpfile.js 文件中引用 gulp-babel:
// 引用 gulp-babel 插件 const babel = require('gulp-babel');
4、調用該插件:
// Js 任務 gulp.task('jsmin', () => { // 使用 gulp.src() 獲取 js 目錄下的所有 js 文件 gulp.src('./src/js/*.js') // es6 轉換 .pipe(babel({ // 它可以判斷當前代碼的運行環境,將代碼轉換為當前運行環境所支持的代碼 presets: ['@babel/env'] })) .pipe(gulp.dest('./dist/js')) });
5、在 src/js 目錄下,新建 base.js 文件,寫一些 es6 的語法:
const x = 100; let y = 200; const fn = () => { console.log(1234); }
6、在命令行執行任務:
gulp jsmin
然后就可以看到 dist/js 目錄下的 base.js 文件:
"use strict"; var x = 100; var y = 200; var fn = function fn() { console.log(1234); };
已經轉換為了 es5 的代碼。
7、安裝 gulp-uglify 插件:
npm install --save-dev gulp-uglify
8、在 gulpfile.js 文件中引用 gulp-uglify:
// 引用 gulp-uglify 插件 const uglify = require('gulp-uglify');
9、調用該插件:
// Js 任務 // 1. ES6 代碼轉換 // 2. js 代碼壓縮 gulp.task('jsmin', () => { // 使用 gulp.src() 獲取 js 目錄下的所有 js 文件 gulp.src('./src/js/*.js') // es6 轉換 .pipe(babel({ // 它可以判斷當前代碼的運行環境,將代碼轉換為當前運行環境所支持的代碼 presets: ['@babel/env'] })) // 壓縮 js 文件 .pipe(uglify()) .pipe(gulp.dest('./dist/js')) });
10、回到命令行工具中執行任務:
gulp jsmin
重新打開 dist/js 目錄下的 base.js 文件,發現代碼已經進行了壓縮:
"use strict";var x=100,y=200,fn=function(){console.log(1234)};
任務示例4:
把 src 目錄下的 images 文件夾和 lib 文件夾,拷貝到 dist 目錄下
1、打開 gulpfile.js 文件,建立 copy 任務:
// 復制文件夾 gulp.task('copy', () => { // 使用 gulp.src() 獲取 src 目錄下的 images 文件夾 gulp.src('./src/images/*') .pipe(gulp.dest('./dist/images')) // 使用 gulp.src() 獲取 src 目錄下的 lib 文件夾 gulp.src( './src/lib/*') .pipe(gulp.dest('./dist/lib')) });
2、回到命令行工具中執行任務:
gulp copy
完成后,可以看到 dist 目錄下多了 images 文件夾和 lib 文件夾。
任務示例5:
執行一個任務,其他的任務也一起執行
1、打開 gulpfile.js 文件,建立構建任務:
// 構建任務 // 當在命令行執行 default 任務時,會依次執行后面的任務 gulp.task('default', ['htmlmin', 'cssmin', 'jsmin', 'copy']);
2、回到命令行工具中執行任務:
gulp default
這里執行報錯:
百度了問題,發現是4.0版本的原因。
3、構建任務的代碼要修改為:
// 構建任務 // 當在命令行執行 default 任務時,會依次執行后面的任務 // gulp.series|4.0 依賴順序執行 // gulp.parallel|4.0 多個依賴嵌套'html','css','js'並行 gulp.task('default', gulp.series(gulp.parallel('htmlmin','cssmin','jsmin','copy')));
4、重新回到命令行工具執行任務:
gulp default
此時執行成功了。
注意:如果說任務名稱叫 default,那么執行任務的時候就可以只輸入:gulp,會自動地去找一個名字叫 default 的任務。
文件匹配:
往往我們在使用src方法的時候需要輸入多個或者一類文件,而不僅僅是某個具體的文件,這時我們就可以使用gulp提供的匹配規則來處理。
"src/file.js"
:單個文件["src/file1,src/file2.js"]
:多個文件*
: 所有文件- **:0或者多個文件夾
- {}:多個屬性
- !:排除
示例:
src('src/*.js') // src自身目錄所有的js文件,不含后代文件夾中 src('src/a*c.js') src('src/**/*.js') // src目錄所有的js文件,含后代文件夾中的 src('src/*.{jpg,png,gif}') // src自身目錄下的所有jpg、png和gif文件 src(['**/*.js', '!node_modules/**']) // 所有的js文件,但是node_modules下的除外
注意:src 接收的文件匹配字符串會順序解釋,所以你可以寫成這樣 gulp.src(['.js', '!b.js', 'bad.js'])
(排除所有以 b 開頭的 JS 文件但是除了 bad.js
)
gulp4.0相比3.0有一些改變的地方:
1、gulp4.0分離了cli和核心部分
gulp -v # 輸出 CLI version: 2.0.1 Local version: 4.0.2
2、Task
task分為兩種:
- Private tasks:配置文件中的一個function,僅能在該文件中使用
- Public tasks:將Private tasks導出,可以供gulp命令執行
const { series, parallel } = require('gulp'); // Private tasks function clean(cb) { // body omitted cb(); } // Private tasks function build(cb) { // body omitted cb(); } exports.build = build; // Public tasks, 執行gulp build exports.default = series(clean, parallel(css, javascript)); // Public tasks, 執行gulp
注意:
在task中,操作完成時,我們必須要通過cb()或者return的方式來告知gulp此任務已完成。
// cb function clean(cb) { del(['dist]); cb(); }); // return function minifyjs() { return src('src/**/*.js') .pipe(minify()) .pipe(dest('dist')); }); function promiseTask() { return new Promise(function(resolve, reject) { // body omitted resolve(); }); });
所以可以把 gulpfile.js 文件整體修改為:
// 引用 gulp 模塊 const gulp = require('gulp'); // 引用 gulp-htmlmin 插件 const htmlmin = require('gulp-htmlmin'); // 引用 gulp-file-include 插件 const fileinclude = require('gulp-file-include'); // 引用 gulp-less 插件 const less = require('gulp-less'); // 引用 gulp-csso 插件 const csso = require('gulp-csso'); // 引用 gulp-babel 插件 const babel = require('gulp-babel'); // 引用 gulp-uglify 插件 const uglify = require('gulp-uglify'); // 使用 gulp.task() 方法建立任務 // 1.任務的名出 // 2.任務的回調函數 gulp.task('first', () => { console.log('第一個gulp任務'); // 1.使用 gulp.src() 獲取要處理的文件 gulp.src('./src/css/base.css') // 2.將處理后的文件輸出到 dist/css 目錄 .pipe(gulp.dest('./dist/css')); }); // HTML 任務 // 1. html 文件中代碼的壓縮操作 // 2. 抽取 html 文件中的公共代碼 gulp.task('htmlmin', (cb) => { // 使用 gulp.src() 獲取 src 目錄下的所有 html 文件 gulp.src('./src/*.html') // 抽離公共代碼 .pipe(fileinclude()) // 壓縮 html 文件中的代碼,collapseWhitespace:壓縮折疊空格 .pipe(htmlmin({ collapseWhitespace: true })) .pipe(gulp.dest('./dist')); cb(); }); // Css 任務 // 1. less 語法轉換 // 2. css 代碼壓縮 gulp.task('cssmin', (cb) => { // 使用 gulp.src() 獲取 css 目錄下的所有 less 文件及 css 文件 // gulp.src('./src/css/*.less') gulp.src(['./src/css/*.less', './src/css/*.css']) // 將 less 語法進行轉換 .pipe(less()) // 壓縮 css 文件中的代碼 .pipe(csso()) // 將處理后的文件輸出到 dist/css 目錄 .pipe(gulp.dest('./dist/css')); cb(); }); // Js 任務 // 1. ES6 代碼轉換 // 2. js 代碼壓縮 gulp.task('jsmin', (cb) => { // 使用 gulp.src() 獲取 js 目錄下的所有 js 文件 gulp.src('./src/js/*.js') // es6 轉換 .pipe(babel({ // 它可以判斷當前代碼的運行環境,將代碼轉換為當前運行環境所支持的代碼 presets: ['@babel/env'] })) // 壓縮 js 文件 .pipe(uglify()) .pipe(gulp.dest('./dist/js')) cb(); }); // 復制文件夾 gulp.task('copy', () => { // 使用 gulp.src() 獲取 src 目錄下的 images 文件夾 return gulp.src('./src/images/*') .pipe(gulp.dest('./dist/images')) // 使用 gulp.src() 獲取 src 目錄下的 lib 文件夾 return gulp.src('./src/lib/*') .pipe(gulp.dest('./dist/lib')) }); // 構建任務 // 當在命令行執行 default 任務時,會依次執行后面的任務 // gulp.series|4.0 依賴順序執行 // gulp.parallel|4.0 多個依賴嵌套'html','css','js'並行 gulp.task('default', gulp.series('htmlmin','cssmin','jsmin','copy'));
此時在命令行執行任務后的效果圖:(發現前面執行的任務都只是開始,沒有告知完成)
3、series:序列(順序執行)
// task1執行完再執行task2 exports.taskName = series(task1, task2)
4、parallel:並行(同時執行)
// task1和task2同時執行 exports.taskName = parallel(task1, task2)
5、 混用:
exports.taskName = series(clean, parallel(css, javascript))
6、輸入與輸出
gulp提供了src及dest方法分別來進行文件讀入、輸出操作,同時提供了pipe管道方法來鏈式執行其他操作。
const { src, dest } = require('gulp'); // 將src目錄下的所有js輸出到output目錄 exports.default = function() { return src('src/*.js') .pipe(dest('output/')); }
如果我們想在中途添加文件可以采用如下方式:
const { src, dest } = require('gulp'); const uglify = require('gulp-uglify'); exports.default = function() { return src('src/*.js') .pipe(uglify()) .pipe(src('vendor/*.js')) // 添加文件 .pipe(dest('output/')); }
當然我們也可以進行多次輸出:
const { src, dest } = require('gulp'); const babel = require('gulp-babel'); const uglify = require('gulp-uglify'); exports.default = function() { return src('src/*.js') .pipe(babel()) .pipe(dest('temp/')) .pipe(uglify()) .pipe(dest('output/')); }
7、監聽文件:
我們可以使用watch方法來監聽文件的改動,以便在改動時執行相應的處理任務。
const { watch, series } = require('gulp'); function clean(cb) { // body omitted cb(); } function javascript(cb) { // body omitted cb(); } function css(cb) { // body omitted cb(); } exports.default = function() { watch('src/*.css', css); watch('src/*.js', series(clean, javascript)); };
監聽方法會返回一共實例,該實例提供了如下幾個方法:
watcher.on(eventName, eventHandler)
eventName[string]
:事件名稱,可以是add
,addDir
,change
,unlink
,unlinkDir
,ready
,error
, orall
eventHandler[function]
:事件處理函數,該函數接收path和stats兩個參數。
const { watch } = require('gulp'); const watcher = watch(['input/*.js']); watcher.on('change', function(path, stats) { console.log(`File ${path} was changed`); }); watcher.on('add', function(path, stats) { console.log(`File ${path} was added`); }); watcher.on('unlink', function(path, stats) { console.log(`File ${path} was removed`); }); watcher.close();
watcher.close()
:關閉文件監聽器
watcher.add(globs)
:添加文件到監聽器
globs[string|array]
: 要添加的文件
watcher.unwatch(globs)
:移除監聽器中的文件
globs[string|array]
: 要移除的文件
常用插件
- gulp-clean:用於清理;
- gulp-notify:用於打印消息文本;
- gulp-rename:用於修改名字;
- gulp-concat:用於合並文件;
- gulp-zip:用於生成一個zip壓縮包;
- gulp-minify-css:用於壓縮css;
- gulp-autoprefixer:用於給css添加前綴;
- gulp-imagemin:用於給圖片進行優化;
- gulp-uglify:用於壓縮js;
- amd-optimize:用於amd模塊引用編譯;
- gulp-import-css:如果css文件是通過import導入的可以使用此插件進行合並優化;
- gulp-rev-replace:用於替換;
- gulp-useref:引入使用build標記,進行替換;
- gulp-rev:生成md5文件名;
- gulp-filter:對文件進行過濾;
- gulp-header:壓縮之后將注釋寫入到文件的頭部
- gulp-if:進行邏輯判斷
- gulp-size:獲取文件大小
- gulp-less:編譯less文件
- gulp-sass:編譯sass文件
- gulp-file-include:對文件進行引入
- gulp-sourcemaps:生成map文件
- gulp-livereload:自動刷新
- gulp-clean-css:css壓縮
- browserSync:啟動server並啟動熱更新
- gulp-plumber : 監測工作流,報錯,防止遇到錯誤時直接退出gulp
- gulp-rev : 文件名添加版本號
- gulp-css-spritesmith:根據css文件自動生成雪碧圖
如果要查找gulp插件,一般有兩個地方: