در این چند سال اخیردر پروژه های وب  روند توسعه  در بخش FrontEnd خیلی سریع و پیچده شده است. این روند دیگر شامل نوشتن چند فایل css یا js نیست که همراه پروژه آپلود شوند. این روند شامل کامپایل کردن فایل Sass و Less به css، اجرای JSHint و JSLint روی اسکریپتها، Bundle و Minify کردن فایلهای css و js و غیره. برای اجرا خودکار این کارها نیاز به یک ابزار FrontEnd Build  هست. در .NET ابزاری به نام MSBuild وجود دارد که بخشی از .NET Framework دارد که پروسه کامپایل کردن کد، پکیج کردن، تست و استقرار (Deployment) رو در بخش BackEnd بر عهده دارد. پروسه اجرای کارها در بخش FrontEnd Build را میتوان بر عهده MSBuild گذاست اما مایکروسافت این کار را انجام نداده است. مایکروسافت به جای تغییر MSBuild و استفاده از آن برای انجام کارهای FrontEnd Build از اکوسیستمی که از قبل وجود داشته و به خوبی این کار را انجام میدهد، در Visual Studio 2015 استفاده کرده است.

Gulp ابزاری است  برای انجام کارهای FronEnd  که در Visual Studio 2015 تعبیه شده است. اما Gulp چیست ؟

Gulp یک FrontEnd Build سیستم است که از آن میتوان برای انجام خودکار کارهای معمول در توسعه وب استفاده کرد. Gulp بر روی nodejs ساخته شده است. خود Gulp و فایلی که شامل کارهایی است که Gulp باید انجام دهد به وسیله JavaScript نوشته شده است. Gulp چهار دستور اصلی دارد: task, src, dest و watch.

  • task:  برای ایجاد یک تابع استفاده میشود که این تابع را میتوان بصورت مستقیم اجرا کرد یا به عنوان وابستگی در داخل یک تابع دیگر آنرا صدا زد.
  • src: برای باز کردن و برگرداندن محتویات فایل  به عنوان یک stream.
  • dest: برای مشخص کردن مسیر ذخیره سازی یک stream به عنوان فایل.
  • watch: برای مونیتور کردن تغییرات در یک فایل یا گروهی از فایلها و اجرای یک یا چند task هنگامی که تغییری رخ دهد.

Gulp به خودی خود کار زیادی انجام نمیدهد ولی دارای مجموعه زیادی از پلاگینها است که کارهای اصلی را پلاگینها انجام میدهند.

خوب برای شروع Visual Studio 2015 را باز کنید یک پروژه ایجاد نمایید. در پنچره New Project از منوی Template بر روی C# سپس Web کلیک کنید سپس در سمت راست ASP.NET Web Application را انتخاب و بر روی دکمه OK کلیک کنید:

visual studio new web project

پس از باز شدن پنجره دیگر از ASP.NET 5 Preview Template بر روی وب سایت کلیک کنید دو باره دکمه OK را کلیک کنید و صبر کنید تا پروژه ایجاد شود.

asp.net 5 site template

پس از ایجاد پروژه فایل gulpfile.js را باز کنید. این فایل جایی است که taskها را تعریف میکنید. بدنه این فایل به شکل زیر است:

/// <binding Clean='clean' />

var gulp = require("gulp"),
    uglify = require('gulp-uglify'),
    jshint = require('gulp-jshint'),
    rimraf = require("rimraf"),
    fs = require("fs");

eval("var project = " + fs.readFileSync("./project.json"));

var paths = {
    bower: "./bower_components/",
    lib: "./" + project.webroot + "/lib/"
};

gulp.task("clean", function (cb) {
    rimraf(paths.lib, cb);
});

gulp.task("copy", ["clean"], function () {
    var bower = {
        "bootstrap": "bootstrap/dist/**/*.{js,map,css,ttf,svg,woff,eot}",
        "bootstrap-touch-carousel": "bootstrap-touch-carousel/dist/**/*.{js,css}",
        "hammer.js": "hammer.js/hammer*.{js,map}",
        "jquery": "jquery/jquery*.{js,map}",
        "jquery-validation": "jquery-validation/jquery.validate.js",
        "jquery-validation-unobtrusive": "jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"
    }

    for (var destinationDir in bower) {
        gulp.src(paths.bower + bower[destinationDir])
          .pipe(gulp.dest(paths.lib + destinationDir));
    }
});

قبل از توضیح این کدهای که بصورت پیشفرض در فایل وجود دارد، در ابتدا اولین task را Gulp تعریف و اجرا کنیم. به انتهای فایل کدهای زیر اضافه و سپس ذخیر نماید.

gulp.task('greet', function () {
    console.log('Hello world!');
});

حالا بر روی فایل gulpfile.js راست کلیک کنید و از منو باز شده روی Task Runner Explorer کلیک کنید.

