مطالب
MongoDB #14
عمل تکثیر در MongoDB
عمل تکثیر (Replication) به فرآیند همزمان سازی داده در میان چند سرور گفته می‌شود. تکثیر، افزونگی را فراهم می‌آورد و دسترسی پذیری داده‌ها را توسط کپی داده در چندین سرور مختلف افزایش می‌دهد. این کار، یک پایگاه داده را در مقابل از دسترس خارج شدن یک سرور مفرد، محافظت می‌کند. همچنین امکان بازیابی از خرابی سخت افزار و وقفه‌های سرویس را به کاربر می‌دهد. توسط کپی برداری از اطلاعات، می‌توانید یکی از آنها را برای بازیابی، گزارشگیری و پشتیبان گیری اختصاص دهید.

چرا تکثیر؟
  • برای ایمن نگه داری اطلاعات
  • دسترسی پذیری بالای اطلاعات (شبانه روزی)
  • بازیابی اطلاعات
  • نیازی به از کار افتادن هنگام انجام عملیات نگه‌داری ندارد
  • مقایس پذیری خواندن داده‌ها (کپی برداری‌های اضافه برای عمل خواندن)
  • کپی اطلاعات برای نرم افزارها شفاف و قابل دستیابی است.

تکثیر در MongoDB چگونه کار می‌کند
MongoDB عمل تکثیر را با استفاده از مجموعه کپی یا المثنی (Replica set) انجام می‌دهد. مجموعه کپی یک گروه از نمونه‌های mongodb هستند که مجموعه داده یا دیتاست مشابهی را میزبانی (Host) می‌کنند. در یک کپی داده، یک گره، گره اصلی است که تمام عملیات نوشتن را دریافت می‌کند. بقیه‌ی نمونه‌های ثانویه، عملیات را از گره اصلی، دریافت و اعمال می‌کنند؛ بنابراین آنها هم دیتاست مشابهی دارند. مجموعه‌ی کپی تنها می‌تواند یک گره‌ی اصلی داشته باشد.
  1. یک مجموعه‌ی کپی، یک گروه از دویا چند گره است. (عموما حداقل 3 گره نیاز است.)
  2. در یک مجموعه‌ی کپی، یک گره، گره اصلی است و بقیه گره‌ها گره‌های ثانویه هستند.
  3. همه‌ی داده‌ها از گره‌ی اصلی به گره‌های ثانویه تکثیر می‌شوند.
  4. هنگام انجام عملیات نگه داری یا ازدسترس خارج شدن سرور، گزینش برای گره اصلی و انتخاب گره اصلی جدید آغاز می‌شود.
  5. گره از کار افتاده، بعد از بازیابی دوباره، به مجموعه کپی ملحق می‌شود و بعنوان یک گره ثانویه کار می‌کند.
در زیر یک نوع دیاگرام از تکثیر در MongoDB نشان داده شده است که در آن برنامه‌ی سمت کلاینت همیشه با گره‌ی اصلی در ارتباط است و گره‌ی اصلی، داده‌ها را گره‌های ثانویه تکثیر می‌کند.


ویژگی‌های مجموعه‌ی کپی
  • یک کلاستر از N عدد گره
  • هر گره‌ایی می‌تواند گره اصلی باشد
  • همه‌ی عملیات نوشتن بر روی گره اصلی انجام می‌شود
  • عمل ازدسترس خارج شدن سرور و جایگزین شدن یک گره بصورت اتوماتیک
  • بازیابی بصورت اتوماتیک
  • همراهی و توافق در گزینش گره اصلی

ساختن یک مجموعه کپی
در اینجا می‌خواهیم یک نمونه از mongodb را به یک مجموعه‌ی کپی تبدیل کنیم. برای این کار مراحل زیر را انجام دهید:
  • همه‌ی نمونه‌های در حال اجرای mongod را در سمت سرور، متوقف کنید.
  • اکنون mongod سمت سرور را با سوئیچ –replSet راه اندازی کنید.
