前端構建工具Gulp.js知多少(webpack/gulp/grunt)

@TOCjavascript

寫在前面

前幾天在更新webpack知識的時候,想起來三年前用過的前端構建工具gulp/grunt,遂寫個筆記總結一下,出來混老是要還的,忘得七七八八了...css

閱讀本文章以前,相信你已經對前端構建工具(webpack、gulp、grunt)有必定的認知和了解了,那麼他們之間究竟有什麼區別呢?html

什麼是gulp?

gulp文檔上面有這麼一句話\color{blue} {用自動化構建工具加強你的工做流程!} ,也就是說 gulp是一個自動化構建工具; gulp的一些功能以下(包括但不限於): 前端

自動化構建工具gulp

gulp或grunt和webpack的區別

其實Webpack和另外兩個並無太多的可比性vue

  • Gulp/Grunt是一種可以優化前端的開發流程的工具,而WebPack是一種模塊化的解決方案,不過Webpack的優勢使得Webpack在不少場景下能夠替代Gulp/Grunt類的工具。java

  • Grunt和Gulp的工做方式是:在一個配置文件中,指明對某些文件進行相似編譯,組合,壓縮等任務的具體步驟,工具以後能夠自動替你完成這些任務。 node

    Grunt和Gulp的工做流程

  • Webpack的工做方式是:把你的項目當作一個總體,經過一個給定的主文件(如:index.js),Webpack將從這個文件開始找到你的項目的全部依賴文件,使用loaders處理它們,最後打包爲一個(或多個)瀏覽器可識別的JavaScript文件。 webpack

    Webpack的工做方式
    上述內容轉自@zhangwang的入門Webpack,看這篇就夠了

gulp起步

傻瓜式起步照搬官網文檔 1.安裝nginx

// 全局安裝
$ npm install -g gulp
或者
$ npm install --global gulp

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

2.在項目根目錄下建立一個名爲 gulpfile.js 的文件:git

var gulp = require('gulp');

gulp.task('default', function() {
  // 將你的默認的任務代碼放在這
});
複製代碼

3.運行 gulp:

$ gulp
複製代碼

默認的名爲 default 的任務(task)將會被運行,在這裏,這個任務並未作任何事情。 具體詳情能夠查看gulpjs.com文檔

項目搭建

新建一個項目gulp-test 環境:

$ node -v // v9.1.0
$ npm -v // 6.5.0
複製代碼

1.新建文件如下文件以下

gulp-test/
          css/
               index.scss
           js/
               helloworld.js
           index.html
           gulpfile.js
複製代碼

其中 gulpfile.js 是咱們gulp的配置文件,啓動gulp默認會找個這個文件並執行; 2.接下來安裝依賴

$ npm init
複製代碼

一直按回車Enter初始化package.json文件(小技巧: npm iniy -y 能夠免去繁瑣的enter步驟) 此時咱們的目錄結構是這樣了

gulp-test/
          css/
               index.scss
           js/
               helloworld.js
           index.html
           gulpfile.js
           package.json
複製代碼

安裝依賴

npm i --save-dev gulp        // gulp自動化構建工具
npm i --save-dev gulp-uglify //js壓縮
npm i --save-dev gulp-concat //文件合併
npm i --save-dev gulp-jshint //js語法檢測
npm i --save-dev gulp-rename //文件重命名
npm i --save-dev gulp-sass //sass編譯工具
npm i --save-dev gulp-minify-css //css壓縮
npm i --save-dev del       //文件刪除
// 如下三選一
npm i --save-dev gulp-connect       // 自動刷新頁面
npm i --save-dev  browser-sync       // 自動刷新頁面
npm i --save-dev gulp-livereload       // 自動刷新頁面
複製代碼

這裏頁面實時刷新只講這個gulp-connect ,其餘詳情能夠參照Browsersync和文章gulp-livereload

安裝完依賴後配置gulpfile.js以下:

// 定義依賴項和插件
const gulp=require('gulp');
const  uglify=require('gulp-uglify'); //js壓縮
const  concat=require('gulp-concat'); //文件合併
const jshint = require('gulp-jshint'); //js語法檢測
const rename = require('gulp-rename'); // 重命名
const sass = require('gulp-sass'); // 編譯scss
const  minifycss = require('gulp-minify-css'); // 壓縮css
// const livereload = require('gulp-livereload'); // 自動刷新頁面
const  del = require('del'); //文件刪除
const connect = require('gulp-connect'); // 自動刷新頁面

