gulp入門+ES6

jopen 10年前發布 | 46K 次閱讀 gulp JavaScript開發


Gulp是一個基于 nodejs stream 的流式前端構建工具,與Grunt功能相同,專注于前端資源的編譯、檢查、壓縮等自動化工作。

安裝gulp

安裝gulp之前,更新一下npm(可選,避免因版本過低報錯):

curl https://www.npmjs.org/install.sh | sudo sh

使用npm安裝gulp到全局:

npm install -g gulp

使用npm安裝gulp到當前項目的node_modules, 并更新package.json配置信息:

npm install --save-dev gulp

編寫gulpfile.js

最簡單的gulpfile.js結構:

var gulp = require('gulp');

gulp.task('task-name', function() {
    console.log('Hello, Gulp!'); 
});

在gulpfile.js所在路徑的終端輸入gulp task-name就可以看到Hello, Gulp!了,這個示例沒有實際作用,純粹是為了演示gulpfile.js的基本結構。

下面我們使用 gulp 實現一個實用功能:編譯 Sass,并添加瀏覽器前綴。首先,初始化一個演示目錄:

  • mkdir gulp-in-action,創建演示目錄gulp-in-action
  • cd gulp-in-action,進入演示目錄gulp-in-action
  • mkdir sass,創建 Sass 目錄sass
  • touch sass/demo.scss,創建 Sass 文件demo.scss用于演示
  • touch gulpfile.js,創建 gulp 的配置文件gulpfile.js
  • tree .,以樹狀圖的形式展示當前目錄結構

gulp入門+ES6

然后,安裝依賴gulp、gulp-sass和gulp-autoprefixer:

npm install --save-dev gulp gulp-sass gulp-autoprefixer

其中,gulp-sass用于將 Sass 文件編譯為 CSS 文件,gulp-autoprefixer用于為 CSS 屬性添加適當的瀏覽器前綴。此外,在正式的開發項目中,應該使用npm init或者自建方式創建一個package.json存儲依賴關系等配置信息,當然,如果想要獲得更優秀的腳手架,你可以嘗試一下yeoman(號稱現代前端開發的腳手架)。

接下來,使用熟悉的編輯器打開gulpfile.js,編寫 gulp 的自動化構建邏輯:

// 導入 gulp/gulp-sass/gulp-autoprefixer 三個模塊
var gulp = require('gulp');
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
// 使用 gulp.task() 方法注冊一個任務
// 第一個參數是任務名稱
// 第二個參數是任務的執行邏輯
gulp.task('styles', function() {
    return gulp.src('sass/demo.scss')
        .pipe(sass())
        .pipe(autoprefixer())
        .pipe(gulp.dest('css'));
});

在繼續下面的操作之前,我們有必要認識一下 gulp 中的五大函數:

  • gulp.task(name, fn),注冊一個 gulp 任務
  • gulp.run(...tasks),并行運行多個 gulp 任務
  • gulp.watch(glob, fn),實時監控內容,當glob內容變化時,執行fn
  • gulp.src(glob),glob是目標文件的路徑,返回一個可讀的 stream
  • gulp.dest(gloc),glob是輸出路徑,返回一個可寫的 stream

那么,什么是pipe()呢?先來看一個unix命令:

cat gulpfile.js | wc -l

這是一條由管道符(|)拼接起來的命令,整體由兩部分組成,每一部分都是一條獨立的命令:cat gulpfile.js用來獲取gulpfile.js的文件內容;wc -l用來統計文件中的行數。管道符(|)在這里的作用是拼接兩條命令,將前者(cat gulpfile.js)的輸出,作為后者的wc -l的輸入。

gulp 中使用的pipe()函數就是模擬了管道符的操作方式,比如下面的 gulp 命令:

gulp.src('sass/demo.scss')
    .pipe(sass())
    .pipe(autoprefixer())

就可以想象為:

'sass/demo.scss' | sass() | autoprefixer()

基礎知識介紹完了,最后我們來執行 gulp 任務,終端中輸入:

gulp styles

這里的styles就是gulpfile.js中注冊過的任務名稱。如果配置文件沒有錯誤地話,執行完成后項目結構如下:

gulp入門+ES6

編譯之前,sass/demo.scss的內容如下:

.container {
    display: flex;
}

編譯之后,打開css/demo.css文件,內容如下:

.container {
    display: -webkit-box;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex; 
}

可見,gulp styles已經自動完成了 Sass 到 CSS 的編譯,并添加了適當的瀏覽器前綴。

接下來,我們使用gulp.watch()函數優化一下自動化任務,讓 Sass 文件每次發生改動時可以自動編譯。gulp 官方插件開發說明中建議開發者遵循單一職責原則,所以,我們這里實現watch任務最好的方式就是借助styles任務的功能,增加下面的代碼到gulpfile.js配置文件中:

gulp.task('watch', function() {
    gulp.watch('sass/demo.scss', ['styles']);
});

然后在終端運行gulp watch命令,即可實時修改實時編譯了。到此,我們基本實現了既定的自動化目標,當然,只做這么點工作就太讓 gulp 屈才了,不過本文定位為入門文章,更多更深入的使用方式,建議學習慕課網 《Grunt-beginner前端自動化工具》 一課,內容全面深入淺出,值得一學。

gulp.watch()

gulp.watch()可以返回一個監聽對象,用來監聽額外的事件,比如change:

var watcher = gulp.watch('sass/*.scss');
watcher.on('change', function (event) {
    console.log('Event type: ' + event.type);
    console.log('Event path: ' + event.path);
});