گرامر پایه --replSet به شکل زیر است:
mongod --port "PORT" --dbpath "YOUR_DB_DATA_PATH" --replSet "REPLICA_SET_INSTANCE_NAME"
مثال
mongod --port 27017 --dbpath "D:\set up\mongodb\data" --replSet rs0
دستور فوق یک نمونه از mongod را با نام rs0، روی پورت 27017 راه اندازی می‌کند. اکنون command prompt را باز کنید و به این نمونه mongod متصل شوید. در سمت کلاینت، دستور ()rs.initiate را برای شروع کردن یک مجموعه‌ی کپی جدید صادر کنید. برای چک کردن تنظیمات مجموعه‌ی کپی، دستور ()rs.conf را صادر کنید. برای چک کردن وضعیت مجموعه کپی نیز دستور ()rs.status را صادر کنید.

افزودن اعضا به مجموعه‌ی کپی
برای افرودن اعضا به مجموعه‌ی کپی، چند نمونه mongodb را در چندین کامپیوتر راه اندازی کنید. اکنون برنامه‌ی سمت کلاینت را اجرا و دستور ()rs.add را اجرا کنید.

گرامر
گرامر پایه دستور ()rs.add به شکل زیر است:
>rs.add(HOST_NAME:PORT)
مثال
فرض کنید نام نمونه‌ی mongodb شما mongod1.net و بر روی پورت 27017 در حال اجراست. برای افزودن این نمونه به مجموعه کپی، دستور () rs.add را در سمت کلاینت اجرا کنید.
>rs.add("mongod1.net:27017")
>
توجه کنید که فقط وقتی می‌توانید یک نمونه mongodb را برای مجموعه کپی اضافه کنید که به گره اصلی متصل باشید. برای چک کردن اینکه به گره اصلی متصل هستید، دستور ()db.isMaster را در سمت کلاینت صادر کنید.
نظرات مطالب
C# 7 - Tuple return types and deconstruction
بهبود نحوه‌ی انتساب Tuples در حین deconstruction در C# 10.0
پیشتر از یکی از دو روش زیر برای تعریف و مقدار دهی متغیرهای حاصل از deconstruction می‌شد استفاده کرد؛ یا استفاده از var برای هر دو و یا تعریف و مقدار دهی هر دو خارج از deconstruction:
Car car = new("Test", "Blue");

var (model, color) = car;
// Initialization

string model = string.Empty;
string color = string.Empty;
(model, color) = car;
// Assignment
در C# 10.0 این محدودیت برطرف شده‌است و هر دو حالت را می‌توان با هم داشت:
string model = string.Empty;
(model, var color) = car;
// Initialization and assignment
مطالب
بررسی Source Generators در #C - قسمت اول - معرفی
Source Generators که به همراه C# 9.0 ارائه شدند، یک فناوری نوین meta-programming است و به عنوان جزئی از پروسه‌ی استاندارد کامپایل برنامه، ظاهر می‌شود. هدف اصلی از ارائه‌ی Source Generators، تولید کدهای تکراری مورد استفاده‌ی در برنامه‌ها است. برای مثال بجای انجام کارهای تکراری مانند پیاده سازی متدهای GetHashCode، ToString و یا حتی یک AutoMapper و یا Serializer، برای تمام کلاس‌های برنامه، Source Generators می‌توانند آن‌ها را به صورت خودکار پیاده سازی کنند و همچنین با هر تغییری در کدهای کلاس‌ها، این پیاده سازی‌ها به صورت خودکار به روز خواهند شد. مزیت این روش نه فقط تولید پویای کدها است، بلکه سبب بهبود کارآیی برنامه هم خواهند شد؛ از این جهت که برای مثال می‌توان اعمالی مانند Serialization را بدون انجام Reflection در زمان اجرا، توسط آن‌ها پیاده سازی کرد.


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

یک برنامه می‌تواند از چندین Source Generators نیز استفاده کند که روش قرار گرفتن آن‌‌ها را در پروسه‌ی کامپایل، در شکل زیر مشاهده می‌کنید:



Source Generators از یکدیگر کاملا مستقل هستند و اطلاعات آن‌ها Immutable است. یعنی نمی‌توان اطلاعات تولیدی توسط یک Source Generator را در دیگری تغییر داد و تمام فایل‌های تولیدی توسط انواع Source Generators موجود، به پروسه‌ی کامپایل نهایی اضافه می‌شوند. هرچند زمانیکه فایلی توسط یک تولید کننده‌ی کد، به کامپایلر اضافه می‌شود، بلافاصله اطلاعات آن در کل برنامه و IDE و تمام Source Generators موجود دیگر، قابل مشاهده و استفاده است.


