مطالب
شیوه کدنویسی در الکترون
در قسمت قبلی، انبوهی از کدهای جاوااسکرپیتی را دیدیم که در کنار یکدیگر نوشته شده بودند و این حجم کد، در یک برنامه‌ی واقعی‌تر افزایش پیدا می‌کند و بهتر است الگوی‌های کدنویسی آن را بهتر بشناسیم، تا کمتر به مشکل برخورد کنیم.

برای شناسایی ایرادات در کد و بهبود کیفیت کدها می‌توانید از ابزارهای دسته‌ی lint استفاده کنید که تعدادی از معروفترین این ابزارها (jslint ,cpplint ,eslint ,nodelint و ...) هستند.
برای نصب چنین ابزاری مثل lint می‌توانید به شکل زیر آن را نصب کنید:
npm install -g eslint
فلگ g در بالا به معنای global بوده و باعث می‌شود که eslint نصب شده، بر روی همه پروژه‌های node.js اجرا شود.
برای اولین بار نیاز است که آماده سازی ابتدایی برای این کتابخانه صورت بگیرد که با دستور زیر قابل انجام است:
eslint --init
سپس تعدادی سوال شخصی از شما پرسیده می‌شود که باید پاسخ داده شود که نمونه‌ای از آن‌را در زیر می‌بینید:
? How would you like to configure ESLint? Answer questions about your style
? Are you using ECMAScript 6 features? Yes
? Are you using ES6 modules? Yes
? Where will your code run? Browser, Node
? Do you use CommonJS? No
? Do you use JSX? No
? What style of indentation do you use? Spaces
? What quotes do you use for strings? Double
? What line endings do you use? Windows
? Do you require semicolons? Yes
? What format do you want your config file to be in? JSON
Successfully created .eslintrc.json file in D:\ali\electron
از این پس با دستور زیر، قادرید کیفیت کدهای خود را بهبود بخشید
eslint .
یا
eslint index.js

می‌توانید این دستور را در در خصوصیت test، در بخش اسکریپت، به شکل زیر وارد کنید:
{
  "name": "electron",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "electron .",
    "test":"eslint ."
  },
  "author": "",
  "license": "ISC"
}
تا از این پس با دستور زیر قابل اجرا باشد:
npm test
بعد از اجرای دستور و طبق سوالات پاسخ داده شده، بهبود کیفیت کد به شکل زیر پاسخ داده می‌شود:
D:\ali\electron\index.js
   1:26  error  Strings must use doublequote                            quotes
  16:8   error  Strings must use doublequote                            quotes
  19:3   error  Expected indentation of 4 space characters but found 2  indent
  22:3   error  Expected indentation of 4 space characters but found 2  indent

✖ 4 problems (4 errors, 0 warnings)

برای نامگذاری فایل‌های js، به جای استفاده از _ از - استفاده کنید. این قاعده‌ای است که گیت هاب در نامگذاری فایل‌های js انجام می‌دهد. یعنی به جای عبارت dotnet_tips.js از عبارت dotnet-tips.js استفاده کنید. خاطرتان جمع باشد که هیچ فایل جاوااسکرپیتی رسمی در الکترون، خارج از این قاعده نامگذاری نشده است.
سعی کنید از جدیدترین قواعد موجود در ES6 استفاده کنید مانند:
let برای تعریف متغیرها
const برای تعریف ثابت ها
توابع جهتی به جای نوشتن عبارت function
استفاده از template string‌ها به جای چسباندن رشته‌ها از طریق عملگر +

برای نامگذاری متغیرها از همان قوانین تعریف شده برای node.js استفاده کنید که شامل موارد زیر است:
- موقعی که یک ماژول را به عنوان یک کلاس استفاده می‌کنید از متد CamelCase استفاده کنید مثل BrowserWindow
- موقعی که از یک ماژول که حاوی مجموعه‌ای از دستورات و api‌ها است استفاده می‌کنید، از قانون mixedCase استفاده کنید مثل app یا globalShortcut
- موقعی که یک api به عنوان خصوصیت یک شیء مورد استفاده قرار میگیرد، از mixedCase استفاده کنید؛ به عنوان مثال win.webContents یا fs.readFileSync
- برای مابقی اشیا مثل دستورات process و یا تگ webview که به شکل متفاوت‌تری مورد استفاده قرار می‌گیرند، از همان عنوان‌های خودشان استفاده می‌کنیم.

موقعی که api جدیدی را می‌سازید و قصد تعریف متدی را دارید بهتر است دو متد برای get و set تعریف شود، نسبت به حالتی که در کتابخانه جی کوئری مورد استفاده قرار می‌گیرد یعنی عبارت‌های زیر
setText('test');
getText();
نسبت به عبارت
.text([text]);
ترجیح داده می‌شوند.
نظرات مطالب
استفاده از Froala WYSIWYG Editor در ASP.NET
از راهنمایی شما بسیار متشکرم. دو مورد برای من پیش اومد؛ یکی اینکه با استفاده از راهنمایی‌های شما دکمه کد اضافه شد، اما اول اینکه زمانی روی آن کلیک میکنم هیچ اتفاقی نمیافته. با دو browser چک کردم و هیچ تغییری نکرد. مطلب دوم: در local  آیکن‌ها نمایش داده می‌شوند اما روی هاست آیکن‌ها نمایش داده نمی‌شوند. در ابتدا از bundle استفاده می‌کردم اما با اینکه لینک مستقیم فایل‌ها را هم گذاشتم باز همان مشکل را داشتم. البته فایل اصلی jquery را هم به ابتدای صفحه انتقال دادم، اما باز هم تغییری نکرد.
اشتراک‌ها
کتابخانه ی تاریخ شمسی در جاوا اسکریپت PersianDate

کتابخانه‌ی تاریخ شمسی برای پروژه‌های وب و مورد استفاده در جاوا اسکریپت به NuGet اضافه شد

این کتابخانه کامل‌ترین کتابخانه‌ی تاریخ شمسی در جاوا اسکریپت می‌باشد که از تاریخ 1/1/1 تا 30/12/9377 را پشتیبانی می‌کند

جهت نصب این دستور را در Package Manager Console تایپ کنید

Install-Package anyresolver.persiandate

 
کتابخانه ی تاریخ شمسی در جاوا اسکریپت PersianDate
مطالب
شروع به کار با Ember.js
Ember.js کتابخانه‌ای است جهت ساده سازی تولید برنامه‌های تک صفحه‌ای وب. برنامه‌هایی که شبیه به برنامه‌های دسکتاپ در مرورگر کاربر عمل می‌کنند. دو برنامه نویس اصلی آن Yehuda Katz که عضو اصلی تیم‌های jQuery و Ruby on Rails است و Tom Dale که ابتدا SproutCore را به وجود آورد و بعدها به Ember.js تغییر نام یافت، هستند.

منابع اصلی Ember.js

پیش از شروع به بحث نیاز است با تعدادی از سایت‌های اصلی مرتبط با Ember.js آشنا شد:
سایت اصلی: http://emberjs.com
مخزن کدهای آن: https://github.com/emberjs
انجمن اختصاصی پرسش و پاسخ: http://discuss.emberjs.com
موتور قالب‌های آن: http://handlebarsjs.com
لیست منابع مطالعاتی مرتبط مانند ویدیوهای آموزشی و لیست مقالات موجود: http://emberwatch.com
و بسته‌ی نیوگت آن: https://www.nuget.org/packages/EmberJS



مفاهیم پایه‌ای Ember.js

شیء Application
 App = Ember.Application.create();
یک برنامه‌ی Ember.js با تعریف وهله‌ای از شیء Application آن آغاز می‌شود. با اینکار به صورت خودکار رویدادگردان‌هایی به صفحه اضافه می‌شوند. کامپوننت‌های پیش فرض آن ایجاد شده و همچنین قالب اصلی برنامه رندر می‌شود.

