2015 年 12 月

第 30 卷,第 13 期

本文章是由機器翻譯。

Visual Studio-適用於 Web 開發的現代工具: Grunt 和 Gulp

Adam Tuliper | 2015 年 12 月

有許多工具可為現代的 Web 開發人員。經常會出現在現今的 Web 專案的兩個是 JavaScript 工作跑石 Grunt 以及 Gulp。使用 JavaScript 來執行工作看起來似乎是外部索引概念如果永遠不會完成,或如果您習慣單純的 Visual Studio Web 程式開發,但有很好的理由,使其能夠試用。JavaScript 工作跑石,瀏覽器之外的運作,並且通常會使用 Node.js 在命令列,讓您輕鬆地執行前端開發相關的工作,包括縮小,串連多個檔案,判斷指令碼相依性,並將 HTML 網頁的指令碼參考適當的順序,以便建立單元測試控管,處理像是 TypeScript 或 CoffeeScript,以及其他前端的建置指令碼。

哪一個 — Grunt 或 Gulp 嗎?

選擇工作執行器是大部分的個人或 project 喜好設定,除非您想要使用的外掛程式只支援特定的工作執行器。主要差異是 Grunt 受到 JSON 組態設定,而且每個 Grunt 工作通常必須建立中繼檔案傳遞項目,其他工作,而 Gulp 驅動的可執行的 JavaScript 程式碼 (亦即,不只是 JSON),並可以串流處理到下一個工作的結果,而不需要使用暫存檔案。Gulp 是較新的孩子區塊,而且此情況下,您會看到很多較新的專案使用它。儘管如此,Grunt 有許多已知的支援,例如 jQuery,使用它來建置...jQuery 者。同時 Grunt 以及 Gulp 工作透過外掛程式,也就是您安裝以處理特定工作的模組。外掛程式的廣大生態系統,而且通常您會發現支援 Grunt 以及 Gulp,因此,一次,通常使用其中一個工作套件歸納為個人的選擇。

安裝和使用 Grunt

安裝程式適用於 Grunt 以及 Gulp 是簡短我年 10 月的文章中涵蓋的節點封裝管理員 (npm),(msdn.com/magazine/mt573714)。若要安裝 Grunt 命令實際上有兩個部分。第一個是 Grunt 命令列介面的單次安裝。第二個安裝 Grunt 至您的專案資料夾。這兩個部分安裝可讓您使用多個版本的 Grunt 上您的系統,並使用 Grunt 命令列介面,從任何路徑:

#only do this once to globally install the grunt command line runner
npm install –g grunt-cli
#run within your project folder one time to create package.json
#this file will track your installed npm dependencies
#like grunt and the grunt plug-ins, similar to bower.json (see the last article)
npm init
#install grunt as a dev dependency into your project (again see last article)
#we will still need a gruntfile.js though to configure grunt
npm install grunt –save-dev

Grunt 組態

Grunt 組態檔中所示,是只包裝函式,其中包含組態、 正在載入外掛程式和工作定義的 JavaScript 檔案 圖 1

圖 1 Grunt 組態檔

module.exports = function (grunt) {
  // Where does uglify come from? Installing it via:
  // npm install grunt-contrib-uglify --save-dev
  grunt.initConfig({
    uglify: {
      my_target: {
        files: {
          'dest/output.min.js': '*.js'
        }
      }
    }
  });
  // Warning: make sure you load your tasks from the
  // packages you've installed!
  grunt.loadNpmTasks('grunt-contrib-uglify');
  // When running Grunt at cmd line with no params,
  // you need a default task registered, so use uglify
  grunt.registerTask('default', ['uglify']);
  // You can include custom code right inside your own task,
  // as well as use the above plug-ins
  grunt.registerTask('customtask', function () {
    console.log("\r\nRunning a custom task");
  });
};

您可以在執行工作 圖 1 在命令列,只要呼叫:

#no params means choose the 'default' task (which happens to be uglify)
grunt
#or you can specify a particular task by name
grunt customtask

完成後,您會發現 uglified (縮製),以及串連在 wwwroot/輸出-min.js 的結果。如果您使用過 ASP.NET 縮小和統合,您會看到這個程序也不同,這不繫結至執行您的應用程式或甚至是編譯時,還有其他許多選項,您可以選擇的工作,例如 uglifying。我個人覺得更簡單且容易了解這個工作流程。

您可以鏈結在一起 Grunt 相依於另一個工作。這些工作會執行同步執行,使得其中一個必須先完成才能繼續進行下一步]。

#Specify uglify must run first and then concat. Because grunt works off
#temp files, many tasks will need to wait until a prior one is done
grunt.registerTask('default', ['uglify', 'concat']);

安裝和使用 Gulp

安裝 Gulp 如下安裝 Grunt。我會進入更多詳細資料,含大,但請注意,您可以執行類似的項目使用。我只是不想要太重複。Gulp 同時具有全域安裝,因此使用從任何路徑上您的系統,以及本機安裝到專案資料夾中的特定專案的版本號碼。全域安裝的 Gulp 會遞交控制項為安裝在本機專案中,如果找到了,因此尊重您的專案版本 Gulp:

#Only do this once to globally install gulp
npm install –g gulp
#Run within your project folder one time to create package.json
#this file will track your installed npm dependencies
#like gulp and the gulp plug-ins
npm init
#Install gulp as a dev dependency into your project
#we will still need a gulpfile.js to configure gulp
npm install gulp --save-dev

Gulp 組態和 API

明顯不同於 Grunt gulp 設定。Gulpfile.js 組態檔中,通常會在所顯示的結構 圖 2, 包含 「 必須 」 載入的外掛程式,然後定義工作。請注意,我不使用 JSON 組態設定。相反地,工作是程式碼驅動的。

圖 2 Gulp 組態檔

// All the 'requires' to load your
// various plug-ins and gulp itself
var gulp = require('gulp');
var concat = require('gulp-concat');
// A custom task, run via: gulp customtask
gulp.task('customtask', function(){
  // Some custom task
});
// Define a default task, run simply via: gulp
gulp.task('default', function () {
  gulp.src('./lib/scripts/*.js')
    .pipe(concat('all-scripts.js'))
    .pipe(gulp.dest('./wwwroot/scripts'));
});

Gulp 透過數個索引鍵的 Api 和概念的運作方式: 來源、 目的地、 管道、 工作和 globs。Gulp.src API 會告訴 Gulp 開啟要使用的檔案及這些檔案通常然後傳送至其他函式,而不是所建立的暫存檔案。這是從 Grunt 主要的差別。下列範例會顯示沒有管道將結果,我將在稍後介紹 gulp.src 一些基本範例。這個 API 呼叫中,會採用所謂 glob 做為參數。Glob 基本上是模式,您可以輸入 (像是規則運算式) 若要指定一個或多個檔案的路徑 (有更多有關在 globs github.com/isaacs/node-glob):