مقایسه‌ای بین تولید کننده‌های کد و فناوری IL Weaving

Source Generators، تنها راه و روش تولید کد، نیستند و پیش از آن روش‌هایی مانند استفاده از T4 templates ، Fody ، PostSharp و امثال آن نیز ارائه شده‌است. در ادامه مقایسه‌ای را بین تولید کننده‌های کد و فناوری IL Weaving را که پیشتر در سری AOP در این سایت مطالعه کرده‌اید، مشاهده می‌کنید:
تولید کننده‌های کد:
- تنها می‌توانند فایل‌های جدید را اضافه کنند. یعنی «در حین» پروسه‌ی کامپایل ظاهر می‌شوند و به عنوان یک مکمل، تاثیر گذارند. برای مثال نمی‌توانند محتوای یک خاصیت یا متد از پیش موجود را تغییر دهند. اما می‌توانند هر نوع کد partial ای را «تکمیل» کنند.
- محتوای اضافه شده‌ی توسط یک تولید کننده‌ی کد، بلافاصله توسط Compiler شناسایی شده و بررسی می‌شود و همچنین در Intellisense ظاهر شده و به سادگی قابل دسترسی است. همچنین، قابلیت دیباگ نیز دارد.

IL Weaving:
- می‌توانند bytecode برنامه را تغییر دهند. یعنی «پس از» پروسه‌ی کامپایل ظاهر شده و کدهایی را به اسمبلی نهایی تولید شده اضافه می‌کنند. در این حالت محدودیتی از لحاظ محل تغییر کدها وجود ندارد. برای مثال می‌توان بدنه‌ی یک متد یا خاصیت را بطور کامل بازنویسی کرد و کارکردهایی مانند تزریق کدهای caching و logging را دارند.
- کدهایی که توسط این پروسه اضافه می‌شوند، در حین کدنویسی متداول، قابلیت دسترسی ندارند؛ چون پس از پروسه‌ی کامپایل، به فایل باینری نهایی تولیدی، اضافه می‌شوند. بنابراین قابلیت دیباگ به همراه سایر کدهای برنامه را نیز ندارند. به علاوه چون توسط کامپایلر در حین پروسه‌ی کامپایل، بررسی نمی‌شوند، ممکن است به همراه قطعه کدهای غیرقابل اجرایی نیز باشند و دیباگ آن‌ها بسیار مشکل است.



آینده‌ی Reflection به چه صورتی خواهد شد؟

هرچند Reflection کار تولید کدی را انجام نمی‌دهد، اما یکی از کارهای متداول با آن، یافتن و محاسبه‌ی اطلاعات خواص و فیلدهای اشیاء، در زمان اجرا است و مزیت کار کردن با آن نیز این است که اگر خاصیتی یا فیلدی تغییر کند، نیازی به بازنویسی قسمت‌های پیاده سازی شده‌ی با Reflection نیست. به همین جهت برای مثال تقریبا تمام کتابخانه‌های Serialization، از Reflection برای پیاده سازی اعمال خود استفاده می‌کنند.
امروز، تمام اینگونه عملیات را توسط Source Generators نیز می‌توان انجام داد و این فناوری جدید، قابلیت به روز رسانی خودکار کدهای تولیدی را با کم و زیاد شدن خواص و فیلدهای کلاس‌ها دارد و نمونه‌ای از آن، Source Generator توکار مرتبط با کار با JSON در دات نت 6 است که به شدت سبب بهبود کارآیی برنامه، در مقایسه با استفاده‌ی از Reflection می‌شود؛ چون اینبار تمام محاسبات دقیق مرتبط با Serialization به صورت خودکار در زمان کامپایل برنامه انجام می‌شود و جزئی از خروجی برنامه‌ی نهایی خواهد شد و دیگر نیازی به محاسبه‌ی هرباره‌ی اطلاعات مورد نیاز، در زمان اجرای برنامه نیست.
نمونه‌ای از روش دسترسی به اطلاعات کلاس‌ها و خواص و فیلدهای آن‌ها را در زمان کامپایل برنامه توسط Source Generators، در مثال قسمت بعد، مشاهده خواهید کرد.