مسیر یابی
با مرور قسمت‌های مختلف برنامه توسط کاربر، نیاز است حالات برنامه را مدیریت کرد؛ اینجا است که کار قسمت مسیریابی شروع می‌شود. مسیریابی، منابع مورد نیاز جهت آدرس‌های مشخصی را تامین می‌کند.
App.Router.map(function() {
    this.resource('accounts'); // takes us to /accounts
    this.resource('gallery'); // takes us to /gallery
});
در اینجا نحوه‌ی تعریف آغازین مسیریابی Ember.js را مشاهده می‌کنید که توسط متد resource آن مسیرهای قابل ارائه توسط برنامه مشخص می‌شوند.
به این ترتیب مسیرهای accounts/ و gallery/ قابل پردازش خواهند شد.

این مسیرها، تو در تو نیز می‌توانند باشند. برای مثال:
App.Router.map(function() {
    this.resource('news', function() {
        this.resource('images', function () { // takes us to /news/images
            this.route('add');// takes us to /news/images/add
        });
    });
});
به این ترتیب نحوه‌ی تعریف مسیریابی آدرس news/images/add را مشاهده می‌کنید. همچنین در این مثال از دو متد resource و route استفاده شده‌است. از متد resource برای حالت تعریف اسامی استفاده کنید و از متد route برای تعریف افعال و تغییر دهنده‌ها. برای نمونه در اینجا فعل افزودن تصاویر با متد route مشخص شده‌است.


مدل‌ها
مدل‌ها همان اشیایی هستند که برنامه مورد استفاده قرار می‌دهد و می‌توانند یک آرایه‌ی ساده و یا اشیاء JSON دریافتی از وب سرور باشند.
حداقل به دو روش می‌توان مدل‌ها را تعریف کرد:
الف) با استفاده از افزونه‌ی Ember Data
ب) با کمک شیء Ember.Object
App.SiteLink = Ember.Object.extend({});
App.SiteLink.reopenClass({
    findAll: function() {
        var links = [];
        //… $.getJSON …

        return links;
    }
});
ابتدا یک زیرکلاس از Ember.Object به کمک متد extend ایجاد خواهد شد. سپس از متد توکار reopenClass برای توسعه‌ی API کمک خواهیم گرفت.
در ادامه متد دلخواهی را ایجاد کرده و برای مثال آرایه‌ای از اشیاء دلخواه جاوا اسکریپتی را بازگشت خواهیم داد.
پس از تعریف مدل، نیاز است آن‌را به سیستم مسیریابی معرفی کرد:
App.GalleryRoute = Ember.Route.extend({
    model: function() {
        return App.SiteLink.findAll();
    }
});
به این ترتیب زمانیکه کاربر به آدرس gallery/ مراجعه می‌کند، دسترسی به model وجود خواهد داشت. در اینجا model یک واژه‌ی کلیدی است.


کنترلرها
کنترلرها جهت ارائه‌ی اطلاعات مدل‌ها به View و قالب برنامه تعریف می‌شوند. در اینجا همیشه باید بخاطر داشت که model تامین کننده‌ی اطلاعات است. کنترلر جهت در معرض دید قرار دادن این اطلاعات، به View برنامه کاربرد دارد و مدل‌ها هیچ اطلاعی از وجود کنترلرها ندارند.
کنترلرها علاوه بر اطلاعات model، می‌توانند حاوی یک سری خواص و اشیاء صرفا نمایشی که قرار نیست در بانک اطلاعاتی ذخیره شوند نیز باشند.
در Ember.js قالب‌ها (templates) اطلاعات خود را از کنترلر دریافت می‌کنند. کنترلرها اطلاعات مدل را به همراه سایر خواص نمایشی مورد نیاز در اختیار View و قالب‌های برنامه قرار می‌دهند.


برای تعریف یک کنترلر می‌توان درون شیء مسیریابی، با تعریف متد setupController شروع کرد:
App.GalleryRoute = Ember.Route.extend({
    setupController: function(controller) {
        controller.set('content', ['red', 'yellow', 'blue']);
    }
});
در این مثال یک خاصیت دلخواه به نام content تعریف و سپس آرایه‌ای به آن انتساب داده شده‌است.

روش دوم تعریف کنترلرها با ایجاد یک زیر کلاس از شیء Ember.Controller انجام می‌شود:
App.GalleryController = Ember.Controller.extend({
    search: '',
    content: ['red', 'yellow', 'blue'],
    query: function() {
        var data = this.get('search');
        this.transitionToRoute('search', { query: data });
    }
});


قالب‌ها یا templates
قالب‌ها قسمت‌های اصلی رابط کاربری را تشکیل خواهند داد. در اینجا از کتابخانه‌ای به نام handlebars برای تهیه قالب‌های سمت کاربر کمک گرفته می‌شود.
<script type="text/x-handlebars" data-template-name="sayhello">
    Hello,
    <strong>{{firstName}} {{lastName}}</strong>!
