gulp4在前端工程化中的應用

前言

    博主最近準備開發一個UI組件庫,遇到了一個難題,博主但願單獨打包組件樣式scss文件,而不是與組件一塊兒用webpack打包。調研發現gulp能夠解決這個問題,因而,研究了下gulp4在前端工程化中的應用。css

1.簡介

     gulp是一種基於流的自動化構建工具,基於nodeJs中的stream(流)來讀取和寫入數據,相對於grunt直接對文件進行IO讀寫來講速度更快。
    藉助於gulp,咱們能夠自動化地完成js/sass/less/css等文件的的測試、檢查、合併、壓縮、格式化,並監聽文件在改動後重復指定的這些步驟。
    gulp與webpack最大的不一樣點體如今gulp並不能像webpack那樣將css/less/image等非js類資源模塊化打包。
    gulp適用場景:單獨打包sass/less/css、壓縮圖片、壓縮html等。html

2.安裝gulp

全局安裝gulp前端

$ npm install gulp -g

做爲項目的開發依賴(devDependencies)安裝:
$ npm install gulp --save-dev

查看gulp版本( 注意:gulp3與gulp4區別較大,請參考文章第4節
$ gulp -v
CLI version: 2.2.0
Local version: 4.0.2

新建 gulpfile.js
// 定義default任務(gulp4)
gulp.task('default', async() => { 
    await ...
});
複製代碼

執行gulp(默認會執行default任務)node

$ gulp

3.經常使用API

  • gulp.src(globs[, options])
    讀取目錄下的文件
  • gulp.dest(path[, options])
    向目錄寫入文件
  • gulp.task(name[, deps], fn)
    定義一個gulp任務
  • gulp.pipe()
    將目標文件經過插件處理
  • gulp.watch(glob [, opts], tasks) 或 gulp.watch(glob [, opts, cb])
    監視文件系統,而且能夠在文件發生改動時候執行操做
  • gulp.series(task1, task2, task3) (gulp4新增)
    串行執行任務
  • gulp.parallel(task1, task2, task3) (gulp4新增)
    並行執行任務

4.gulp3與glup4

gulp3與gulp4的變化,主要體如今任務定義及執行體系的變化。webpack

4.1gulp3中任務定義及執行順序

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

4.2gulp4中任務定義及執行順序

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中任務執行再也不採用依賴執行方式,而是採用串行執行(gulp.series)和並行執行(gulp.parallel)兩種方式。
(1)串行(順序)執行,與gulp3中順序執行不一樣,先開始default任務,再順序執行task一、task2任務,最後結束default任務。

gulp4如果採用如gulp3中依賴執行方式,則會報 Task function must be specified錯誤。

解決方案:
採用 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配置。

5.gulp檢測、轉換、打包、壓縮js

所需插件:

  • gulp-eslint:eslint檢測
  • gulp-babel:babel轉換
  • gulp-concat:合併文件(js/css/html等)
  • gulp-uglify:壓縮js

實現功能:
將當前目錄下的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
 

6.gulp轉換、合併、壓縮scss/css

所需插件:

  • gulp-sass:sass編譯
  • gulp-concat:合併文件
  • gulp-clean-css:壓縮css

實現功能:
(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文件。
 

7.gulp壓縮html、image

所需插件:

  • gulp-htmlmin:html壓縮
  • gulp-imagemin:圖片壓縮

實現功能:
(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
 

8.gulp在生產和開發環境下的應用

前端開發過程當中,針對開發環境和生產環境配置每每不一樣:
開發環境:起本地服務,支持調試,熱更新。
生產環境:壓縮合並代碼用於部署線上環境。
所需插件:

  • del:清空目錄
  • gulp-eslint:eslint代碼檢測
  • gulp-babel:babel轉換,將es6代碼轉爲es5
  • gulp-concat:合併文件
  • gulp-uglify:js壓縮
  • gulp-sass:sass編譯
  • gulp-clean-css:css壓縮
  • gulp-htmlmin:html壓縮
  • gulp-imagemin:圖片壓縮
  • gulp.connect:起server服務調試

實現功能:
(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一下,灰常感謝^_^)

相關文章
相關標籤/搜索