ASP.NET5之客戶端開發:Grunt和Gulp構建工具在Visual Studio 2015中的高效的應用

Grunt和Gulp是Javascript世界裏的用來作自動壓縮、Typescript編譯、代碼質量lint工具、css預處理器的構建工具,它幫助開發者處理客戶端開發中的一些煩操重複性的工做。Grunt和Gulp都在Visual studio 2015中獲得支持。ASP.NET 項目模板默認使用Gulp。css

Grunt和Gulp

Grunt和Gulp有什麼區別?Gulp雖然是稍微晚一點登場的,可是它因crisp performance和優雅的語法受到歡迎。與Grunt不一樣,Grunt每每在硬盤上是讀寫文件,Gulp使用流式的API去鏈式的調用方法,Grunt是早些出現的客戶端構建工具,Grunt預約義了大多數常常要作的壓縮和單元測試等工做。Grunt天天都有數以千計的下載和應用。html

使用Grunt

這個實例使用Empty ASP.NET項目模板來展現自動化的客戶端構建工做。非空的ASP.NET項目模板默認使用Gulp。node

最終示例清理目標部署目錄,合併Javascript文件,檢查代碼質量,壓縮Javascript文件內容而且部署到web項目的跟目錄,咱們將使用如下包:web

grunt:任務執行者包;npm

grunt-contrib-clean:一個用來移除文件和目錄的任務json

grunt-contrib-jshint:一個審查代碼質量的任務gulp

grunt-contrib-concat:一個鏈接多文件在一個文件中的任務數組

grunt-contrib-uglify:一個壓縮和縮小文件尺寸的任務asp.net

grunt-contrib-watch:一個檢測文件活動的任務編輯器

準備項目

首先,建立信的空的Web應用程序添加示例的Typescript文件,Typescript文件在Visual Studio 2015的默認設置下,會自動地編譯爲Javascript中而且做爲Grunt的源文件。

  1. 在Vistual Studio 2015中,建立新的ASP.NET應用程序。
  2. 在「新ASP.NET項目」對話框中,選擇ASP.NET Empty模板而且單擊OK按鈕。
  3. 在解決方案管理器中,能夠看到項目的目錄結構,Src文件夾包含一個空的wwwroot和dependencies節點QQ截圖20150529214148
  4. 在項目中添加一個名爲Typescript的文件夾
  5. 在添加任何文件以前,確認Visual Studio 2015打開了「保存時編譯」的項目(在「工具->選項->文本編輯器->Typescript=>項目」節點下)
    QQ截圖20150529214720
  6. 右擊Typescript目錄,點擊」添加->新項目」選擇Javascript項目命名爲Tastes.ts(注意ts後綴),拷貝下列代碼
    enum Tastes { Sweet, Sour, Salty, Bitter }
  7. 在Typescript目錄中添加第二個文件命名爲Food.ts,拷貝如下代碼
    class Food {
        constructor(name: string, calories: number) {
            this._name = name;
            this._calories = calories;
        }
    
        private _name: string;
        get Name() {
            return this._name;
        }
    
        private _calories: number;
        get Calories() {
            return this._calories;
        }
    
        private _taste: Tastes;
        get Taste(): Tastes { return this._taste }
        set Taste(value: Tastes) {
            this._taste = value;
        }
    }

配置NPM

下一步,配置npm來下來grunt和grunt-tasks

  1. 在解決方案目錄中,右擊並選擇「添加->新項目」選擇npm configuration file,保留默認的文件名,點擊肯定按鈕
  2. 在package.json文件中,在devDependencies屬性下,輸入grunt,使用只能提示選擇grunt並回車,添加冒號,並使用智能提示選擇版本號
    QQ截圖20150529220540
  3. 添加咱們須要的更多的依賴項目
    QQ截圖20150529220818
  4. 保存文件

這些包將會被自動下載,你能夠在node-modules目錄下看到下載的內容,前提是你打開了」顯示全部文件「

QQ截圖20150529221043

若是須要的話,你要能夠經過右鍵單擊dependences下的NPM,選擇Restore Packages按鈕恢復這些包

配置Grunt