وضعیت T4 templates چگونه خواهد شد؟

در سال‌های آغازین ارائه‌ی دات نت، استفاده از T4 templates جهت تولید کدها بسیار مرسوم بود؛ اما با ارائه‌ی Source Generators، این ابزار نیز منسوخ شده در نظر گرفته می‌‌شود.
T4 Templates همانند Source Generators تنها کدها و فایل‌های جدیدی را تولید می‌کنند و توانایی تغییر کدهای موجود را ندارند. اما مشکل مهم آن، داشتن Syntax ای خاص است که توسط اکثر IDEها پشتیبانی نمی‌شود. همچنین عموما اجرای آن‌ها نیز دستی است و برخلاف Source Generators، با تغییرات کدها، به صورت خودکار به روز نمی‌شوند.


تغییرات زبان #C در جهت پشتیبانی از تولید کننده‌های کد

از سال‌های اول ارائه‌ی زبان #C، واژه‌ی کلیدی partial، جهت فراهم آوردن امکان تقسیم کدهای یک کلاس، به چندین فایل، میسر شد که از این قابلیت در فناوری T4 Templates زیاد استفاده می‌شد. اکنون با ارائه‌ی تولید کننده‌های کد، واژه‌ی کلیدی partial را می‌توان به متدها نیز افزود تا پیاده سازی اصلی آن‌ها، در فایلی دیگر، توسط تولید کننده‌های کد انجام شود. تا C# 8.0 امکان افزودن واژه‌ی کلیدی partial به متدهای خصوصی یک کلاس و آن هم از نوع void وجود داشت و در C# 9.0 به متدهای عمومی کلاس‌ها نیز اضافه شده‌است و اکنون این متدها می‌توانند void هم نباشند:
partial class MyType
{
   partial void OnModelCreating(string input); // C# 8.0

   public partial bool IsPet(string input);  // C# 9.0
}

partial class MyType
{
   public partial bool IsPet(string input) =>
     input is "dog" or "cat" or "fish";
}
مطالب
شروع کار با webpack - قسمت چهارم
در سه قسمت قبلی با مفاهیم گوناگونی از وبپک آشنا شدیم که می‌توان به ساخت باندل‌های ساده و پیشرفته، استفاده از لودرها، فایل‌های پیکربندی  و ... اشاره کرد.

بارگذاری فایل‌های css به کمک وبپک

همان طور که قبلا اشاره شد، هسته‌ی وبپک به خودی خود بجز باندل کردن اسکریپت‌های خام جاوا اسکریپت و در نهایت Minify کردن آنها، قادر به انجام کار دیگری نیست. همین طور ذکر شد، برای اینکه وبپک فوت و فن جدیدی را یاد بگیرد، از Loader‌ها استفاده می‌کنیم. وارد کردن فایل‌های css به باندل نیز به کمک Loader‌ها خواهد بود. برای اینکار به دو Loader احتیاج داریم و به کمک npm آنها را به عنوان وابستگی برای توسعه‌ی پروژه نصب خواهیم کرد .
// نصب لودر‌های مورد نظر
npm install css-loader style-loader -D
لودر css وظیفه‌ی بارگذاری فایل‌های css و همچنین وابستگی آنها ( import هایی که در این فایل‌ها انجام شده) را دارد و در نهایت css نهایی را بر می‌گرداند.
لودر style نیز وظیفه‌ی اضافه کردن ماژول اکسپورت شده را به DOM، به عنوان یک style خواهد داشت.
در ساختار پروژه نیز تغییراتی انجام شده و فایل‌ها و لودر‌های اضافی حذف شده‌اند تا تمرکز بر روی مطلب بیشتر باشد. مانند قسمت اول، یک تک صفحه‌ی index.html را خواهیم داشت که دارای محتوای زیر است:
//index.html file
<html>
  <head>
    <title>webpack part 4</title>

  </head>
  <body>
    <h1>webpack is awesome</h1>
    <p>part 4 of tutorial</p>
    <div>i have a background</div>
    <h1>تست فونت !</h1>

    <script src="/assets/js/bundle.js">
    </script>
  </body>