</script>
این قالب‌ها توسط تگ اسکریپت تعریف شده و نوع آن‌ها text/x-handlebars مشخص می‌شود. به این ترتیب Ember.js، این قسمت از صفحه را یافته و عبارات داخل {{}} را با مقادیر دریافتی از کنترلر جایگزین می‌کند.
<script type="text/x-handlebars" data-template-name="sayhello">
    Hello,
    <strong>{{firstName}} {{lastName}}</strong>!
 
    {{#if person}}
    Welcome back,
    <strong>{{person.firstName}} {{person.lastName}}</strong>!
    {{/if}}
 
    <ul>
        {{#each friend in friends}}
        <li>
            {{friend.name}}
        </li>
        {{/each}}
    </ul>
 
    <img {{bindAttr src="link.url" }} />
    {{#linkTo ''about}}About{{/linkTo}}
</script>
در این مثال نحوه‌ی تعریف عبارات شرطی و یا یک حلقه را نیز مشاهده می‌کنید. همچنین امکان اتصال به ویژگی‌هایی مانند src یک تصویر و یا ایجاد لینک‌ها را نیز دارا است.
بهترین مرجع آشنایی با ریز جزئیات کتابخانه‌ی handlebars، مراجعه به سایت اصلی آن است.


قواعد پیش فرض نامگذاری در Ember.js
اگر به مثال‌های فوق دقت کرده باشید، خواصی مانند GalleryController و یا GalleryRoute به شیء App اضافه شده‌اند. این نوع نامگذاری‌ها در ember.js بر اساس روش convention over configuration کار می‌کنند. برای نمونه اگر مسیریابی خاصی را به نحو ذیل تعریف کردید:
 this.resource('employees');
شیء مسیریابی آن App.EmployeesRoute
کنترلر آن App.EmployeesController
مدل آن App.Employee
View آن App.EmployeesView
و قالب آن employees
بهتر است تعریف شوند. به عبارتی اگر اینگونه تعریف شوند، به صورت خودکار توسط Ember.js یافت شده و هر کدام با مسئولیت‌های خاص مرتبط با آن‌ها پردازش می‌شوند و همچنین ارتباطات بین آن‌ها به صورت خودکار برقرار خواهد شد. به این ترتیب برنامه نظم بهتری خواهد یافت. با یک نگاه می‌توان قسمت‌های مختلف را تشخیص داد و همچنین کدنویسی پردازش و اتصال قسمت‌های مختلف برنامه نیز به شدت کاهش می‌یابد.


تهیه‌ی اولین برنامه‌ی Ember.js
تا اینجا نگاهی مقدماتی داشتیم به اجزای تشکیل دهنده‌ی هسته‌ی Ember.js. در ادامه مثال ساده‌ای را جهت نمایش ساختار ابتدایی یک برنامه‌ی Ember.js، بررسی خواهیم کرد.
بسته‌ی Ember.js را همانطور که در قسمت منابع اصلی آن در ابتدای بحث عنوان شد، می‌توانید از سایت و یا مخزن کد آن دریافت کنید و یا اگر از VS.NET استفاده می‌کنید، تنها کافی است دستور ذیل را صادر نمائید:
 PM> Install-Package EmberJS
پس از اضافه شدن فایل‌های js آن به پوشه‌ی Scripts برنامه، در همان پوشه‌، فایل جدید Scripts\app.js را نیز اضافه کنید. از آن برای افزودن تعاریف کدهای Ember.js استفاده خواهیم کرد.
در این حالت ترتیب تعریف اسکریپت‌های مورد نیاز صفحه به صورت ذیل خواهند بود:
<script src="Scripts/jquery-2.1.1.js" type="text/javascript"></script>
<script src="Scripts/handlebars.js" type="text/javascript"></script>
<script src="Scripts/ember.js" type="text/javascript"></script>
<script src="Scripts/app.js" type="text/javascript"></script>
کدهای ابتدایی فایل app.js جهت وهله سازی شیء Application و سپس تعریف مسیریابی صفحه‌ی index بر اساس روش convention over configuration به همراه تعریف یک کنترلر و افزودن متغیری به نام content به آن که با یک آرایه مقدار دهی شده‌است:
App = Ember.Application.create();
App.IndexRoute = Ember.Route.extend({
    setupController:function(controller) {
        controller.set('content', ['red', 'yellow', 'blue']);
    }
});
باید دقت داشت که تعریف مقدماتی Ember.Application.create به همراه یک سری تنظیمات پیش فرض نیز هست. برای مثال مسیریابی index به صورت خودکار به نحو ذیل توسط آن تعریف خواهد شد و نیازی به تعریف مجدد آن نیست:
App.Router.map(function() {
    this.resource('application'); 
    this.resource('index');
});
سپس برای اتصال این کنترلر به یک template خواهیم داشت:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script src="Scripts/jquery-2.1.1.js" type="text/javascript"></script>
    <script src="Scripts/handlebars.js" type="text/javascript"></script>
    <script src="Scripts/ember.js" type="text/javascript"></script>
    <script src="Scripts/app.js" type="text/javascript"></script>
</head>
<body>
    <script type="text/x-handlebars" data-template-name="index">
        Hello,
        <strong>Welcome to Ember.js</strong>!
        <ul>
            {{#each item in content}}
            <li>
                {{item}}
            </li>
            {{/each}}
        </ul>
    </script>
</body>
</html>
توسط اسکریپتی از نوع text/x-handlebars، اطلاعات آرایه content دریافت و در طی یک حلقه در صفحه نمایش داده خواهد شد.
مقدار data-template-name در اینجا مهم است. اگر آن‌را به هر نام دیگری بجز index تنظیم کنید، منبع دریافت اطلاعات آن مشخص نخواهد بود. نام index در اینجا به معنای اتصال این قالب به اطلاعات ارائه شده توسط کنترلر index است.

تا همینجا اگر برنامه را اجرا کنید، به خوبی کار خواهد کرد. نکته‌ی دیگری که در مورد قالب‌های Ember.js قابل توجه هستند، قالب پیش فرض application است. با تعریف Ember.Application.create یک چنین قالبی نیز به ابتدای هر صفحه به صورت خودکار اضافه خواهد شد:
<body>
    <script type="text/x-handlebars" data-template-name="application">
        <h1>Header</h1>
        {{outlet}}
    </script>
outlet واژه‌‌ای است کلیدی که سبب رندر سایر قالب‌های تعریف شده در صفحه می‌گردد. مقدار data-template-name آن نیز به application تنظیم شده‌است (اگر این مقدار ذکر نگردد نیز به صورت خودکار از application استفاده می‌شود). برای مثال اگر بخواهید به تمام قالب‌های رندر شده در صفحات مختلف، مقدار ثابتی را اضافه کنید (مانند هدر یا منو)، می‌توان قالب application را به صورت دستی به نحو فوق اضافه کرد و آن‌را سفارشی سازی نمود.



کدهای کامل این قسمت را از اینجا می‌توانید دریافت کنید:
EmberJS01.zip
مطالب
شروع کار با webpack - قسمت دوم
در مطلب قبلی بیشتر از لحاظ تئوریک با وب‌پک آشنا شدیم و در آخر نیز یک تک اسکریپت را با استفاده از آن باندل کرده و در صفحه‌ی index.html اضافه کردیم.

توجه :
در مطلب قبلی برای استفاده و نصب وبپک دو راه پیشنهاد شد؛ یکی نصب وبپک به صورت سراسری و دیگری به صورت محلی در محیط کاری فعلی پروژه. استفاده‌ی نگارنده به صورت محلی می‌باشد و برای فراخوانی وبپک از دستور npm run webpack استفاده خواهد شد. در صورتی که از وبپک به صورت سراسری (گلوبال ) استفاده می‌کنید، به جای این دستور فقط کافی است در خط فرمان دستور webpack را نوشته و آن را اجرا کنید.

اضافه کردن فایل تنظیمات وبپک

وبپک دارای تنظیمات و حالت‌های مختلفی برای تولید خروجی نهایی می‌باشد که می‌توان این تنظیمات را به صورت پارامترهای ورودی، در هنگام فراخوانی برای آن مشخص کرد. ولی برای ساده کردن و همچنین عدم الزام به تکرار برای تنظیمات مورد نیاز می‌توانیم یک فایل پیکربندی را ایجاد کنیم و موارد مورد نیاز را در آن تعریف کرده و تنها با فراخوانی نام webpack در خط فرمان، به صورت خودکار این تنظیمات خوانده شده و دستورات ما اجرا شوند. TaskRunner‌های گالپ و گرانت نیز دارای یک فایل پیکربندی، برای مشخص کردن تنظیمات مورد نیاز کاربر می‌باشند.

ساخت فایل پیکربندی وبپک

در محیط کاری پروژه یک فایل جدید را با نام webpack.config.js ایجاد می‌کنیم، تا پیکر بندی مورد نظرمان را برای وبپک در آن مشخص کنیم (نام این فایل قراردادی است و امکان مشخص کردن فایلی با نام دیگر نیز وجود دارد که در آینده با آن برخورد خواهیم کرد).
این فایل به صورت یک ماژول در فرمت commonjs می‌باشد (در صورتی که با ماژول‌های مختلف آشنا نیستید، مطالعه‌ی این مقاله پیشنهاد می‌شود ماژول‌ها در es6).
پس از ایجاد فایل پیکربندی در محیط کاری پروژه، محتوای زیر را به آن اضافه خواهیم کرد. این حالت را می‌توان ساده‌ترین پیکربندی وبپک دانست و با دستور webpack ./main.js bundle.js که در پایان مطلب قبلی در خط فرمان اجرا کردیم، تفاوتی ندارد.
// webpack.config.js file
module.exports = {
    entry:'./main.js'
    ,output:{
        filename:'bundle.js'
    }
}
پروپرتی entry مشخص کننده‌ی فایل ورودی است که قصد پردازش آن را داریم و پروپرتی output نیز خود یک آبجکت می‌باشد که در ساده‌ترین حالت، احتیاج به تعریف یک پروپرتی با نام filename را در آن داریم که مشخص کننده‌ی نام فایل باندل شونده توسط وبپک می‌باشد.
حال با اجرای دستور npm run webpack، وبپک به صورت خودکار محتوای فایل پیکربندی را خوانده و تنظیمات تعریف شده را در فایل باندل نهایی ترتیب اثر می‌دهد.

حالت نظاره گر یا watch mode

اضافه کردن فایل پیکربندی می‌تواند مفید باشد و ما را از الزام به تکرار برای مشخص کردن پارامترهای مورد نیاز در هر بار اجرای وبپک بی‌نیاز می‌کند. ولی فرض کنید در حال توسعه‌ی پروژه‌ای هستید و مدام در حال تغییر فایل‌های پروژه می‌باشید. فایلی اضافه، حذف و یا دچار تغییر می‌شود و برای هر بار انجام شدن پروسه‌ی باندلینگ باید وبپک را فراخوانی کنیم. برای جلوگیری از این پروسه‌ی تکراری، وبپک دارای حالت نظاره‌گر یا watch mode می‌باشد. معنای این حالت این است که وبپک تغییرات محیط کاری شما را در نظر می‌گیرد و با انجام هر تغییری، دوباره باندل مربوطه را از نو می‌سازد.
برای وارد شدن به این حالت یک راه کار این می‌باشد که در هنگام فراخوانی وبپک در خط فرمان، پرچم زیر را به آن اضافه کنیم:
//for when webpack is installed globally 
webpack --watch
//for when webpack is installed locally in project 
npm run webpack -- --watch
(در فراخوانی بالا دو حالت نصب سراسری و محلی وبپک در نظر گرفته شده‌است. حالت اول نکته‌ای را ندارد. ولی در حالت دوم برای اینکه پارامترهای خط فرمان توسط npm به دست وبپک برسد، احتیاج به اضافه کردن -- می‌باشد. جهت عدم آشنایی با این مورد می‌توانید به اینجا مراجعه کنید: فرستادن پارامتر به اسکریپت‌های npm)
راه کار دوم جهت تنظیم کردن وبپک در حالت نظاره گر، اضافه کردن پروپرتی watch به فایل پیکربندی وبپک است. پس از انجام این تغییر، محتوای فایل پیکربندی به این صورت خواهد بود:
//webpack.config.js file
module.exports = {
    entry:'./main.js'
    ,output:{
        filename:'bundle.js'
    }
    ,watch :true
}
اینبار برای ورود وپ بک به حالت نظاره‌گر کافی است وبپک را یک بار از طریق خط فرمان با دستور npm run webpack، فراخوانی کنیم.
در صورتی که مشکلی وجود نداشته باشد، با اجرای این دستور، کنترل خط فرمان به شما برنخواهد گشت و وبپک در حالت اجرا باقی می‌ماند که در تصویر زیر قابل مشاهده‌است.

حال اگر در اسکریپت main.js تغییری ایجاد کنید، خواهید دید که وبپک به صورت خودکار باندل را از اول خواهد ساخت.

وب سرور وبپک

تا اینجا از وبپک به عنوان یک باندل کننده بهره برده‌ایم و جهت میزبانی فایل‌های پروژه از فایل سیستم و سیستم عامل بهره بردیم. ولی می‌دانیم که در حین توسعه دادن برنامه‌های وب، استفاده از فایل سیستم و سیستم عامل مفید نیست و دچار مشکلات عدیده‌ای هم از سمت مرورگرها و هم از سمت کتابخانه‌های معروف جاوا اسکریپتی خواهیم شد( مانند مباحث cors و ...). جهت حذف این مشکلات می‌توانیم وب سرور مورد علاقه‌ی خود را اجرا کنیم یا از وب سرور فراهم شده توسط وبپک بهره ببریم.
جهت نصب وب سرور وبپک دستور زیر را در خط فرمان  اجرا خواهیم کرد ( به صورت سراسری یا محلی به انتخاب شما خواهد بود و قبلا توضیح داده شده است).
// to install globally :
npm install -g webpack-dev-server

//to install locally in project :
npm install -D webpack-dev-server
در حالتی که وبپک به صورت سراسری نصب شده باشد، با اجرای دستور webpack-dev-server در خط فرمان، وب سرور وبپک شروع به کار خواهد کرد و تنظیمات را نیز از فایل پیکربندی اعمال می‌کند.
در صورتی که وبپک به صورت محلی نصب شده باشد، بایستی یک مدخل به قسمت اسکریپت‌های package.json برای راهنمایی npm اضافه کنیم. محتویات این فایل پس از تغییرات، از این قرار است:
//package.json file
{
  "name": "dntwebpack",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "webpack": "webpack",
    "webpackserver": "webpack-dev-server"
  },
  "author": "mehdi",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^1.13.1",
    "webpack-dev-server": "^1.14.1"
  }
}
در اینجا پروپرتی جدیدی به قسمت scripts، با نام webpackserver اضافه شده‌است. حال با فراخوانی این اسکریپت با دستور زیر، وب سرور وبپک شروع به کار خواهد کرد:
npm run webpackserver
(دقت کنید که نام‌های قرار داده شده‌ی در قسمت scripts می‌توانند به صورت دلخواه باشند و شما می‌توانید نامی را که دلخواه خودتان است، برگزینید؛ به طور مثال به جای webpackserver نام دیگری را در فایل package.json برای آن مشخص کنید و در هنگام فراخوانی از آن استفاده کنید).
در صورتی که همه چیز بدون مشکل باشد، خروجی شبیه به تصویر زیر را مشاهده خواهید کرد که آدرسی که به صورت محلی، سرور بر روی آن میزبان شده است نیز قابل مشاهده است:


باندل کردن اسکریپت‌های گوناگون توسط وبپک

تا اینجای کار تنها از یک تک اسکریپت، با نام main.js استفاده کردیم. قطعا پروژه‌های واقعی از یک تک اسکریپت تشکیل نخواهند شد و اسکریپت‌های گوناگونی خواهیم داشت. جهت استفاده از چندین اسکریپت توسط وبپک، دو سناریوی مختلف رخ خواهند داد که هر دو را برسی خواهیم کرد:
اضافه کردن اسکریپت‌ها به صورت داینامیک یا پویا توسط وبپک 

در محیط کاری پروژه، یک فایل جدید user.js را اضافه می‌کنیم که از این فایل در فایل main.js استفاده خواهد شد.
محتوای فایل user.js یک تابع ساده‌ی جاوا اسکریپتی خواهد بود:
// user.js file 

function userLog() {
    console.log("ahooy from user module file");
}

module.exports={
    userLog:userLog
}  
حال جهت استفاده از این ماژول در فایل main.js تغییرات زیر را اعمال خواهیم کرد:
//main.js file

var user = require("./user");

user.userLog();

console.log(`i'm bundled by webpack`);
پس از ذخیره‌ی تغییرات خواهید دید که وب سرور وبپک از این تغییرات آگاه شده و باندل جدید را خواهد ساخت که در اینجا خروجی مانند تصویر زیر را خواهید دید:
در تصویر قابل مشاهده است که ماژول user.js نیز وارد باندل شده است.


در صورتی که به مسیری که وبپک در حال میزبانی بر روی آن است در مرورگر خود مراجعه کنید، پیغام‌های چاپ شده را در کنسول مشاهده خواهید کرد.

اضافه کردن اسکریپت‌ها به باندل به صورت استاتیک توسط وبپک

قطعا در پروژه‌های خود از کتابخانه‌هایی که توسط برنامه نویسان دیگر تولید شده‌اند مانند جی کوئری و ... استفاده خواهیم کرد. استفاده از این اسکریپت‌ها به صورت داینامیک و ایمپورت کردن آنها در هر ماژول جالب نخواهد بود و یا ممکن است ماژولی که خود شما نوشته اید به صورت اشتراکی بین تمام برنامه اجرا شود. در این گونه از موارد می‌توانیم این اسکریپت‌ها را در فایل پیکربندی به وبپک معرفی کنیم تا در هنگام باندلینگ، به باندل وارد شوند.
اسکریپت جدیدی را در پروژه اضافه می‌کنیم و نامش را shared.js می‌گذاریم که دارای محتوای زیر است :
// shared.js file
console.log('log message from shared module !');
حال برای اینکه این اسکریپت را به وبپک معرفی کنیم، فایل پیکربندی وبپک را باز کرده و تغییرات زیر را در آن اعمال می‌کنیم :
//webpack.config.js file
module.exports = {
    entry:['./shared.js','./main.js']
    ,output:{
        filename:'bundle.js'
    }
    ,watch :true
}
قابل مشاهده است که قسمت entry، به جای این که یک تک فایل را معرفی کند، تبدیل به یک آرایه شده‌است که هم فایل shared.js را در بر می‌گیرد و هم فایل main.js را دارد.
در مواقعی که فایل پیکربندی دچار تغییر می‌شود، بایستی وبپک را متوقف و دوباره اجرا کنید تا تنظیمات جدید، اعمال شوند. پس از راه اندازی دوباره وبپک، در صورت موفقیت آمیز بودن تغییراتتان، خروجی را شبیه تصویر رو به رو خواهید گرفت و مشخص است که فایل shared.js نیز در باندل وارد شده است.


استفاده از Loader‌ها در وبپک

به صورت پیش فرض وبپک قابلیت باندل کردن ماژول‌های جاوا اسکریپت را دارد و همچنین می‌تواند این فایل‌ها را Minify  کند (در مطالب بعدی خواهیم دید). ولی به طور مثال استفاده از تایپ اسکریپت از توانایی‌های وبپک به صورت توکار خارج است. اینجاست که Loader‌ها وارد کار می‌شوند.
اگر بخواهیم به زبان ساده Loader‌‌ها را تعریف کنیم می‌توان  آنها را کامپوننت هایی دانست که به وبپک فوت و فن کار جدیدی را یاد می‌دهند.
در ادامه Loader تایپ اسکریپت را نصب خواهیم کرد و به کمک آن فایل‌های پروژه را تبدیل به تایپ اسکریپت کرده و در هنگام باندل کردن از وبپک می‌خواهیم که این فایل‌ها را ترنسپایل کند و سپس باندل را از روی آنها بسازد ( برای مطالعه‌ی ادامه‌ی این مطلب احتیاجی به آشنایی به تایپ اسکریپت نیست و هدف استفاده از یک loader است. ولی در صورت علاقه می‌توانید به اینجا مراجعه کنید سری آموزش تایپ اسکریپت)

نصب Loader تایپ اسکریپت 

به خط فرمان برگشته و با استفاده از npm، لودر تایپ اسکریپت مورد نیاز وبپک را نصب می‌کنیم. دستور مورد نیاز این قرار است :
npm install -D ts-loader

( توجه :
در ادامه این مطلب از پیکربندی ساده‌ی یک پروژه‌ی تایپ اسکریپتی استفاده شده است که اعم از ایجاد فایل tsconfig.json و اضافه کردن پوشه‌ی typings به پروژه می‌باشد.)
فایل main.ts را که یک فایل تایپ اسکریپتی می‌باشد، به پروژه اضافه می‌کنیم. محتوای آن به صورت زیر خواهد بود. قابل مشاهده است که از ویژگی‌های ES6 در این فایل استفاده شده و این انتظار را از لودر تایپ اسکریپت داریم که این فایل را در هنگام باندلینگ برای ما ترنسپایل کند.
// main.ts file
let user = require("./user");

user.userLog();
let mainlogger = () => {
    console.log(`i'm bundled by webpack in an arrow function`);
}

mainlogger();
برای اینکه به وبپک خبر دهیم که در پروژه در حال استفاده از تایپ اسکریپت هستیم، فایل پیکربندی وبپک را باز کرده و پروپرتی جدیدی را با نام module به آن معرفی می‌کنیم که خود یک آبجکت می‌باشد. حال در آبجکت module یک پروپرتی جدید را با نام loaders که جنس آرایه‌ای دارد، اضافه می‌کنیم. آرایه‌ی loaders شامل همه‌ی loader هایی خواهد بود که شما قصد استفاده‌ی آنها را به همراه وبپک دارید. هر عضو از این آرایه خود نیز یک آبجکت می‌باشد که دارای سه پروپرتی زیر می‌باشد:
test : یک رجکس می‌باشد که به loader می‌گوید به دنبال چه فایل‌هایی بگردد.
exclude : از جنس رجکس و مشخص کننده‌ی مسیرهایی است که از پروژه باید جدا شوند و توسط loader پردازش نشوند (مانند فایل‌های از قبل کامپایل شده‌ی کتابخانه‌ها).
loader : مشخص کننده‌ی نام loader مورد نظر .
محتوای فایل پیکربندی وبپک، پس از معرفی loader تایپ اسکریپت، به این صورت خواهد بود:
//webpack.config.js
module.exports = {
    entry:['./shared.js','./main.js']
    ,output:{
        filename:'bundle.js'
    }
    ,watch :true
    ,module:{
        loaders:[
            {
                test:/\.ts$/
                ,exclude:/node_modules/
                ,loader:'ts-loader'
            }
        ]
    }
}
حال با اجرای دوباره‌ی وبپک، loader تایپ اسکریپت ابتدا اجرا شده، سپس وبپک وارد کار می‌شود و فایل‌ها را باندل خواهد کرد. در صورتی که بدون مشکل همه چیز اجرا شود، خروجی مانند تصویر زیر را خواهید داشت:

در این مطلب تنظیمات مختلف وبپک، فایل پیکربندی، استفاده از چندین فایل به همراه وبپک، وب سرور وبپک و همچنین با loader‌های وبپک آشنا شدیم.
دریافت فایل‌ها dntwebpack-part2.zip  
مطالب
برنامه نویسی پیشرفته JavaScript - قسمت 3 - انواع ارجاعی و نحوه‌ی ایجاد اشیاء

انواع ارجاعی

قبلا در مورد مقادیر ارجاعی صحبت کردیم. در اینجا نیز به این موضوع اشاره می‌کنیم که هر مقدار ارجاعی، نمونه‌ای ایجاد شده از یک نوع ارجاعی می‌باشد. انواع ارجاعی در واقع ساختارهایی هستند که جهت گروه بندی داده‌ها و عملکرد بین آنها استفاده می‌شوند. در سایر زبان‌های برنامه نویسی شیء گرا، به انواع ارجاعی، کلاس و به مقادیر ارجاعی، شیء می‌گویند. در جاوا اسکریپت نیز، به مقادیر ارجاعی و یا نمونه‌های ایجاد شده از انواع ارجاعی، شیء می‌گویند. به انواع ارجاعی، توصیف گر شیء نیز می‌گویند؛ زیرا ویژگی‌ها و متدهای آن شیء را معرفی و توصیف می‌نماید.


نحوه‌ی ایجاد شیء از نوع ارجاعی Object

از آنجاییکه نوع ارجاعی Object هیچ ویژگی و متد خاصی ندارد، متداول‌ترین نوع ارجاعی جهت ایجاد اشیاء سفارشی می‌باشد. به دو روش می‌توان نمونه‌ای را از یک Object ایجاد نمود. روش اول استفاده از عملگر new و بصورت زیر می‌باشد:

var person = new Object ();
person . name = "Meysam" ;
person . age = 32 ;

با استفاده از عملگر new، شیء person را از نوع Object ایجاد نمودیم که شامل دو ویژگی (Property) به نام‌های name و age می‌باشد. در واقع شیء person ساختاری را جهت نگهداری اطلاعات یک شخص معرفی می‌کند. این عمل موجب جلوگیری از پراکندگی تعریف متغیرها و گروه بندی آنها در قالب یک شیء می‌شود. روش دوم استفاده از Object Literal Notation یا نماد تحت الفظی شیء و بصورت زیر می‌باشد:

var person = {
    name : "Meysam" ,
    age : 32
};

Object Literal Notation ، دستور میانبری برای ایجاد یک شیء از نوع Object می‌باشد. در مثال فوق هم، همانند روش اول، شیء person را با دو ویژگی name و age ایجاد نمود‌ه‌ایم. در این روش، نام ویژگی‌ها می‌توانند به صورت رشته‌ای و عددی نیز به یک شیء اختصاص یابد.

var person = {
    "name" : "Meysam" ,
    "age" : 32
};

معمولا از دو روش فوق زمانی استفاده می‌شود که می‌خواهیم اشیایی را ایجاد نماییم که ویژگی‌های آن‌ها فقط خواندنی باشند. با استفاده از روش دوم، حتی می‌توان یک شیء خالی را ایجاد نمود که در ابتدا هیچ ویژگی ای ندارد  و در مراحل بعد، ویژگی‌هایی را به آن اضافه نمود.

var person = {}; // var person = new Object();
person . name = "Meysam" ;
person . age = 32 ;

در مثال فوق شیء person بدون ویژگی‌ها تعریف شده است؛ سپس به آن ویژگی‌هایی را اضافه نموده‌ایم.

استفاده از روش Object Literal Notation ، یکی از روش‌های محبوب برنامه نویسان جاوا اسکریپت می‌باشد. زیرا با کمترین کد و بصورت بصری، شیء ای را ایجاد نموده و مثلا به یک متد ارسال می‌نمایند. به مثال زیر توجه کنید:

function displayInfo ( arg ) {
    var output = "" ;
    if ( arg . name != undefined )
        output += "Name: " + arg . name + "\n" ;
    if ( arg . age != undefined )
        output += "Age: " + arg . age + "\n" ;
    return output ;
}

alert (displayInfo ({
    name : "Meysam" ,
    age : 32
}));

alert (displayInfo ({
    name : "Sohrab"
}));

در این مثال یک تابع تعریف شده است که آرگومان ورودی آن یک شیء می‌باشد. در تابع بررسی می‌شود که اگر ویژگی name و یا age برای این آرگومان تعریف شده بود، خروجی تابع را تولید نماید. در واقع این ویژگی‌ها اختیاری می‌باشند و می‌توانند ارسال نگردند. در زمان فراخوانی تابع نیز شیء ای را بصورت Object Literal Notation ایجاد نموده و به تابع ارسال کردیم.

این الگو برای ارسال آرگومان، زمانی استفاده می‌شود که تعداد زیادی آرگومان اختیاری داریم و می‌خواهیم به تابع ارسال نماییم. معمولا کار با آرگومان‌های نامی (Named Arguments) راحت‌تر است ولی زمانیکه تعداد آرگومان‌های اختیاری زیاد باشند، مدیریت و نگهداری آنها سخت و طاقت فرسا می‌گردد و ظاهر زشتی را به تابع می‌دهد. بهترین راهکار جهت مدیریت چنین شرایطی این است که آرگومان‌های اجباری را به صورت آرگومان‌های نامی تعریف کنیم و آرگومان‌های اختیاری را به صورت یک شیء به تابع ارسال کنیم.

نکته‌ی دیگری که باید به آن توجه نمود این است که جهت دسترسی به ویژگی‌های یک شیء از (.) استفاده می‌شود. همچنین می‌توان به یک ویژگی با استفاده از [] و بصورت یک آرایه دسترسی داشت که در این صورت نام ویژگی بصورت رشته‌ای در [] ذکر خواهد شد.

alert ( person . name );
alert ( person [ "name" ]);

در عمل تفاوتی بین دو مورد فوق وجود ندارد. مهمترین مزیت استفاده از [] این است که می‌توانید توسط یک متغیر به ویژگی‌های یک شیء دسترسی داشته باشید. همچنین اگر نام ویژگی شامل کاراکترهایی باشد که خطای گرامری رخ می‌دهد یا از اسامی رزرو شده استفاده کرده باشید، می‌توانید از [] جهت دسترسی به ویژگی استفاده نمایید.

var propertyName = "name" ;
alert ( person [ propertyName ]);
alert ( person [ "first name" ]);

در دستور alert اول، با استفاده از یک متغیر به ویژگی name از شیء person دسترسی پیدا نمودیم. در دستور آخر نیز، به دلیل وجود space در نام ویژگی، مجبور هستیم جهت دسترسی به ویژگی first name از [] استفاده نماییم.


بررسی نوع ارجاعی Function

توابع در واقع یک شیء و نمونه‌ای از نوع ارجاعی Function می‌باشند که می‌توانند همانند سایر اشیاء ویژگی‌ها و متدهای خاص خود را داشته باشند. بنابراین می‌توان در یک عبارت، تابعی را به یک شیء نسبت داد. به مثال زیر توجه کنید:

var sum = function ( a , b ) {
    return a + b ;
};

alert ( sum ( 10 , 20 ));

خروجی :

    30


شیء sum را تعریف نموده و یک تابع را به آن اختصاص دادیم که شامل دو آرگومان ورودی می‌باشد. حال می‌توان با شیء sum همانند یک تابع رفتار نمود و تابع مورد نظر را فراخوانی کرد. توجه داشته باشید که هیچ نامی را در زمان تعریف تابع به آن اختصاص نداده‌ایم. به این شکل تعریف تابع، Function Expression می‌گویند.

همانند سایر اشیاء، نام تابع نیز اشاره‌گری به تابع می‌باشد. بنابراین می‌توان توابع را نیز به یکدیگر نسبت داد. به مثال زیر توجه کنید:

function sum ( a , b ) {
    return a + b ;
}
alert ( sum ( 10 , 10 ));

var anotherSum = sum ;
alert ( anotherSum ( 10 , 10 ));

sum = null ;
alert ( anotherSum ( 10 , 10 ));
alert ( sum ( 10 , 10 )); // Error: Object is not a function;

خروجی :

    20

    20

    20

    Error: Object is not a function


ابتدا تابعی را به نام sum ایجاد نمودیم که دو عدد را با هم جمع می‌کند. دقت داشته باشید که به این شکل تعریف تابع sum ، اعلان تابع یا Function Declaration می‌گویند. سپس متغیری را به نام anotherSum ، تعریف نموده و sum را به آن نسبت دادیم. توجه داشته باشید که در زمان انتساب یک تابع به یک متغیر نباید () را ذکر کنیم، زیرا ذکر () به منزله‌ی فراخوانی تابع و اختصاص خروجی آن به متغیر می‌باشد و نه انتساب اشاره گر تابع به آن متغیر. فراخوانی sum و anotherSum خروجی یکسانی را دارند؛ زیرا هر دو به یک تابع اشاره می‌کنند. در خطوط بعدی، شیء sum را با مقدار null تنظیم نمودیم. در واقع با این کار اشاره‌گر sum برابر null شده است؛ یعنی دیگر به هیچ تابعی اشاره نمی‌کند. ولی تابع همچنان در حافظه وجود دارد؛ زیرا اشاره‌گر دیگری به نام anotherSum در حال اشاره نمودن به آن می‌باشد. در مرحله‌ی بعدی که sum را فراخوانی نمودیم، به دلیل null بودن آن، خطا رخ خواهد داد.


بازنگری مجدد به مبحث Overloading

در اینجا فقط می‌خواهیم اشاره‌ای کنیم به مبحث Overloading که قبلا در مورد آن بحث کردیم تا دلیل فنی عدم وجود Overloading را در جاوا اسکریپت درک کنیم. همانطور که قبلا بیان شد، نام تابع در واقع اشاره گری به تابع می‌باشد؛ بنابراین تعریف دو تابع هم نام، همانند اختصاص مجدد مقدار یا تغییر مقدار یک متغیر می‌باشد. به مثال زیر توجه کنید:

function calc ( num1 , num2 ) {
    return num1 + num2 ;
}

function calc ( num1 , num2 ) {
    return num1 - num2 ;
}

همانطور که پیشتر نیز عنوان شد، تابع دوم جایگزین تابع اول می‌گردد. در واقع تعریف فوق همانند تعریف زیر می‌باشد:

var calc = function ( num1 , num2 ) {
    return num1 + num2 ;
};

calc = function ( num1 , num2 ) {
    return num1 - num2 ;
};

همانطور که می‌بینید، ابتدا متغیری به نام calc تعریف شده‌است و با یک تابع مقداردهی اولیه شده است. سپس با تابع دوم مقداردهی مجدد گردیده است و دیگر به تابع قبلی اشاره نمی‌کند. بنابراین همیشه تابع آخر جایگزین توابع قبلی می‌گردد. 


Function Declaration در مقابل Function Expression

این دو روش تعریف و استفاده از توابع تقریبا مشابه هم می‌باشند و فقط یک تفاوت اصلی بین آنها وجود دارد و آن به نحوه‌ی رفتار موتور پردازشی جاوا اسکریپت بر می‌گردد. Function Declaration قبل از اینکه کدهای جاوا اسکریپت خوانده و اجرا شوند، خوانده شده و در دسترس خواهند بود؛ اما Function Expression تا زمانی که روال اجرای کد به این خط از کد نرسد، اجرا نخواهد شد و در دسترس نخواهد بود. به مثال Function Declaration زیر توجه کنید:

alert ( sum ( 10 , 20 ));

function sum ( a , b ) {
    return a + b ;
}

خروجی :

    30


قبل از اعلان تابع sum ، این تابع فراخوانی شده است؛ ولی هیچ خطایی رخ نمی‌دهد. زیرا قبل از اجرای دستورات، تابع sum خوانده و در دسترس خواهد بود. اما اگر تابع فوق بصورت Function Expression تعریف شده بود، خطا رخ می‌داد و برنامه اجرا نمی‌شد.

alert ( sum ( 10 , 20 )); // Error: undefined is not a function

var sum = function ( a , b ) {
    return a + b ;
};

خروجی :

    Error: undefined is not a function


همانطور که می‌بینید، در خط اول برنامه، خطای اجرایی رخ داده است. زیرا هنوز روال اجرایی برنامه به خط تعریف تابع sum نرسیده‌است. بنابراین تابع sum در دسترس نخواهد بود و فراخوانی آن موجب بروز خطا می‌گردد.


ارسال تابع به عنوان ورودی یا خروجی توابع دیگر

همانطور که قبلا بیان شد، نام تابع در واقع یک متغیر می‌باشد که به تابع مورد نظر اشاره می‌کند. بنابراین می‌توان همانند یک متغیر با آن رفتار نموده و به عنوان آرگومان ورودی و یا مقدار خروجی یک تابع آن را ارسال نمود. به مثال زیر توجه کنید:

function add ( a , b ) {
    return a + b ;
}

function mult ( a , b ) {
    return a * b ;
}

function calc ( a , b , fn ) {
    return a * b + fn ( a , b );
}

alert ( calc ( 10 , 20 , add ));
alert ( calc ( 10 , 20 , mult ));

خروجی :

    230

    400


دو تابع به نامهای add و mult با دو آرگومان ورودی تعریف شده‌اند که به ترتیب حاصل جمع و حاصل ضرب دو آرگومان را بر می‌گردانند. تابع calc نیز با 3 آرگومان ورودی تعریف شده‌است که قصد داریم برای آرگومان سوم یک تابع را ارسال نماییم. تابع calc در 2 مرحله فراخوانی شده‌است که در یک مرحله تابع add و در مرحله‌ی دیگر تابع mult به عنوان آرگومان ورودی ارسال شده‌اند. همانطور که از قبل می‌دانید، نام تابع اشاره‌گری به خود تابع می‌باشد. در تابع calc نیز با فراخوانی آرگومان fn در واقع داریم تابع ارسالی را فراخوانی می‌نماییم. حال به مثال زیر توجه کنید که یک تابع را به عنوان خروجی بر می‌گرداند:

function createFunction ( a , b ) {
    return function ( c ) {
        var d = ( a + b ) * c ;
        return d ;
    };
}

var fn = createFunction ( 10 , 20 );
alert ( fn ( 30 ));

خروجی :

    900


تابع createFunction دارای 2 آرگومان ورودی می‌باشد و یک تابع را با 1 آرگومان ورودی بر می‌گرداند. در ابتدا تابع createFunction را با آرگومان‌های 10 و 20 فراخوانی نمودیم. خروجی این تابع که خود یک تابع با یک آرگومان ورودی می‌باشد، به عنوان خروجی برگردانده شده و در متغیر fn قرار می‌گیرد. سپس تابع fn با آرگومان ورودی 30 فراخوانی می‌گردد که مقادیر 10 و 20 را با هم جمع نموده و در 30 ضرب می‌نماید. 

مطالب
وظیفه app.UseExceptionHandler("/Error") در Blazor Server
علیرغم اینکه در Program.cs یا Startup.cs کد زیر وجود دارد، اما بازهم استثناءها در Blazor Server در قالب یک نوار زرد رنگ، پایین مرورگر نشان داده می‌شوند؛ حال در محیط توسعه باشد و یا در محیط تولید و پابلیش نهایی محصول!
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
            }

برای آزمایش آن، کد فوق را به شکل زیر کامنت می‌کنیم تا در محیط توسعه نیز در صورتیکه استثنایی رخ داد، ما را به صفحه‌ی Error.cshtml پیش فرض هدایت کند:
            //if (env.IsDevelopment())
            //{
                //app.UseDeveloperExceptionPage();
            //}
            //else
            //{
                app.UseExceptionHandler("/Error");
            //}
حال کامپوننت counter را به شکل زیر ویرایش می‌کنیم تا استثنایی به عمد رخ دهد:
@page "/counter"

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
        throw new Exception("This is my Exception !!");
    }
}
با اجرای برنامه ملاحظه خواهید کرد که به صفحه‌ی Error.cshtml هدایت نخواهید شد! حتی با اینکه استثنایی رخ داد، خط app.UseExceptionHandler("/Error")   اصلا کاری به مدیریت استثناء نداشت. حال سؤالی اینجا پیش می‌آید: پس چرا مایکروسافت در visual studio به تولید کدهای پیش فرض صفحه Error.cshtml و صدا زدن میان افزار فوق در یک اپلیکیشن Blazor Server می‌پردازد؟
در واقع بسیاری از میان افزارهای Asp.Net Core مانند UseExceptionHandler  در تمام فازهای یک اپلیکیشن Blazor Server به درستی کار نمی‌کنند؛ زیرا Blazor Server با SignalR و هابش کار می‌کند. 
هنگام راه‌اندازی یک برنامه‌ی Blazor Server، ابتدا چند درخواست HTTP وجود دارد که از خط لوله‌ی Asp .Net Core عبور می‌کنند؛ در واقع دقیقا قبل از تشکیل هاب و عملیات websocket. در این فاز اگر استثنایی رخ دهد، آنگاه میان افزار  UseExceptionHandler  وارد عمل خواهد شد و صفحه را به Error.cshtml هدایت خواهد نمود و به این دلیل است که این کدها به صورت پیش فرض وجود دارند. بنابراین باید صفحه‌ی Error.cshtml را نیز در اپلیکیشن‌های تولید شده‌ی خود، به زبان‌های موردنظر پروژه‌تان ترجمه کرده و پیام‌های مناسبی را به کاربر نشان دهید.
باید دقت نمود که دیگر پس از این فاز نمی‌توان به این میان افزار متکی بود. برای مدیریت استثناءها در فازهای بعد از این فاز، می‌توان از ErrorBoundary و یا مدیریت دستی استثناءها استفاده نمود.
مطالب
شروع کار با webpack - قسمت اول
سیستم‌های مدیریت ماژول یا باندل کننده‌های جاوااسکریپتی، چندی است که دچار تنوع زیادی شده‌اند و هر از گاهی، چهره‌های جدیدی خود نمایی می‌کنند. اگر با انگولار 2 آشنا باشید قطعا با SystemJs که یکی دیگر از این گونه باندل کننده هاست آشنایید. در این سری قصد داریم که با یک باندل کننده‌ی تقریبا همه کاره با نام webpack آشنا شویم.


مقدمه و توضیحی بر اینکه چه لزومی بر باندل کننده‌های جاوااسکریپتی هست؟
زمانیکه جاوا اسکریپت پا به عرصه‌ی وجود گذاشت، در توسعه‌ی برنامه‌های کلاینت، از سیستم‌های بیلد استفاده‌ای نمیشد و شاید بتوان ساده‌ترین دلیل آن را عدم احتیاج جاوااسکریپت به کامپایل دانست. ولی با گذشت زمان و عوض شدن چهره‌ی برنامه‌های سمت کلاینت و بزرگ‌تر شدن آنها، برنامه نویسان با مشکلاتی از قبیل نگه داری و امنیت، در برنامه‌های بزرگ رو به رو بودند.
در پاسخ به بزرگ شدن پروژه‌ها قطعا شما این پیشنهاد را خواهید داد که بایستی برنامه را به قسمت‌ها و یا ماژول‌های کوچک‌تری بشکنیم، تا هم نگه داری از آن ساده‌تر شود و هم احتمال بروز خطا در حین انجام پروژه کاهش یابد. اما باید به یاد داشت که این قسمت‌های کوچک شده به معنای یک تگ اسکریپت جدا در صفحات وب برنامه می‌باشند و این مساله به این معنا خواهد بود که برای  هر یک از آنها، مرورگر بایستی به میزبان، درخواستی را ارسال کرده و فایل‌ها را جداگانه دریافت کند. قطعا پاسخ به این مشکل دوباره چسباندن این ماژول‌ها به یکدیگر است تا مرورگر فقط یک درخواست را برای این فایل‌ها ارسال کند. این مسئله همچنین برای فایل‌های css و تصاویر نیز صادق می‌باشد. 
دومین مشکلی که با ماژول سازی برنامه با آن روبه رو می‌شویم، بالا رفتن حجم  کد و درنتیجه بالا رفتن ترافیک مصرفی خواهد بود که این مسئله نیز بایستی توسط یک Minifier حل شود. مشکل بعدی، وابستگی ماژول‌ها به یکدیگر است .در صورتی که در اضافه کردن یک  ماژول به وابستگی‌های آن دقت نداشته باشیم، باعث بروز خطا در برنامه می‌شویم. با استفاده از یک باندلر می‌توانیم وابستگی‌های هر ماژول را تعریف کنیم تا این مسئله نیز حل شود. 
آخرین  مساله‌ای که به ذهن می‌آید نیز می‌توان قابلیت‌های جدید ES6 را نام برد که به صورت سراسری در تمامی مرورگرها ممکن است هنوز قابل استفاده نباشند و شما به عنوان برنامه نویس قصد بهره بردن از آنها را داشته باشید. درنتیجه راهکار، استفاده از یک ترانسپایلر است که می‌توان از معروف‌ترین آنها تایپ اسکریپت و babel را نام برد .

راه‌کارهای مختلف برای حل مشکلات ذکر شده
در صورتی که با فریمورک‌های سمت سرور آشنایی داشته باشید، حتما با سیستم‌های باندل کننده و Minify کننده‌ی آنها برخورد داشته اید. به طور مثال فریمورک Asp.Net Mvc دارای یک باندل کننده‌ی توکار است که مشکل بسته بندی کردن کل ماژول‌ها و همچنین Minify کردن آنها را حل می‌کند. ولی تا آخرین اطلاعی که دارم، مشکل وابستگی ماژول‌ها به جز اینکه برنامه نویس به صورت دستی ترتیب اضافه شدن را رعایت نماید، قابل حل نیست. همچنین در اینجا استفاده از یک ترانسپایلر نیز مقدور نمی‌باشد.
راه حل دیگر استفاده از Task Runner‌های جاوا اسکریپتی مانند گرانت و گالپ می‌باشد که تمامی مسائلی که پیش‌تر ذکر شد، به وسیله‌ی آنها قابل حل است؛ به جز مسئله‌ی وابستگی ماژول‌ها به یکدیگر که بایستی به صورت دستی توسط برنامه نویس ترتیب آنها رعایت شود یا از فریمورک هایی مانند browserify و ... استفاده شود.

راه حل webpack
تفاوت وب پک با TaskRunner‌های جاوا اسکریپتی را می‌توان در اینجا بیان کرد که وب پک در انجام یک وظیفه تخصص وافری دارد و آن وظیفه نیز پردازش فایل‌های ورودی و خروجی داده شده به آن است که با استفاده از کامپوننت‌هایی که با نام loader از آن نام می‌برد، این وظیفه را انجام می‌دهد. با استفاده از این لودرها شما نتیجه‌ای را که از یک TaskRunner انتظار دارید، خواهید گرفت؛ مانند ترنسپایل کردن ماژول‌ها، بسته بندی ماژول‌ها، Minify کردن آنها و در نهایت قابلیتی که معمولا در Task Runner‌ها موجود نیست و وب پک امکان انجام آن را دارد، ترکیب فایل‌های Css با فایل‌های جاوا اسکریپت برنامه است. این کار برای تصاویر و فونت‌های برنامه نیز قابل انجام است.

پیش فرض‌های کار با webpack
دو پیش فرض مهم در شروع به کار با وب پک از این قرارند:
1. وب پک برای نصب Asset‌‌های سمت کلاینت شما از NPM استفاده می‌کند و انتظار دارد که شما نیز این پکیج منیجر بهره ببرید و به طور مثال از bower استفاده نکنید.
2.استفاده از یک سیستم ماژولار ( اینکه از کدام یک استفاده می‌کنید مهم نیست Commonjs ، amd ، es6 و...)

نصب webpack و شروع کار
webpack یکی از صد‌ها ماژول‌های نوشته شده‌ی با استفاده از پلتفرم nodejs می‌باشد. پس اول از همه چیز در صورتیکه nodejs بر روی سیستم شما نصب نیست، آن را دریافت و نصب کنید.  
قبل از شروع به کار بهتر است که یک محیط کار تمیز ( یک فولدر خالی) را آماده کنید و سپس با اجرای دستور npm init، یک بستر برای کار با npm را داشته باشیم. می‌توانید به صورت دستی نیز یک فایل package.json را اضافه کنید و گزینه‌های مدنظرتان را به آن اضافه کنید.
من با اجرای این دستور و جواب دادن به سوالاتش یک خروجی فایل package.json با این محتوا را ایجاد کردم :
{
  "name": "dntwebpack",
  "version": "1.0.0",
  "description": "a webpack tutorial",
  "main": "main.js",
  "scripts": {
     
  },
  "author": "mehdi",
  "license": "MIT"
}
قدم دوم نصب webpack می‌باشد. برای نصب وب پک دو راه وجود دارد:
1. نصب وب پک به صورت گلوبال ( سراسری ) با استفاده از دستور :npm install -g webpack  ، با اجرای این دستور قابلیت استفاده از وب پک را در همه جا با استفاده از خط فرمان، خواهید داشت.
2. ایراد روش اول این است که ممکن است در آینده بخواهید در پروژه‌های گوناگون از دو نسخه‌ی متفاوت وب پک استفاده کنید و به خاطر نسخه‌ای که به طور سراسری نصب شده است به مشکل بر بخورید. پس با استفاده از دستور npm install -D webpack  یا npm install --save-dev webpack  وب پک را به صورت محلی برای پروژه نصب می‌کنیم ( کاربرد پرچم D- یا --save-dev این است که وب پک در قسمت وابستگی‌هایی که فقط جهت توسعه‌ی پروژه هستند، در فایل package.json اضافه می‌شود).
در ادامه در محیط کاری که ایجاد کردیم، دو فایل دیگر را ایجاد می‌کنیم. اولی یک فایل ساده‌ی html جهت اینکه اسکریپت‌های پروژه را به آن اضافه کنیم و دیگری یک فایل اسکریپت جهت اینکه آن را به وب پک بدهیم.
فایل html را index.html نام گذاری کردم و اسکریپت سمپل را نیز main.js. محتوای هر دوفایل به این صورت می‌باشد:
<html>
    <!-- index.html -->
    <head>
        first part of webpack tut!
    </head>
    <body>
        <h1>webpack is awesome !</h1>
        <script src="bundle.js"></script>
    </body>
</html>
//main.js

//start of the journey with webpack

console.log(`i'm bundled by webpack`);
اگر دقت کنید اسکریپتی با نام bundle.js در فایل html رجوع داده شده است که در پروژه وجود خارجی ندارد و قصد این است که این فایل را با استفاده از وب پک تولید کنیم.
حالا نوبت به این می‌رسد که تک فایل main.js را به وب پک بدهیم.
در صورتی که وب پک را به صورت سراسری نصب کرده باشید، این کار ساده است. در خط فرمان با فراخوانی وب پک با دستور webpack ./main.js bundle.js

فایل bundle.js را تولید می‌کنیم.
در صورتی که وب پک به صورت محلی در پروژه نصب شده باشد، فایل package.json را باز کرده و در قسمت scripts، یک ورودی جدید را به اسم webpack به همراه فرمان مورد نظر، به آن می‌دهیم. محتوای فایل package.json پس از این کار به صورت زیر خواهد بود:
{
  "name": "dntwebpack",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
    ,"webpack":"webpack"
  },
  "author": "mehdi",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^1.13.1"
  }
}
حال با استفاده از دستور npm run webpack ./main.js bundle.js  ، وب پک فراخوانی شده و تک فایل main.js را باندل می‌کند.
در صورتی که اجرای دستور بالا موفقیت آمیز باشد، پاسخی مشابه به زیر را باید دریافت کنید:

در قسمت بعدی با تنظیمات پیشرفته‌تر و loader‌های وب پک آشنا می‌شویم .
فایل‌های پروژه dntwebpack.zip  (جهت اجرای آنی احتیاج به نصب وب‌پک را دارید که این کار با استفاده از دستور npm install در فولدر پروژه قابل انجام است).