Grunt使用名爲gruntfile.js的文件清單進行配置、加載和註冊任務,讓它能夠手動的運行或者基數Vistual Studio的事件機制自動運行

  1. 右鍵單擊項目文件,選擇」添加->新項目「,選擇」Grunt configuration file」選項,保留默認的文件名,並點擊添加按鈕
    初始的文件包含了grunt.initConfig()方法,這個方法就是咱們用來設置選項的地方
    module.exports = function (grunt) {
        grunt.initConfig({
        });
    };
  2. 在上文的方法中,添加clean任務,這個配置能夠添加一個數組來定義要清理的目錄或者文件
    module.exports = function (grunt) {
        grunt.initConfig({
            clean: ["wwwroot/lib/*", "temp/"],
        });
    };
  3. 在initConfig方法下方,咱們須要調用grunt.loadNpmTasks方法來讓任務在Visual Studio中運行
    grunt.loadNpmTasks("grunt-contrib-clean");
  4. 保存這個文件,文件內容以下所示
    module.exports = function (grunt) {
        grunt.initConfig({
            clean: ["wwwroot/lib/*", "temp/"],
        });
        grunt.loadNpmTasks("grunt-contrib-clean");
    };
  5. 右鍵點擊gruntfile.js,選擇」Task Runner Explorer」
  6. 驗證clean任務已經出如今「任務」節點下
    QQ截圖20150529222302
  7. 右鍵點擊clean任務,選擇Run,一個命令行窗體顯示,並執行定義的任務
    QQ截圖20150529222425
  8. 在initConfig方法中,添加concat任務
    Src屬性定義了要連接的文件列表,dest屬性定義了合併完成的目標文件,而all屬性定義了在任何構建環境下,任務都將執行
    module.exports = function (grunt) {
        grunt.initConfig({
            clean: ["wwwroot/lib/*", "temp/"],
            concat: {
                all: {
                    src: ['TypeScript/Tastes.js', 'TypeScript/Food.js'],
                    dest: 'temp/combined.js'
                }
            },
        });
        grunt.loadNpmTasks("grunt-contrib-clean");
    };
  9. 添加jihit任務
    jihit代碼質量工具將會在temp目錄下全部的js文件中運行
    jshint: {
                files: ['temp/*.js'],
                options: {
                    '-W069': false,
                }
            }
  10. 添加uglify任務
    src定義了混淆的源文件列表,dest定義了目標文件
    uglify: {
            all: {
                    src: ['temp/combined.js'],
                    dest: 'wwwroot/lib/combined.min.js'
            }
    },
  11. 最後,調用grunt.loadNpmTasks()讓上文定義的全部任務在Visual Studio中執行
  12. 保存文件,最終文件內容以下所示
    module.exports = function (grunt) {
        grunt.initConfig({
            clean: ["wwwroot/lib/*", "temp/"],
            concat: {
                all: {
                    src: ['TypeScript/Tastes.js', 'TypeScript/Food.js'],
                    dest: 'temp/combined.js'
                }
            },
            jshint: {
                files: ['temp/*.js'],
                options: {
                    '-W069': false,
                }
            },
            uglify: {
                all: {
                    src: ['temp/combined.js'],
                    dest: 'wwwroot/lib/combined.min.js'
                }
            },
        });
        grunt.loadNpmTasks("grunt-contrib-clean");
        grunt.loadNpmTasks('grunt-contrib-jshint');
        grunt.loadNpmTasks('grunt-contrib-concat');
        grunt.loadNpmTasks('grunt-contrib-uglify');
    };
  13. 你會發現,上文定義的任務已經都出如今了Task Runner Explorer中
    QQ截圖20150529223715
    依次執行這些任務,
    QQ截圖20150529224009

集成起來

使用grunt.registerTask方法來註冊運行一系列指定順序的任務,好比,運行上文中任務的順序應該爲clean->concat->jshint->uglify。在文件中添加如下代碼,而且保持方法調用和loadNpmTasks調用時同級的

grunt.registerTask("all", ['clean', 'concat', 'jshint', 'uglify']);


如今你能夠在Task Runner Explorer中找到一個名爲all的別名任務,運行它便可順序執行上文中的全部任務了 
QQ截圖20150529224509

監測文件變化