</html>
اگر دقت کنید، در این فایل لینکی به فایل‌های استایل، مانند css وجود ندارد و هدف این است که این فایل‌ها توسط وبپک پردازش شوند.
برای شروع به فایل پیکربندی وبپک مراجعه کرده و دو Loader ی را که برای این کار، بالاتر در پروژه نصب کردیم، به وبپک معرفی می‌کنیم.
//webpack.config.js
var path = require("path");
var webpack = require("webpack");

module.exports = {
    context: path.resolve("js"),
    entry: ['./main.js']
    , output: {
        path: path.resolve("build/js"),
        publicPath: "assets/js",
        filename: 'bundle.js'
    },
    devServer: {
        contentBase: "assets"
    }
    , watch: true
    , module: {
        loaders: [
            {
                test: /\.css$/
                , exclude: /node_modules/
                , loader: 'style-loader!css-loader'
            }
        ]
    }
}
در قطعه کد بالا محتوای فایل پیکربندی قابل مشاهده است. مشخص است که لودر جدیدی را به وبپک معرفی کرده‌ایم که به دنبال فایل‌هایی با پسوند css در پروژه می‌گردد. ولی در کلید loader که وظیفه‌ی فراخوانی لودر مورد نظر را در مواجهه با این فایل‌ها دارد، کمی با قبل تفاوت وجود دارد.
loader:'style-loader!css-loader'
در قطعه کد بالا، نشانگر ! در مواقعی استفاده می‌شود که قصد داریم لودر‌ها را به صورت زنجیره‌ای استفاده کنیم. مثلن در اینجا به وبپک می‌گوییم که برای فایل‌های css ابتدا لودر css را فراخوانی کن و سپس با خروجی که از این لودر می‌گیری، لودر style را صدا بزن و منتظر جواب آن باش. ترتیب فراخوانی نیز از آخر به اول می‌باشد (اول لودر css سپس لودر style).
در مطالب قبلی ذکر شد که دو حالت برای معرفی فایل‌ها به وبپک وجود دارد؛ یکی معرفی آنها در کلید entry فایل پیکربندی و دیگری استفاده از تابع require در اسکریپت‌ها، برای بارگذاری پویای ماژول‌های دیگر. استفاده از استایل‌های css نیز به همین صورت است. برای بارگذاری فایل‌های استایل، از روش پویا استفاده کرده و در فایل main.js استایل مورد نظر را با کمک require وارد می‌کنیم.
محتوای فایل main.js بدین صورت است:
// main.js file
require("./../assets/main.css");
console.log(`i'm bundled by webpack`);
محتوای فایل main.css نیز بدین شکل می‌باشد:
// main.css
body{
    background-color: #DAA520;
}
با راه اندازی وبپک و باز کردن صفحه‌ی index می‌توان دید که فایل استایل ما به همراه باندل وارد شده است:

در تصویر بالا مشخص است که در تگ Head صفحه، یک تگ جدید style، توسط وبپک ایجاد شده و استایل ما به صفحه تزریق شده‌است. همچنین اگر وبپک را به حالت Minify کردن باندل ببریم (در مطلب قبلی نحوه‌ی این کار ذکر شد)، باندل نهایی برای فایل‌های css نیز Minify خواهد شد.


استفاده از Sass با کمک وبپک 


روش استفاده از Sass نیز تفاوتی با css نخواهد داشت و فقط کافی است Loader آن را در پروژه نصب کنیم و در نهایت آن را در فایل پیکربندی، به وبپک معرفی کنیم. با دستور زیر لودر Sass را در پروژه وارد می‌کنیم:

// نصب لودر sass
npm install -D sass-loader node-sass

( node-sass به عنوان وابستگی لودر sass، در کنار آن نصب شده است)

حال به فایل پیکربندی می‌رویم و لودر جدید را به قسمت لودر‌ها اضافه می‌کنیم:

// webpack.config.js 
module: {
        loaders: [
            {
                test: /\.css$/
                , exclude: /node_modules/
                , loader: 'style-loader!css-loader'
            }
            ,{
                test:/\.scss$/
                ,exclude:/node_modules/
                ,loader:'style-loader!css-loader!sass-loader'
            }
        ]
    }

در پوشه‌ی assets نیز فایل جدیدی را با عنوان main.scss ساخته و محتوای زیر را در آن وارد می‌کنیم:

// main.scss
$background-color:#DAA520;

body{
    background-color: $background-color;
}