پس از باز شدن ویندوز Task Runner Explorer در سمت چپ آن لیست taskها را مشاهده میکنید که در انتهای لیست greet را که اضافه کرده ایم، مشاهده میکنید.

task runner explorer

روی greet راست کلیک کنید و از منو باز باز شده بر روی Run کلیک کنید تا اجرا شود پس از اجرا پیام ‌Hello World! را مشاهده میکنید.

gulp hello task

با استفاده از task  کاری را با نام greet تعریف کرده ایم که نتیجه اجرای آن چاپ یک پیغام در خروجی است. بعد از تعریف اولین task نگاهی به کدهای از قبل نوشته داخل فایل gulpfile.js می اندازیم. در ابتدای فایل وابستگی هایی که برای اجرای taskها نیاز است، تعریف شده اند.

var gulp = require("gulp"),
    rimraf = require("rimraf"),
    fs = require("fs");

سپس ‌محتویات فایل project.json خوانده میشود.

eval("var project = " + fs.readFileSync("./project.json"));

سپس دو مسیر به پوشه های bower_components و wwwroot\lib تعریف شده است. کلیه پکیجهای css و js که از طریق Bower نصب میشوند در داخل پوشه bower_components قرار میگیرند و در داخل پوشه wwwroot\lib  فایلهای css و jsای که در پروژه استفاه وبهمراه آن انتشار (publish) میابند، قرار میگیرد.

var paths = {
    bower: "./bower_components/",
    lib: "./" + project.webroot + "/lib/"
};

سپس دو task با نامهای clean و copy تعریف شده اند که در انتها آنها را بیشتر مورد بررسی قرار میدهم. به سراغ نوشتن task بعدی میرویم. در این task میخواهیم JSHint را بر روی یک اسکریپت اجرا کنیم. فایل package.json را باز کنید در devDependencies پکیج JSHint را اضافه میکنیم. ابتدا نام پیکج سپس ورژن پکیج را وارد میکینم. پس ازتایپ کردن نام پکیج Intellisence ویژوال استودیو لیستی از ورژنهای اخیر پکیج را بر اساس <major>.<minor>.<patch> نشان میدهد.

visual studio load gulp package version

  • اولین آیتم در لیست آخرین ورژن پایدار پکیج است.
  • دومین آیتم که با علامت  شروع شده است پکیج منطبق بر ورژن اخیر major را برمیگرداند. 
  • دومین آیتم که با علامت  شروع شده است پکیج منطبق بر ورژن اخیر minor را برمیگرداند. 

پس از اضافه کردن پکیچ فایل package.json را ذخیره نمایید سپس از Solution Explorer بر Dependencies کلیک و آنرا باز کنید و بر روی NPM راست کلیک کنید و از منو باز شده Restore Packages را کلیک کنید و منتظر بمانید تا nodejs پکیج JSHint را دانلود کند.

visua studio restore packages via npm

فایل gulpfile.js را باز کنید و در ابتدای فایل، وابستگی به پلاگین jshint را تعریف کنید:

var gulp = require("gulp"),
    jshint = require('gulp-jshint'),
    rimraf = require("rimraf"),
    fs = require("fs");

سپس task زیر بنویسید:

gulp.task('hint', function () {
    gulp.src(paths.bower + 'hammer.js/hammer.min.js')
        .pipe(jshint())
        .pipe(jshint.reporter('default'));
});

در این task ابتدا با تابع src  فایل hammer.min.js در مسیر  bower_components\hammer.js\hammer.min.js را باز شده و سپس محتویات فایل به صورت یک stream به تابع jshit() ارسال و تابع روی آن اجرا و با استفاده از jshint.reporter('default') خروجی را در کنسول Task Runner Explorer چاپ شده است.run jshint task

task دیگری را اضافه میکنیم. فایل package.json را باز کنید و همانند مرحله قبل پکیچ gulp-uglify را اضافه کنید سپس روی NPM دوباره Restore Packages را بزنید تا پکیچ اضافه شود. وابستگی به پلاگین uglify را تعریف کنید:

uglify = require('gulp-uglify'),

  کد task جدید با نام minify را اضافه کنید:

gulp.task('minify', function () {
    gulp.src(paths.bower + 'hammer.js/hammer.min.js')
        .pipe(uglify())
        .pipe(gulp.dest(paths.bower + "hammer.js/"));
});

سپس task را اجرا کنید و پس از اجرای آن اگر فایل hammer.js را نگاه کنید میبیند که فایل فشرده شده است.

در انتها به دو کار clean و copy اشاره کنم. clean را وقتی اجرا کنید پوشه lib در مسیر src\WebApplication1\wwwroot را پاک میکند. copy  به کار clean وابستگی دارد. قبل از اجرای کار copy  اول کار clean اجرا میشود سپس copy اجرا میشود.