gulp.task('server', function() {
  connect.server({
    port: 8080, //指定端口號,在瀏覽器中輸入localhost:8080就能夠直接訪問生成的html頁面
    root: './', //指定html文件起始的根目錄
    livereload: true //啓動實時刷新功能(配合上邊的connect.reload()方法同步使用)
  });
});

// 定義名爲 "my-task" 的任務壓縮js
gulp.task('my-task-js', function(){
  gulp.src('./js/*.js')
    .pipe(jshint())
    .pipe(uglify())
    .pipe(concat('all.js'))
    .pipe(rename({suffix: '.min'}))
    .pipe(gulp.dest('./dist/js'))
    .pipe(connect.reload())
});


// 定義名爲 "my-task-css" 的任務編譯scss壓縮css
gulp.task('my-task-css', function() {
  gulp.src('./css/*.scss')
    .pipe(sass().on('error', sass.logError))
    .pipe(concat('all.css'))
    .pipe(rename({suffix: '.min'}))
    .pipe(minifycss())
    .pipe(connect.reload())
    .pipe(gulp.dest('./dist/css'))

});

gulp.task('html', function(){
  gulp.src('*.html')
    .pipe(gulp.dest('dist/html'))
    .pipe(connect.reload())
})
//執行壓縮前,先刪除之前壓縮的文件
gulp.task('clean', function() {
  return del(['./dist/css/all.css', './dist/css/all.min.css', './dist/all.js','./dist/all.min.js', './dist/html'])
});
// 定義默認任務

gulp.task('default',['clean'],function() {
  gulp.start('my-task-js', 'my-task-css', 'watch', 'server' );
});
// 任務監聽
gulp.task('watch', function() {
  // Watch.js files
  gulp.watch('./js/*.js', ['my-task-js']);
  // Watch .scss files
  gulp.watch('./css/*.scss', ['my-task-css']);
  // Watch .html files
  gulp.watch('./*.html', ['html']);
  // Watch any files in dist/, reload on change
  // gulp.watch(['dist/!**']).on('change', livereload.changed);
});

複製代碼

大概講解一下gulpfile.js:

// ...
// 定義名爲 "my-task" 的任務壓縮js
gulp.task('my-task-js', function(){
  gulp.src('./js/*.js')
    .pipe(jshint()) //js檢測
    .pipe(uglify()) //js壓縮
    .pipe(concat('all.js')) //合併爲all.js
    .pipe(rename({suffix: '.min'})) // 重命名爲all.mim.js
    .pipe(gulp.dest('./dist/js')) //輸出到/dist/js目錄
    .pipe(connect.reload()) // 更新頁面
});
// ...
複製代碼

gulp.task是gulp的api 定義一個使用 Orchestrator 實現的任務(task) 如上咱們定義了my-task-jsmy-task-csshtmlcleandefaultwatchserver等任務,其中:

  • my-task-js 是將 符合所提供的匹配模式的js 進行檢測(gulp-jshint)、壓縮(gulp-uglify)、合併(gulp-concat)、重命名(gulp-rename)、輸出(gulp.dest)到/dist/js目錄下;

  • my-task-css 是將 符合所提供的匹配模式的sass進行編譯(gulp-sass)、壓縮(gulp-uglify)、合併(gulp-concat)、重命名(gulp-rename)、輸出(gulp.dest)到/dist/css目錄下;

  • html 是將 符合所提供的匹配模式的html進行監聽,若是有變化則connect.reload()

  • clean 是若是任務從新啓動時 刪除舊文件;

  • default gulp默認啓動的任務

  • watch gulp的api 監視文件,而且能夠在文件發生改動時候作一些事情。它總會返回一個 EventEmitter 來發射(emit) change 事件。

  • server 依賴gulp-connect啓動一個服務器

gulp.task('server', function() {
  connect.server({
    port: 8080, //指定端口號,在瀏覽器中輸入localhost:8080就能夠直接訪問生成的html頁面
    root: './', //指定html文件起始的根目錄
    livereload: true //啓動實時刷新功能(配合上邊的connect.reload()方法同步使用)
  });
});
複製代碼