سپس در فایل main.js به جای وارد کردن فایل css قبلی، فایل scss جدید را با کمک require وارد می‌کنیم و در ادامه وبپک را اجرا می‌کنیم. خواهیم دید که مانند قبل بدون مشکلی وبپک اجرا شده، فایل scss را به css ترجمه کرده و سپس به کمک بقیه لودر‌ها، به باندل اضافه می‌کند. استفاده از بقیه‌ی فریمورک‌های css مانند Less و ... نیز با کمک لودر آنها به همین صورت قابل انجام است.


استفاده از Autoprefixer 

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

npm install -D autoprefixer-loader

و بعد از نصب شدن آن، در فایل پیکربندی وبپک به لودرهایی که برای فایل‌های css و scss اضافه کرده بودیم، این لودر را نیز به صورت زنجیر وار اضافه می‌کنیم:

//webpack.config.js
module: {
        loaders: [
            {
                test: /\.css$/
                , exclude: /node_modules/
                , loader: 'style-loader!css-loader!autoprefixer-loader'
            }
            ,{
                test:/\.scss$/
                ,exclude:/node_modules/
                ,loader:'style-loader!css-loader!autoprefixer-loader!sass-loader'
            }
        ]
    }

در هر دو لودری که برای css و scss ساخته بودیم، از لودر autoprefixer استفاده کردیم. برای تست اینکه این لودر بدون مشکل کار می‌کند، در فایل main.scss تغییر زیر را ایجاد می‌کنیم:

//main.scss
$background-color:#DAA520;

body{
    background-color: $background-color;
    display: flex;
}

حال با اجرای وبپک خواهیم دید که prefix‌های مورد نیاز توسط لودر اضافه شده اند ( این لودر از کتابخانه‌ی postcss کمک می‌گیرد).




باندل کردن تصاویر و فونت‌ها با کمک وبپک


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

جهت باندل کردن تصاویر و فونت‌ها، به لودر جدیدی با نام url-loader احتیاج داریم. قبل از هر چیزی این لودر را در پروژه با کمک npm نصب می‌کنیم:

npm install -D url-loader file-loader

(لودر file-loader به عنوان وابستگی مورد نیاز است)

روند همچنان مثل گذشته است و پس از نصب لودر، وارد فایل پیکربندی شده و لودر جدید را به وبپک معرفی می‌کنیم:

//webpack.config.js file
module: {
        loaders: [
            {
                test: /\.css$/
                , exclude: /node_modules/
                , loader: 'style-loader!css-loader!autoprefixer-loader'
            }
            ,{
                test:/\.scss$/
                ,exclude:/node_modules/
                ,loader:'style-loader!css-loader!autoprefixer-loader!sass-loader'
            },{
                test:/\.(png|jpg|ttf|eot)$/
                ,exclude:/node_modules/
                ,loader:'url-loader?limit=100000'
            }
        ]
    }

در لودر اضافه شده، پسوند فایلهایی را که قصد داریم به باندل وارد شوند، معرفی می‌کنیم. در اینجا فرمت‌های png , jpg ,ttf, eot ذکر شده‌اند.

تنها نکته‌ی جدید، در مشخص کردن نام لودر وجود دارد و آن نیز قسمت پس از علامت ؟ می‌باشد. هنگام مشخص کردن اینکه از چه لودری قصد استفاده داریم، می‌توانیم با استفاده از ؟ پارامترهایی را به لودر مورد نظر ارسال کنیم. در اینجا به پارامتر limit، مقدار 100000 را داده‌ایم که برای این لودر به این معناست که اگر حجم فایل در حال پردازش، حجمی بیشتر از این مقدار را داشت، این فایل را به صورت یک لینک جدا از باندل قرار بده. ولی اگر حجمی کمتر از این مقدار داشت، لودر به صورت خودکار فایل را به فرمت Base64 انکود می‌کند و در درون باندل قرار می‌دهد.


برای تست اینکه آیا این لودر به درستی کار می‌کند یا نه، یک تصویر نمونه را در فولدر assets قرار می‌دهیم و سپس در فایل main.scss تغییرات زیر را انجام می‌دهیم.

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



حال محدودیت حجم فایل را بالا می‌بریم و می‌توان دید که تصویر در باندل نهایی به صورت انکود شده قرار گرفته است .


