博主最近準備開發一個UI組件庫,遇到了一個難題,博主但願單獨打包組件樣式scss文件,而不是與組件一塊兒用webpack打包。調研發現gulp能夠解決這個問題,因而,研究了下gulp4在前端工程化中的應用。css
gulp是一種基於流的自動化構建工具,基於nodeJs中的stream(流)來讀取和寫入數據,相對於grunt直接對文件進行IO讀寫來講速度更快。
藉助於gulp,咱們能夠自動化地完成js/sass/less/css等文件的的測試、檢查、合併、壓縮、格式化,並監聽文件在改動後重復指定的這些步驟。
gulp與webpack最大的不一樣點體如今gulp並不能像webpack那樣將css/less/image等非js類資源模塊化打包。
gulp適用場景:單獨打包sass/less/css、壓縮圖片、壓縮html等。html
全局安裝gulp前端
$ npm install gulp -g |
$ npm install gulp --save-dev |
$ gulp -v CLI version: 2.2.0 Local version: 4.0.2 |
// 定義default任務(gulp4)
gulp.task('default', async() => {
await ...
});
複製代碼
執行gulp(默認會執行default任務)node
$ gulp |
gulp3與gulp4的變化,主要體如今任務定義及執行體系的變化。webpack
gulp3對於任務,順序執行完該任務的依賴任務後,才執行該任務。git
gulp3中任務定義:es6
// gulpfile.js文件
const gulp = require('gulp');
// 定義task1任務
gulp.task('task1', function() {
console.log('task1');
});
// 定義task2任務
gulp.task('task2', function() {
console.log('task2');
});
// 定義default任務,依賴於task1任務和task2任務
gulp.task('default', ['task1', 'task2'], function() {
console.log('done');
});
複製代碼
gulp3中任務執行:
執行順序:
start task1 => finish task1 => start task2 => finish task2 => start default => finish defaultgithub
gulp4中再也不支持gulp3中任務定義及依賴執行方式。
假設定義任務仍然採用gulp3方式:web
gulp.task('task1', function() {
console.log('task1');
});
複製代碼
執行task1,報錯 Did you forget to signal async completion?
解決方法:採用async await方式定義任務,npm
// 定義task1任務
gulp.task('task1', async() => {
await console.log('task1');
});
複製代碼
執行task1,任務執行成功。
gulp4如果採用如gulp3中依賴執行方式,則會報 Task function must be specified錯誤。gulp4中任務執行再也不採用依賴執行方式,而是採用串行執行(
gulp.series
)和並行執行(gulp.parallel
)兩種方式。
(1)串行(順序)執行,與gulp3中順序執行不一樣,先開始default任務,再順序執行task一、task2任務,最後結束default任務。
gulp.series('task1','task2')
或
gulp.parallel('task1','task2')
替代gulp3中
gulp.task('default', ['task1', 'task2'], function() {... })
方式。
gulp.series
):
const gulp = require('gulp');
// 定義任務task1
gulp.task('task1', async() => {
await console.log('task1');
});
// 定義任務task2
gulp.task('task2', async() => {
await console.log('task2');
});
// 串行執行task一、task2任務
gulp.task('default', gulp.series('task1', 'task2'));
複製代碼
執行結果:
執行順序:
start default => start task1 => finish task1 => start task2 => finish task2 => finish default
並行執行((2)並行執行,先開始default任務,而後同步執行並行任務,最後結束default任務。
gulp.parallel
):
const gulp = require('gulp');
// 定義任務task1
gulp.task('task1', async() => {
await console.log('task1');
});
// 定義任務task2
gulp.task('task2', async() => {
await console.log('task2');
});
// 並行執行task一、task2任務
gulp.task('default', gulp.parallel('task1', 'task2'));
複製代碼
執行結果:
執行順序:
start default => start task1 => start task2 => finish task1 => finish task2 => finish default
要點:
1.gulp4中定義任務採用async await方式定義任務。
2.gulp4中任務執行有串行(gulp.series
)和並行執行(gulp.parallel
)方式,經過合理配置串行和並行便可實現gulp3中的依賴執行。
接下來將探討如何使用gulp打包js、css、image、html以及如何在生產和開發環境下編寫gulp配置。
所需插件:
實現功能:
將當前目錄下的main.js、hello.js、world.js進行eslint檢測,babel轉換,合併壓縮成app.min.js輸出到dist目錄
const gulp = require('gulp');
const babel = require('gulp-babel'); // babel轉換
const eslint = require('gulp-eslint'); // eslint檢測
const concat = require('gulp-concat'); // 合併文件
const uglify = require('gulp-uglify'); // 壓縮js
const del = require('del'); // 清空目錄
// 合併壓縮的文件
const jsFiles = ['./main.js', './hello.js', './world.js'];
// eslint任務,實現eslint檢測和代碼格式化
gulp.task('eslint', async() => {
await gulp.src(jsFiles)
.pipe(eslint())
.pipe(eslint.format()) // 格式化
.pipe(eslint.failAfterError()); // 報錯
});
// clean任務,清空dist文件夾
gulp.task('clean', async() => {
await del(['./dist/']);
});
// jsCompress任務,實現js轉換、合併、壓縮
gulp.task('jsCompress', async() => {
await gulp.src(jsFiles)
.pipe(babel({
presets: ['@babel/env'] // es6轉換爲es5
}))
.pipe(concat('app.min.js')) // 合併爲app.min.js
.pipe(uglify()) // 文件壓縮
.pipe(gulp.dest('./dist/')) // 文件寫入到dist文件夾
});
// 順序執行clean、eslint、jsCompress任務
gulp.task('default', gulp.series('clean', 'eslint', 'jsCompress'));
複製代碼
執行gulp,任務執行成功: 在dist文件夾下生成了app.min.js
所需插件:
實現功能:
(1)當前目錄下的main.scss、style.scss轉換css而後合併壓縮成scss.css寫入到dist目錄。
(2)當前目錄下的全部css文件合併壓縮成style.min.css寫入到dist目錄。
const gulp = require('gulp');
const concat = require('gulp-concat'); // 合併文件
const cleanCss = require('gulp-clean-css'); // 壓縮css
const sass = require('gulp-sass'); // sass編譯
const del = require('del'); // 清空目錄
// clean任務,清空dist目錄
gulp.task('clean', async() => {
await del(['./dist']);
});
// sass任務,實現scss文件編譯、合併、壓縮
gulp.task('sass', async() => {
await gulp.src(['./main.scss', './style.scss'])
.pipe(sass()) // sass編譯
.pipe(concat('scss.css')) // 合併爲scss.css
.pipe(cleanCss()) // 壓縮css文件
.pipe(gulp.dest('./dist'));
});
// css任務,實現css合併、壓縮
gulp.task('css', async() => {
await gulp.src(['./*.css'])
.pipe(concat('style.min.css')) // 合併爲style.min.css
.pipe(cleanCss()) // 壓縮
.pipe(gulp.dest('./dist'));
});
// 先執行clean任務,再並行執行sass和css任務
gulp.task('default', gulp.series('clean', gulp.parallel('sass', 'css')));
複製代碼
執行gulp,任務執行成功
在dist目錄下生成了scss.css和style.min.css文件。
所需插件:
實現功能:
(1)實現當前目錄下的html壓縮輸出到dist目錄下
(2)實現當前目下的png圖片輸出到dist目錄下
const gulp = require('gulp');
const htmlmin = require('gulp-htmlmin'); // html壓縮
const imagemin = require('gulp-imagemin'); // 圖片壓縮
const del = require('del'); // 清空目錄
// clean任務,清空dist目錄
gulp.task('clean', async() => {
await del('./dist');
});
// html任務,壓縮html文件代碼
gulp.task('html', async() => {
await gulp.src('./*.html')
.pipe(htmlmin({ collapseWhitespace: true })) // 壓縮去除空格
.pipe(gulp.dest('dist'));
});
// image任務,壓縮圖片
gulp.task('image', async() => {
await gulp.src('./*.png')
.pipe(imagemin())
.pipe(gulp.dest('./dist'));
})
// 先串行執行clean任務,後並行執行html和image任務
gulp.task('default', gulp.series('clean', gulp.parallel('html', 'image')));
複製代碼
執行gulp,任務執行成功
在dist目錄下生成了壓縮的html文件和image
前端開發過程當中,針對開發環境和生產環境配置每每不一樣:
開發環境:起本地服務,支持調試,熱更新。
生產環境:壓縮合並代碼用於部署線上環境。
所需插件:
實現功能:
(1)實現js eslint檢測、babel轉換、合併、壓縮
(2)實現sass編譯與css合併、壓縮
(3)實現html壓縮
(4)實現image壓縮
(5)開發環境預覽、熱更新
(6)生產環境各個文件打包
const gulp = require('gulp');
const babel = require('gulp-babel'); // es6轉爲es5語法
const eslint = require('gulp-eslint'); // eslint代碼檢測
const concat = require('gulp-concat'); // 文件合併
const uglify = require('gulp-uglify'); // js壓縮
const sass = require('gulp-sass'); // sass編譯
const htmlmin = require('gulp-htmlmin'); // html壓縮
const connect = require('gulp-connect'); // 起server服務
const imagemin = require('gulp-imagemin'); // 圖片壓縮
const del = require('del'); // 清空目錄
const cleanCss = require('gulp-clean-css'); // css壓縮
// 清空dist目錄
gulp.task('clean', async() => {
await del(['./dist']);
});
// html壓縮公共函數
const htmlMin = () => {
return gulp.src('./index.html')
.pipe(htmlmin(
{collapseWhitespace: true}
))
.pipe(gulp.dest('dist'));
};
// html:dev task,用於開發環境下,瀏覽器自動刷新
gulp.task('html:dev', async() => {
await htmlMin().pipe(connect.reload());
});
// html:build task,用於生產環境
gulp.task('html:build', async() => {
await htmlMin();
});
// sass轉換、合併、壓縮css公共函數
const cssMin = () => {
return gulp.src(['./css/style.scss', './css/*.css'])
.pipe(sass())
.pipe(concat('style.min.css'))
.pipe(cleanCss())
.pipe(gulp.dest('./dist/css'))
};
// css:dev任務,用於開發環境
gulp.task('css:dev', async() => {
await cssMin().pipe(connect.reload());
});
// css:dev任務,用於生產環境
gulp.task('css:build', async() => {
await cssMin();
});
// js eslint檢測、babel轉換、合併、壓縮公共函數
const jsMin = () => {
return gulp.src('./js/*.js')
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError())
.pipe(babel({
presets: ['@babel/env']
}))
.pipe(concat('main.min.js'))
.pipe(uglify())
.pipe(gulp.dest('./dist/js'));
};
// js:dev任務,用於開發環境
gulp.task('js:dev', async() => {
await jsMin().pipe(connect.reload());
});
// js:build,用於生產環境
gulp.task('js:build', async() => {
await jsMin();
});
// 圖片壓縮公共函數
const imageMin = () => {
return gulp.src('./img/*.png')
.pipe(imagemin())
.pipe(gulp.dest('./dist/img'));
};
// image:dev任務,用於開發環境
gulp.task('image:dev', async() => {
await imageMin().pipe(connect.reload());
});
// image:build任務,用於生產環境
gulp.task('image:build', async() => {
await imageMin();
});
// server任務,目錄爲dist,入口文件爲dist/index.html,port 8080
gulp.task('server', () => {
connect.server(
{
root: './dist',
port: 8080,
livereload: true
}
)
});
// watch任務,監聽源文件變化,執行對應開發任務
gulp.task('watch', () => {
gulp.watch(['./css/*.css', './css/*.scss'], gulp.series('css:dev'));
gulp.watch('./js/*.js', gulp.series('js:dev'));
gulp.watch('./index.html', gulp.series('html:dev'));
gulp.watch('./img/*.png', gulp.series('image:dev'));
});
// dev任務,啓動開發環境
gulp.task('dev', gulp.series(gulp.parallel('watch', 'server')));
// build任務,用於生產環境下打包壓縮源代碼
gulp.task('build', gulp.series('clean', gulp.parallel('html:build', 'js:build', 'css:build', 'image:build')))
複製代碼
在當前目錄下package.json中script補充dev和build命令:
"scripts": {
"dev": "gulp dev",
"build": "gulp build"
},
複製代碼
執行npm run dev
,便可啓動開發模式,當咱們修改源html、css、js等文件時,會執行對應打包任務從新打包,瀏覽器自動刷新。
執行npm run build
,打包目錄中的源代碼。
在dist文件夾中包含了打包處理後的html、css、js、image等資源。
以上就是博主探索出的gulp4在前端工程化的應用。相信你們看完文章後對gulp應該有了一個初步的認識,後續感興趣的小夥伴還能夠考慮將gulp集成到webpack配置中,更好地提高開發效率。
gulp中文網:www.gulpjs.com.cn
(以爲不錯的小夥伴能夠給文章點個贊,還有github star一下,灰常感謝^_^)