Watch任務能夠監視文件和目錄的變化,而且在監測到變化後觸發一系列任務,在initConfig方法中添加如下的代碼來監視Typescript目錄下的全部js文件的變化,並執行’all「任務

watch: {
            files: ["TypeScript/*.js"],
            tasks: ["all"]
        }

添加一個loadNpmTask方法調用讓任務顯示在Task Runner Explorer中

grunt.loadNpmTasks('grunt-contrib-watch');

運行Watch任務,命令行窗體將處在等待狀態,此時它監視着文件的變化,打開一個Typescript文件,添加任何內容,你就會發現它已經在工做了
QQ截圖20150530075609

與Visual Studio事件一塊兒協做

你除了能夠手動運行這些任務以外,你還能夠把這些任務和Visual Studio事件綁定,當Visual Studio觸發既定的事件後,自動運行定義的任務
在Task Runner Explorer中,右鍵點擊watch任務,選擇「Bindings->Project Open」,此時,當你打開項目的時候,watch任務將自動執行而且觀測文件變化並執行上文中定義的一系列任務
QQ截圖20150530080110

使用Gulp

除了一些著名的不一樣之外,Gulp的配置文件和grunt的很是類似,下文中的例子對比grunt的示例可是使用gulp包和約定。

NPM 包的不一樣

與grunt同樣,gulp定義也在ackage.json文件的devDependencies屬性中,內容以下文所示,你也能夠經過只能提示來更新到最近的版本號。

{
  "version": "1.0.0",
  "name": "GruntFromEmptyWebApp",
  "private": true,
  "devDependencies": {
    "gulp": "3.8.11",
    "gulp-clean": "0.3.1",
    "gulp-jshint": "1.11.0",
    "gulp-concat": "2.5.2",
    "gulp-uglify":"1.2.0",
    "gulp-rename": "1.2.2",
    "gulp-watch": "4.2.4"
  }
}

Gulpfile和Gruntfile示例的不一樣

取代gruntfile.js,添加一個命名爲gulpfile.js的文件,在這個文件中,使用node.js的方法require()爲下文中的幾個變量賦值

var gulp = require('gulp');
var clean = require('gulp-clean');
var concat = require('gulp-concat');
var jshint = require('gulp-jshint');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var watch = require('gulp-watch');

在賦值語句下方,調用gulp的task方法,第一個參數是任務的名字的字符串表示方式,第二個參數是一個回調方法

gulp.task('default', function () {
    // place code for your default task here
});

此時在Task Runner Explorer中已經存在一個命名爲default的任務,雖然它是空的

QQ截圖20150530082113

在task方法的回調函數內部,使用方纔定義的gulp執行咱們須要的工做,首先定義一個clean任務

gulp.src('wwwroot/lib/*').pipe(clean());

Gulp流

gulp是一個包含src、pipe和dest方法的流式對象

  • src()方法用來定義流從哪裏來
  • pipe()方法定義怎麼重寫流
  • dest()方法定義流的輸出

代碼一般的模式以下文所示

gulp.src()
        .pipe()
        .pipe()
        .pipe(dest());

src方法拿到初始的原始流文件,在一系列的pipe調用後執行對流的操做,最後經過dest()方法輸出最終的結果,這種方式的優點是隻有一個輸入和一個輸出,讓任務執行的更快。

集成

下文是咱們組織的一系列任務,將它定義爲ALL,執行的任務和上文中grunt的例子是徹底同樣的

gulp.task("all", function () {
    gulp.src('wwwroot/lib/*').pipe(clean());
    gulp.src(['TypeScript/Tastes.js', 'TypeScript/Food.js'])
           .pipe(concat("combined.js"))
           .pipe(jshint())
           .pipe(uglify())
           .pipe(rename({
               extname: '.min.js'
           }))
           .pipe(gulp.dest('wwwroot/lib'))
});

watch任務也和grunt的示例很是類似

gulp.task("watch", function () {
    gulp.watch("TypeScript/*.js", ['all']);
});

使用一樣的方式,在Task Runner Explorer中綁定Visual Studio事件,就可讓watch任務在項目打開時自動執行了。

乙烷

原文連接:http://docs.asp.net/en/latest/client-side/grunt-gulp.html

相關文章
相關標籤/搜索