قطعا انجام این کار برای تصاویری با حجم بالا مناسب نخواهد بود و برنامه نویس بسته به نیاز بایستی مقدار محدودیت حجم را برای لودر مشخص کند.


در تعریف بالا دیدیم که فرمت‌های مورد نیاز برای وارد کردن فونت را نیز علاوه بر تصاویر، برای وبپک مشخص کرده‌ایم. روند وارد کردن فونت‌ها به باندل نیز تفاوتی با تصاویر ندارد و کافی است تعاریف مورد نیاز را در فایل‌های css داشته باشیم.

برای مثال فونت ساحل در پوشه‌ی assets قرار داده شده و در فایل main.scss تغییرات زیر انجام شده‌اند:

// main.scss

$background-color:#DAA520;
 
div{
    background-image: url("galaxy.jpg");
}

@font-face {
  font-family: Sahel;
  src: url('Sahel.eot');
  src: url('Sahel.eot?#iefix') format('embedded-opentype'),
       url('Sahel.woff') format('woff'),
       url('Sahel.ttf') format('truetype');
  font-weight: normal;
}

@font-face {
  font-family: Sahel;
  src: url('Sahel-Bold.eot');
  src: url('Sahel-Bold.eot?#iefix') format('embedded-opentype'),
       url('Sahel-Bold.woff') format('woff'),
       url('Sahel-Bold.ttf') format('truetype');
  font-weight: bold;
}

@font-face {
  font-family: Sahel;
  src: url('Sahel-Black.eot');
  src: url('Sahel-Black.eot?#iefix') format('embedded-opentype'),
       url('Sahel-Black.woff') format('woff');
    
  font-weight: 900;
} 

body{
    background-color: $background-color;
    font-family: 'Sahel';
    display: flex;
}

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



روش دیگری برای وارد کردن تصاویر نیز موجود است؛ به این صورت که به فرض مثال یک تگ img در اسکریپت ساخته و سپس پروپرتی src آن را با کمک require برابر با آدرس تصویر مورد نظر قرار می‌دهیم. این روش نیز برای وبپک قابل فهم بوده و فایل وارد باندل می‌شود. در ادامه مثالی از این روش آورده شده است:

var img = document.createElement("img");
img.width="200px";
img.height="200px";
img.src= require("path to some image");


چند نکته‌ی پایانی :

1. در فایل پیکربندی همیشه پسوند فایل‌هایی را که در کلید entry قرار داشتند، مشخص کردیم:

entry:['./main.js','./shared.ts']

با کلیدی با نام resolve در فایل پیکربندی می‌توان مشخص کرد در صورتیکه پسوند فایلی مشخص نبود، به ترتیب مشخص شده به دنبال آن بگردد. به طور مثال:

// webpack.config.js
resolve:{
            extensions:['','.js','.ts']
  }

در تعریف بالا ذکر می‌شود در صورتیکه پسوند فایل ورودی مشخص نبود، ابتدا به دنبال فایل بدون پسوند، سپس فایل‌هایی با پسوند js و در نهایت به دنبال فایل‌هایی با پسوند ts بگرد. توجه داشته باشید که ترتیب مشخص کردن پسوند فایل‌ها مهم است و وبپک بر اساس این ترتیب به دنبال فایل مورد نظر خواهد گشت.

حال می‌توان مقدار کلید entry را اینطور تعریف کرد:

entry:['./main','./shared']


2.استفاده از فایل‌های css ی که در درونشان فونت‌های مورد نیاز لینک شده‌اند تنها با استفاده از لودر css قابل انجام نیست. به طور مثال استفاده از کتابخانه‌ی بوت استرپ تنها با این لودر ممکن نیست و بایستی لودر url-loader نیز در پروژه نصب شده باشد تا در هنگامیکه وبپک به فونت‌ها برخورد کرد، بتواند آنها را وابسته به شرایط، وارد باندل نهایی کند.


فایل‌های پروژه: dntwebpack-part4.zip 