#Tell gulp about some files to work with
gulp.src('./input1.js');
#This will represent every html file in the wwwroot folder
gulp.src('./wwwroot/*.html')
#You can specify multiple expressions
gulp.src(['./app/**/*.js', './app/*.css']

目的地 (目的地) API,您可以想像得到,指定目的地,也會採用 glob。由於 globs 定義路徑更具彈性,您可以輸出個別的檔案或輸出的資料夾:

#Tell dest you'll be using a file as your output
gulp.dest ('./myfile.js');
#Or maybe you'll write out results to a folder
gulp.dest ('./wwwroot');

Gulp 中的工作是您撰寫以執行某些動作的指令碼。工作的格式是很簡單,但工作可以使用數種方式。最簡單的方式是將預設的工作和一個或多個其他工作:

gulp.task('customtask', function(){
  // Some custom task to ex. read files, add headers, concat
});
gulp.task('default', function () {
  // Some default task that runs when you call gulp with no params
});

工作可以平行執行,或可以是彼此相依。如果您不在意順序,您可以只將他們鏈結在一起,如下:

gulp.task('default', ['concatjs', 'compileLess'], function(){});

這個範例會定義預設的工作,只會執行不同的工作來串連 JavaScript 檔案和編譯較少的檔案 (假設程式碼在名為以下的工作)。如果要求一項工作完成,其他執行之前,您需要讓取決於另一項工作,然後再執行多個工作。下列程式碼中,預設的工作等候 concat 完成第一次,接著等待 uglify 完成的:

gulp.task('default', ['concat']);
gulp.task('concat', ['uglify'], function(){
  // Concat
});
gulp.task('uglify', function(){
  // Uglify
});

管道 API 用來透過管道傳送到另一個使用 Node.js 資料流 API 某個函數的結果。工作流程通常是: 讀取的 src,管道一項工作,將結果輸出至目的地。這個完整 gulpfile.js 範例會讀取所有 JavaScript 檔案中 /scripts,將它們串連為單一檔案,並將輸出寫入另一個資料夾:

// Define plug-ins – must first run: npm install gulp-concat --save-dev
var gulp = require('gulp');
var concat = require('gulp-concat');
gulp.task('default', function () {
  #Get all .js files in /scripts, pipe to concatenate, and write to folder
  gulp.src('./lib/scripts/*.js')
    .pipe(concat('all-scripts.js'))
    .pipe(gulp.dest('./wwwroot/scripts'));
}

以下是一個實用、 真實世界範例。通常您會想要串連的檔案及/或將資訊的標頭加入至您的原始程式碼檔。您可以輕鬆地達成幾個步驟將幾個檔案加入至您網站的根目錄 (您可以這麼全都放在程式碼,以及工作,請參閱 gulp 標頭文件)。首先,建立名為 copyright.txt,其中包含要加入,像這樣的標頭檔:

/*
MyWebSite Version <%= version %>
https://twitter.com/adamtuliper
Copyright 2015, licensing, etc
*/

接下來,建立名為 version.txt 包含目前的版本號碼 (還有外掛程式,grunt 碰撞,以遞增版本號碼,以及 gulp 碰撞等) 的檔案:

1.0.0

現在,您的專案根目錄中,安裝 gulp 標頭和 gulp concat 外掛程式:

npm install gulp-concat gulp-header --save-dev

或者,您可以手動將它們加入至 package.json 檔案,並讓 Visual Studio 執行您的封裝還原。

最後,您只需要告訴 Gulp gulpfile.js 應該做什麼,如所示 圖 3。如果您不想要將所有的指令碼串連在一起,而是將標頭加入至每個檔案,您可以只是一行註解 pipe(concat)。很簡單,對吧?

圖 3 Gulpfile.js

var gulp = require('gulp');
var fs = require('fs');
var concat = require("gulp-concat");
var header = require("gulp-header");
// Read *.js, concat to one file, write headers, output to /processed
gulp.task('concat-header', function () {
  var appVersion = fs.readFileSync('version.txt');
  var copyright =fs.readFileSync('copyright.txt');
  gulp.src('./scripts/*.js')
  .pipe(concat('all-scripts.js'))
  .pipe(header(copyright, {version: appVersion}))
  .pipe(gulp.dest('./scripts/processed'));
});

然後,您只需執行的工作透過下列命令而,瞧,您了串連所有.js 檔案,將自訂標頭加入輸出會寫入至./scripts/processed 資料夾:

gulp concat-header

工作執行器總管

Visual Studio 提供支援 Gulp 和 Grunt 透過工作執行器總管] 中,也就是包含在 Visual Studio 2015 和 Visual Studio 擴充功能可用。您可以在檢視中找到 |其他視窗 |工作執行器總管。工作執行器總管是很棒,因為它會偵測到有 gulpfile.js 或 gruntfile.js 專案中,剖析工作,並提供可執行,找到的工作中所示的 UI 圖 4。此外,您可以定義在您的專案,我稍後接下來因為 ASP.NET 5 及其預設範本中使用這項功能的預先定義的動作發生時執行的工作。只要以滑鼠右鍵按一下工作執行或繫結至特定的動作,例如,在開啟的專案上執行的工作。

顯示兩者的工作執行器總管 Grunt 以及 Gulp 工作選項
圖 4 顯示兩者的工作執行器總管 Grunt 以及 Gulp 工作選項

做為 圖 5 顯示 Grunt 提供選項,當您反白顯示,不會看到與 Gulp,特別是 Grunt 工作 (若要忽略警告) 的強制和詳細資訊的選項 (F 和左上方 V)。這些是直接傳遞至 Grunt 命令列參數。工作執行器總管最棒的一點是它會顯示您的命令就會傳遞至 Grunt 以及 Gulp 命令列 (在 [工作輸出] 視窗),因此沒有任何的神秘面紗,並在幕後運作。

其他 Grunt 選項和命令列
圖 5 其他 Grunt 選項和命令列

Gulp 和 ASP.NET 5

包含 Visual Studio 2015 中的 ASP.NET 5 範本使用 Gulp,它們將安裝 Gulp 到您的專案 node_components 資料夾,使其所有可讓您在專案中使用。您仍然可以使用 Grunt 在 ASP.NET 5 專案中,當然。變得務必將它安裝到您的專案,透過 npm,或將它新增至 packages.json devDependencies 內並讓自動封裝還原功能,Visual Studio 中的執行。我想要強調: 透過命令列或 Visual Studio 內部執行所有這些您較偏好。

撰寫本文時,目前的 ASP.NET 5 範本會包含幾個工作來縮小和串連.css 和.js 檔案。在舊版的 ASP.NET 中,這些工作中的處理已編譯程式碼在執行階段,這在理想情況下並不是位置及時間應該執行這類的工作。如您所見的 圖 6, 、 名為初始狀態的工作和最小呼叫其 css 及 js 方法縮小這些檔案,或清除先前縮製的檔案。

ASP.NET 5 Preview 範本中的方塊外工作
圖 6 的全新的工作,在 ASP.NET 5 Preview 範本

Gruntfile.js 下行顯示同時執行多個工作的另一個範例:

gulp.task("clean", ["clean:js", "clean:css"]);

您可以選擇將 Grunt 以及 Gulp 工作繫結至 Visual Studio 中的四個不同的動作。使用 MSBuild,減小定義建置前和建置後命令列來執行各種工作。與工作執行器總管] 中,您可以定義之前建立,之後建置、 清除及專案開啟事件,以執行這些工作。只要執行將註解加入至 gulpfile.js 或 gruntfile.js 檔案不會影響執行,但查詢工作執行器總管。若要查看 ASP.NET 5 gulpfile.js 中的 「 清除 」 繫結,看看這行在檔案頂端:

// <binding Clean='clean' />

這只需要連結至事件。

總結

Grunt 以及 Gulp 是絕佳的新增至您 Web 的利器。這兩也支援,而且有大量的生態系統的隨插即用增益集功能。每個 Web 專案可以受益,它們可以提供內容。如需詳細資訊,請務必,請參閱下列:


Adam Tuliper是活在陽光普照 SoCal Microsoft 的資深技術推廣者。他是 Web 開發人員、 遊戲開發人員、 Pluralsight 作者和全能技術的熱愛。找到他的 Twitter: @AdamTuliper 或在他的 Adam 車庫部落格上 bit.ly/1NSAYxK

感謝以下的微軟技術專家對本文的審閱: Michael palermo 主講