配置完gulpfile.js以後,咱們給js和css及html加點東西:

首先js/helloworld.js

// helloworld.js
console.log('hello world')
複製代碼

css/index.scss

// index.scss

// 變量測試
$fontColor:  #red;
$backColor: aqua;
// 嵌套類測試
div {
  p {
    font-weight: bold;
    font-size: 20px;
    color: $fontColor;
  }
}

div{
  background: $backColor;
}
複製代碼

index.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>gulp-study</title>
	<link href=/dist/css/all.min.css rel=stylesheet>
</head>
<body>
	<div id="firstDiv">
		<p>我是gulp</p>
		<p>hello world</p>
	</div>
<p>我是p標籤</p>
<p>我是p標籤</p>
</body>
<script src="/dist/js/all.min.js"></script>
</html>

複製代碼

運行gulp

$ gulp 
複製代碼

運行輸出


瀏覽器效果:

效果

接下來咱們修改helloworld.js來看看是否能實時刷新 修改以下:

// helloworld.js
console.log('hello world');

let firstDiv =  document.getElementById('firstDiv')

console.log(firstDiv)

複製代碼

按保存以後,終端給咱們報了一個錯:

Unhandled 'error' event

查看js發現咱們用了es6語法的聲明語句\color{red}{let} 但當前gulp沒法處理es6語法,有問題解決問題,es6=>es5

解決方案: 安裝gulp-babel babel-core babel-preset-es2015

npm i  --save-dev  gulp-babel babel-core babel-preset-es2015
複製代碼

gulpfile.js修改以下:

// ...
const babel = require('gulp-babel');
// ...
// 定義名爲 "my-task" 的任務壓縮js
gulp.task('my-task-js', function(){
  gulp.src('./js/*.js')
    .pipe(babel())
    .pipe(jshint())
    .pipe(uglify())
    .pipe(concat('all.js'))
    .pipe(rename({suffix: '.min'}))
    .pipe(gulp.dest('./dist/js'))
    .pipe(connect.reload())
});
// ...

複製代碼

運行

$ gulp
複製代碼

依然報上面的錯;找了一些緣由發現,雖然安裝了相關依賴,卻沒有配置.babelrc文件,即babel還沒轉化es6

根目錄添加.babelrc文件

{
	"presets": ["es2015"]
}

複製代碼

從新運行:

$ gulp
複製代碼

結果以下

查看dist下的js文件

let已經轉化成var

改變helloworld.js檢查頁面是否刷新

// helloworld.js
console.log('hello world');

let firstDiv =  document.getElementById('firstDiv')

console.log(firstDiv)
firstDiv.style.backgroundColor = 'yellow';

複製代碼

保存,頁面的天空藍換成大家喜歡的yellow顏色

頁面的天空藍換成大家喜歡的yellow顏色

修改index.scss 查看是否會刷新頁面

// index.scss

// 變量測試
$fontColor:  #red;
$backColor: aqua;
// 嵌套類測試
div {
  p {
    font-weight: bold;
    font-size: 20px;
    color: $fontColor;
  }
}

div{
  background: $backColor;
  width: 400px;
  height: 400px;
  margin: 0 auto;
}


複製代碼

頁面更新正常

最後修改index.html 查看是否會刷新頁面

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>gulp-study</title>
	<link href=/dist/css/all.min.css rel=stylesheet>
</head>
<body>
	<div id="firstDiv">
		<p>我是gulp</p>
		<p>hello world</p>
	</div>
<div>
	<p>我是真的皮</p>
</div>
</body>
<script src="/dist/js/all.min.js"></script>
</html>

複製代碼

輸出完美

這次項目源碼請轉@王一諾gulp-study

文章最後

今天主要學習了gulp的簡單項目搭建及實時更新配置;其實gulp相似於grunt的弱化版,但更簡單好用,只是插件會少一些,目前主流的項目搭建工具主要是webpack,但依然有很多項目還用着gulp或者grunt

擴展:

webpack中文網

gulpjs中文網

gruntjs中文網

下面還有一些樓主的學習筆記:

@webpack4+加vue2+從零開始搭設vue項目

@nginx部署/代理/跨域

有興趣的能夠多多交流@樓主博客

相關文章
相關標籤/搜索