نظرات مطالب
ASP.NET MVC #1
- ASP فرق می‌کنه با ASP.NET؛ ASP یک فناوری مبتنی بر COM دهه نود میلادی بود و با آمدن ASP.NET در ابتدای سال‌های 2000، توسعه آن توسط مایکروسافت خاتمه پیدا کرد.
- خروجی چه ASP دهه نود که الان به آن Classics ASP گفته می‌شود، چه ASP.NET دهه بعد از 2000، چه PHP، چه JSP و امثال آن همگی HTML هستند. مرورگرها بجز متون، HTML، CSS، جاوا اسکریپت و تصاویر به صورت پیش فرض قادر به پردازش محتوای دیگری نیستند؛ مگر اینکه افزونه خاصی را بکار برده باشند؛ مانند همین سیلورلایت یا فلش.
- در HTML و CSS چندین و چند روش قرار دادن عناصر در صفحه وجود دارند مانند static، absolute، fixed، relative. بر همین اساس در طراحی HTML یک سری مباحث Responsive یا واکنش‌گرا نیز وجود دارند که با استفاده از ترکیب CSS و HTML به خوبی قابل پوشش هستند. نمونه‌اش را در مباحث twitter bootstrap سایت می‌توانید پیدا کنید. مثلا twitter bootstrap 3 یک فریم ورک CSS اصطلاحا mobile first است. یعنی طوری طراحی شده که سایت شما را به خوبی بتواند با اندازه‌های کوچک نمایشگرها تطابق دهد و قابل استفاده کند.

نتیجه گیری؟
ASP.NET یک فناوری سمت سرور است که نهایتا می‌تواند یک خروجی استاندارد قابل تفسیر توسط مرورگرها را تولید کند. در این بین شما می‌توانید از توانمندی‌های موجود در CSS، HTML و جاوا اسکریپت، برای بهبود دسترسی پذیری به سایت خودتان کمال استفاده را نمائید. اما اساسا این مباحث (مثلا طراحی واکنش‌گرا) ربطی به فناوری‌های سمت سرور ندارند و جزو مباحث سمت کاربر محسوب می‌شوند.
اشتراک‌ها
یک ویرایشگر تمام عیار برای طراحان وب!

با کلیک کردن روی دکمه «Launch the Editor» یک محیط ساده و سریع برای ویرایش فایل‌های HTML، Js و Css به همراه امکان نمایش آنلاین نتایج برای شما فراهم می‌شود. نکته جالب دسترسی ساده به بسیاری از کتابخانه‌های معروف جاوااسکریپت است که به صورت خودکار به پروژه‌های شما اضافه می‌شوند. مدیریت نسخه‌های مختلف فایلها و ... 

یک ویرایشگر تمام عیار برای طراحان وب!
نظرات مطالب
راه اندازی StimulSoft Report در ASP.NET MVC
فایلی که در بالا استفاده شده و آقای بالازاده زحمت مشخص کردنش را کشیدند برای خود محیط گزارش هست.
فایل‌های گزارشی که در استودیو خود استیمول طراحی میشن از فارسی پشتیبانی کرده و دارای خصوصیت Right to left برای true شدن میباشند.
همچین در صورتی که مشکل در نمایش داخل خود صفحه وب است در بالا کد css آن ذکر شده است.
نظرات مطالب
ایجاد قابلیت قالب یا Theme در ASP.NET MVC
- نکته دو: نام bundle را حتما هم عمق با آدرس قالب تعریف کنید تا وقتی فایل css  به پوشه‌ی images  یا فونت مجاور خود اشاره می‌کند، آدرس دهی معتبر باشد. 
امکان بازنویسی خودکار آدرس‌ها داخل فایل‌های استایل هم وجود دارد:
 bundles.Add(new StyleBundle(
                "~/Content/fa",
                ContentDeliveryNetwork.MaxCdn.FontAwesomeUrl)
                .Include("~/Content/fontawesome/site.css",new CssRewriteUrlTransform()));
نکته قابل توجه، استفاده از CssRewriteUrlTransform میباشد.
نظرات مطالب
آغاز به کار با Twitter Bootstrap در ASP.NET MVC
شما اشاره کردید به این که اگر پروژه رو درحالت release قرار بدیم فشرده سازی اعمال میشه یعنی اینکه
در فایل web.config در قسمت compilation خصوصیت debug رو حذف کنیم:
 <compilation debug="true"  targetFramework="4.5" />
این کارو انجام دادم اما وقتی سورس صفحه رو نگاه می‌کنم فشرده سازی اعمال نشده به فایل‌های css  و js !