其他事件:

  • nomatch,在glob沒有匹配到文件時觸發
  • ready,在匹配后即將進行自動化任務前觸發
  • error,自動化任務出錯時觸發
  • end,自動化任務完成時觸發

watcher對象可以調用的一些方法:

  • watcher.end(),中斷watcher
  • watcher.files(),返回監聽的文件列表
  • watch.add(glob[, fn]),添加文件到監聽的文件列表
  • watch.remove(fillpath),從監聽的文件列表中移除文件

node-glob

在上面的gulp.src(glob)和gulp.dest(glob)函數中,glob參數既可以是具體的路徑,也可以是一些路徑規則,通常來說,路徑規則比具體路徑更常用,也更靈活,最常見的符號就是通配符(*),比如sass/*.scss表示匹配sass文件夾下所有以.scss作為后綴的文件。

gulp 中使用 gulp-glob 來匹配文件,下面列出幾種最常見的匹配方式:

  • sass/demo.scss,精確匹配sass文件夾下的demo.scss文件
  • sass/*.scss,匹配sass文件夾下所有以.scss作為后綴的文件
  • sass/**/*.scss,匹配sass文件夾以及子文件夾下所有以.scss作為后綴的文件
  • !sass/demo.scss,!后面跟上述三種模式,可以充匹配結果中排除相關文件,比如這里的!sass/demo.scss表示從匹配結果中排除sass文件夾下的demo.scss文件
  • sass/*.+(sass|scss),匹配sass文件夾下所有以.scss和.sass作為后綴的文件

這些規則和正則表達式有相似之處,更多信息可以參考 minimatchnode-glob中文版 )的官方文檔。

常用插件

目前在 gulp 的官方 插件頁面 ,已經可以搜索到多達 1800+ 的插件,當你需要使用某種插件時,建議優先使用該頁面搜索一下是否有現成的插件可用,然后再考慮造輪子,避免重復工作。

下面列舉一些常用插件,善用這些插件才能讓 gulp 發揮出最大作用。

gulp-load-plugins

在我們的gulpfile.js中,每當需要使用新的插件時,就需要在頭部聲明并加載一次,如果依賴的插件較多,維護起來就會比較困難,gulp-load-plugins插件就是針對這一問題而存在的,安裝方式:

npm install --save-dev gulp-load-plugins

接下來,我們在gulpfile.js中使用gulp-load-plugins替代導入依賴的方式:

// var sass = require('gulp-sass');
// var autoprefixer = require('gulp-autoprefixer');
var $ = require('gulp-load-plugins')();
gulp.task('styles', function() {
    return gulp.src('sass/demo.scss')
        .pipe($.sass())
        .pipe($.autoprefixer())
        .pipe(gulp.dest('css'));
});

之后再有新的依賴加入開發環境,也無需增加頭部的聲明,調用即可使用。

使用gulp-load-plugins,必須保證項目依賴都寫在了package.json中,這是因為gulp-load-plugins的加載核心就是調用package.json的配置信息。 如果你不知道怎么創建一份package.json,那么我們可以做一個游戲,在終端輸入npm init試一試。

browsersync

browsersync是一款瀏覽器實時測試工具,它可以嵌入到多種自動化構建工具中,詳細的使用方式請參考 官方文檔 。安裝方式:

npm install --save-dev browser-sync

重寫gulp watch任務:

gulp.task('watch', function() {
    browserSync.init({
        server: {
            baseDir: "./"
        }
    });
    gulp.watch('sass/demo.scss', ['styles'])
        .on('change', browserSync.reload);
});

在項目根目錄下創建一個index.html用于演示項目:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="css/demo.css">
</head>
<body>
    <p>help</p>
</body>
</html>

為了更明顯的查看效果,我們修改demo/sass.scss的內容為:

body {
    background-color: red;
}

終端運行gulp watch即可自動打開瀏覽器,實時修改頁面的效果:

gulp入門+ES6

學習和使用插件最有效地方式就是去相關的文檔,然后投入到實際開發中……這里僅僅列出列出幾個插件,后續會隨著對 gulp 理解的深入繼續增加更多插件。

gulp + ES6

在最新的 gulp 3.9 版本上,開發者可以使用 ES6(ES2015) 語法 來編寫配置文件了。第一步,先檢查一下 CLI 和本地版本:

gulp -v
// => CLI version 3.9.0
// => Local version 3.9.0

第二步,在終端安裝依賴Babel:

npm install babel-core --save-dev

第三步,將gulpfile.js重名為gulpfile.babel.js:

mv "gulpfile.js" "gulpfile.babel.js"

下面展示一個使用 ES6 語法編寫的gulpfile.babel.js,其中有箭頭函數、模塊導入、常量聲明和模板字符串(更喜歡叫它插值字符串)等新語法:

import gulp from 'gulp';
import sass from 'gulp-sass';
import autoprefixer from 'gulp-autoprefixer';
const dirs = {
    src: 'scss',
    dest: 'css'
};
const sassPaths = {
    src: `${dirs.src}/demo.scss`,
    dest: `${dirs.dest}`
};
gulp.task('styles', () => {
    return gulp.src(paths.src)
        .pipe(sass.())
        .pipe(autoprefixer())
        .pipe(gulp.dest(paths.dest));
});

如果遵循上述步驟遇到了未知錯誤,可以嘗試安裝babel代替babel-core來解決:

npm install babel --save-dev

參考資料

gulp入門+ES6

南北

在校學生,本科計算機專業。狂熱地想當一名作家,為色彩和圖形營造的視覺張力折服,喜歡調教各類JS庫,鐘愛CSS,希望未來加入一個社交性質的公司,內心極度肯定“情感”在社交中的決定性地位,立志于此改變社交關系的快速迭代。 個人博客

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!