اشتراکها
نظرات مطالب
AngularJS #1
knockoutjs کتاب خانه ای برای انجام DataBinding در وب هست، یعنی برای مقید سازی اشیاء جاوا اسکریپت به کنترلهای html.
AngularJS یک Toolset برای درست کردن framework و برنامههای تک صفحه ای میباشد، angular قابلیت مقید سازی دادهها را هم فراهم میکند.
لطفا برای اطلاعات بیشتر این مطلب را مطالعه کنید.
مطالب
چرا TypeScript؟
زبان TypeScript به عنوان superset زبان JavaScript ارائه شدهاست و هدف آن، strong typing و ارائهی قابلیتهای پیشرفتهی زبانهای شیءگرا، جهت نوشتن برنامههای کلاینت و سرور، با کمترین میزان خطاها است. زبان TypeScript چندسکویی و سورس باز است و در نهایت به نگارشی از JavaScript کامپایل میشود که با تمام مرورگرهای فعلی سازگاری دارد و یا در سمت سرور بدون مشکلی توسط NodeJS قابل درک است.
- TypeScript زبان توصیه شدهی توسعهی برنامههای AngularJS 2 است و همچنین با سایر کتابخانههای معروف جاوا اسکریپتی مانند ReactJS و jQuery نیز سازگاری دارد. بنابراین اگر قصد دارید به AngularJS 2 مهاجرت کنید، اکنون فرصت خوبی است تا زبان TypeScript را نیز بیاموزید. همچنین WinJS نیز با TypeScript نوشته شدهاست.
- superset زبان JavaScript بودن به این معنا است که تمام کدهای جاوا اسکریپتی موجود، به عنوان کد معتبر TypeScript نیز شناخته میشوند و همین مساله مهاجرت به آنرا سادهتر میکند. زبانهای دیگری مانند Dart و یا CoffeeScript ، نسبت به JavaScript بسیار متفاوت به نظر میرسند؛ اما Syntax زبان TypeScript شباهت بسیار زیادی به جاوا اسکریپت و خصوصا ES 6 دارد. در اینجا تنها کافی است پسوند فایلهای js را به ts تغییر دهید و از آنها به عنوان کدهای معتبر TypeScript استفاده کنید.
- strong typing و معرفی نوعها، کدهای نهایی نوشته شده را امنتر میکنند. به این ترتیب کامپایلر، پیش از اینکه کدهای شما در زمان اجرا به خطا بر بخورند، در زمان کامپایل، مشکلات موجود را گوشزد میکند. همچنین وجود نوعها، سرعت توسعه را با بهبود ابزارهای مرتبط با برنامه نویسی، افزایش میدهند؛ از این جهت که مفهوم مهمی مانند Intellisense، با وجود نوعها، پیشنهادهای بهتر و دقیقتری را ارائه میدهد. همچنین ابزارهای Refactoring نیز در صورت وجود نوعها بهتر و دقیقتر عمل میکنند. این موارد مهمترین دلایل طراحی TypeScript جهت توسعه و نگهداری برنامههای بزرگ نوشته شدهی با JavaScript هستند.
- Syntax زبان TypeScript به شدت الهام گرفته شده از زبان سیشارپ است. به همین جهت اگر با این زبان آشنایی دارید، درک مفاهیم TypeScript برایتان بسیار ساده خواهد بود.
- بهترین قسمت TypeScript، کامپایل شدن آن به ES 5 است (به این عملیات Transpile هم میگویند). در زبان TypeScript به تمام امکانات پیشرفتهی ES 6 مانند کلاسها و ماژولها دسترسی دارید، اما کد نهایی را که تولید میکند، میتواند ES 5 ایی باشد که هم اکنون تمام مرورگرهای عمده آنرا پشتیبانی میکنند. با تنظیمات کامپایلر TypeScript، امکان تولید کدهای ES 3 تا ES 5 و همچنین ES 6 نیز وجود دارد. نمونهی آنلاین این ترجمه را در TypeScript playground میتوانید مشاهده کنید.
- TypeScript چندسکویی است. امکانات و کامپایلر این زبان، برای ویندوز، مک و لینوکس طراحی شدهاند.
- TypeScript سورس باز است. طراحان اصلی آن، همان طراحان زبان سیشارپ در مایکروسافت هستند و هم اکنون این زبان به صورت سورس باز توسط این شرکت توسعه داده شده و در GitHub نگهداری میشود.
آماده سازی محیطهای کار با TypeScript
برای کار با TypeScript، یک ادیتور متنی ساده، به همراه کامپایلر آن کفایت میکند. اما همانطور که عنوان شد، یکی از مهمترین دلایل وجودی TypeScript، بهبود ابزارهای برنامه نویسی مرتبط با JavaScript است و اگر قرار باشد صرفا از یک ادیتور متنی ساده استفاده شود، فلسفهی وجودی آن زیر سؤال میرود.
نصب TypeScript در ویژوال استودیو
در نگارشهای جدید ویژوال استودیو، از VS 2013 Update 2 به بعد، قسمت ویژهی TypeScript نیز قابل مشاهدهاست. البته این قسمت با به روز رسانیهای TypeScript، نیاز به به روز رسانی دارد. به همین جهت به سایت رسمی آن مراجعه کرده و بستههای جدید مخصوص VS 2013 و یا 2015 آنرا دریافت و نصب کنید.
همچنین افزونهی Web Essentials نیز امکانات بیشتری را جهت کار با TypeScript به همراه دارد و امکان مشاهدهی خروجی جاوا اسکریپت تولیدی را در حین کار با فایل TypeScript فعلی میسر میکند. در سمت چپ صفحه TypeScript را خواهید نوشت و در سمت راست، خروجی JavaScript نهایی را بلافاصله مشاهده میکنید.
تصویر فوق مربوط به VS 2015 است. همچنین گزینهی افزودن یک فایل و آیتم جدید نیز امکان افزودن فایلهای TS را به همراه دارد.
نصب و تنظیم TypeScript در ویژوال استودیو کد
ویژوال استودیو کد، نگارش رایگان، سورس باز و چندسکویی ویژوال استودیو است که بر روی ویندوز، مک و لینوکس قابل اجرا است. ویژوال استودیو کد نیز به همراه پشتیبانی بسیار خوبی از TypeScript است، تا حدی که تمام ارائههای معرفی Anugular 2 توسط تیم مربوطهی آن از گوگل، توسط ویژوال استودیو کد و یکپارچگی آن با TypeScript انجام شدند.
ویژوال استودیو کد بر مبنای فولدرها کار میکند و با گشودن یک پوشه در آن (با کلیک بر روی دکمهی open folder آن)، امکان کار کردن با آن پوشه و فایلهای موجود در آن را خواهیم یافت.
نکتهی مهم اینجا است که پس از نصب VS Code، برای فایلهای با پسوند ts بلافاصله Intellisense مرتبط نیز مهیا است و نیاز به هیچگونه تنظیم اضافهتری ندارد. همچنین قابلیتهای type safety این زبان نیز در این ادیتور به نحو واضحی مشخص هستند:
در ادامه ابتدا یک پوشهی جدید خالی را ایجاد کنید و سپس این پوشه را در VS Code باز نمائید (از طریق منوی فایل، گزینهی گشودن پوشه). سپس ماوس را بر روی نام این پوشه حرکت دهید:
همانطور که مشاهده میکنید، دکمهی new file ظاهر میشود. در اینجا میتوانید فایل جدیدی را به نام test.ts اضافه کنید.
در ادامه با فشردن دکمههای ctrl+shift+p، امکان انتخاب یک task runner را جهت کامپایل فایلهای ts خواهیم داشت:
در اینجا ابتدا عبارت task< را وارد کنید و سپس از منوی باز شده، گزینهی rub build task را انتخاب کنید:
پس از آن، در بالای صفحه مشاهده خواهید کرد که عنوان شده: «هنوز هیچ task runner ایی برای اینکار تنظیم نشدهاست»
برای این منظور بر روی دکمهی configure task runner تصویر فوق که با رنگ آبی مشخص شدهاست، کلیک کنید. به این ترتیب یک فایل جدید به نام task.json ایجاد میشود که در پوشهای به نام vscode. در ریشهی پروژه (یا همان پوشهی جاری) قرار میگیرد:
فایل task.json دارای تعاریفی است که کامپایلر TypeScript یا همان tsc را فعال میکند:
محتوای پیش فرض و ابتدایی این فایل را در قطعه کد فوق مشاهده میکنید. این فایل json را جهت تنظیمات کامپایلر TypeScript پروژهی جاری، ویرایش خواهیم کرد. در این فایل دکمهی ctrl+space را بفشارید. بلافاصله منوی تکمیل کنندهی این فایل ظاهر میشود. از ترکیب ctrl+space در قسمتهای مختلف این فایل جهت دریافت توصیههای بیشتری نیز میتوان استفاده کرد.
در اینجا قسمتی که نیاز به تنظیم دارد، خاصیت args است. مقادیر آن، پارامترهایی هستند که به کامپایلر typescript ارسال میشوند. برای نمونه آنرا به صورت ذیل تغییر دهید:
پارامتر و سوئیچ target مشخص میکند که خروجی تولیدی باید با فرمت ES 5 باشد. همچنین فایلهای js تولیدی را در پوشهی js در ریشهی پروژه یا پوشهی جاری قرار دهد. پارامتر sourceMap مشخص میکند که علاوه بر فایلهای js، فایلهای map که بیانگر نگاشت بین فایلهای ts و js هستند نیز تولید شوند. این فایلها برای دیباگ برنامه بسیار مفید هستند. پارامتر watch، کلیهی تغییرات پوشهی جاری را تحت نظر قرار داده و به صورت خودکار کار کامپایل را انجام میدهد. در آخر نیز فایل و یا فایلهای ts مدنظر ذکر میشوند.
برای اجرای کامپایلر، ابتدا از منوی view گزینهی toggle output را انتخاب کنید تا بتوان خروجی نهایی کامپایلر را مشاهده کرد. سپس گزینهی view->command pallet و اجرا tasks< را انتخاب کنید. در ادامه همانند مرحلهی قبل، یعنی گزینهی run build task را اجرا کنید (که خلاصهی این عملیات ctrl+shift+B است).
به این ترتیب پوشهی js که در خاصیت args مشخص کردیم، تولید میشود:
البته این خطا هم در قسمت output نمایش داده میشود:
علت اینجا است که در تنظیمات فوق، خاصیت command به tsc تنظیم شدهاست و همانطور که در کامنت آن عنوان شدهاست، کامپایلر typescript را از طریق دستور npm install -g typescript دریافت میکند و نیازی به ذکر مسیر آن در اینجا نیست. بنابراین لازم است تا با npm و نصب typescript از طریق آن آشنا شد و به این ترتیب کامپایلر آنرا به روز کرد تا دستور watch را شناسایی کند.
نصب TypeScript از طریق npm
همانطور که عنوان شد، TypeScript چندسکویی است و این مورد را از طریق npm یا NodeJS package manager انجام میدهد. برای این منظور به آدرس https://nodejs.org/en مراجعه کرده و فایل نصاب آنرا مخصوص سیستم عامل خود دریافت و سپس نصب کنید. Node.js یک runtime سمت سرور اجرای برنامههای جاوا اسکریپتی است. از آنجائیکه TypeScript در نهایت به JavaScript تبدیل میشود، استفاده از node.js انتخاب مناسبی جهت اجرا و توزیع آن در تمام سیستم عاملها بودهاست.
پس از نصب node.js، از package manager آن که npm نام دارد، جهت نصب TypeScript استفاده میشود. چون node.js به Path و مسیرهای اصلی ویندوز اضافه میشود، تنها کافی است دستور npm install -g typescript را در خط فرمان صادر کنید. در اینجا سوئیچ g به معنای global و دسترسی عمومی است.
همانطور که در این تصویر مشخص است، پس از صدور دستور نصب TypeScript، نگارش 1.8.9 آن نصب شدهاست. اما زمانیکه کامپایلر tsc را با پارامتر version اجرا میکنیم، شماره نگارش قدیمی 1.0.3.0 را نمایش میدهد. برای رفع این مشکل به مسیر C:\Program Files (x86)\Microsoft SDKs\TypeScript مراجعه کرده و پوشهی 1.0 را به 1.0-old تغییر نام دهید.
اکنون اگر مجددا بررسی کنیم، نگارش صحیح قابل مشاهده است:
پس از این تغییرات اگر مجددا به VS Code باز گردیم و ctrl+shift+B را صادر کنیم (جهت اجرای مجدد task runner و اجرای tsc تنظیم شده) ، پیام ذیل مشاهده میشود:
به این معنا که اینبار پارامتر watch را شناسایی کردهاست و دیگر از کامپایلر قدیمی tsc استفاده نمیکند. برای آزمایش آن، از منوی view گزینهی split editor را انتخاب کنید و سپس در سمت چپ فایل test.ts و در سمت راست، فایل test.js کامپایل شده را باز کنید:
در اینجا چون پارامتر watch فعال شدهاست، هر تغییری که در فایل ts داده شود، بلافاصله کامپایل شده و در فایل js منعکس خواهد شد.
تنظیم VS Code جهت دیباگ کدهای TypeScript
در نوار ابزار کنار صفحهی VS Code، بر روی دکمهی دیباگ کلیک کنید:
سپس بر روی دکمهی چرخدندهی موجود که کار انجام تنظیمات را توسط آن میتوان ادامه داد، کلیک کنید. بلافاصله منویی ظاهر میشود که درخواست انتخاب محیط دیباگ را دارد:
در اینجا node.js را انتخاب کنید. با اینکار فایل جدیدی دیگری به نام launch.json به پوشهی vscode. اضافه میشود. اگر به این فایل دقت کنید دو خاصیت name به نامهای Launch و Attach در آن موجود هستند. این نامها در یک دراپ داون، در کنار دکمهی start دیباگ نیز ظاهر میشوند:
- در فایل launch.json، باید خاصیت "program": "${workspaceRoot}/app.js" را ویرایش کرد و app.js آنرا به test.ts مثال جاری تغییر داد.
- سپس خاصیت "sourceMaps" آن نیز باید تغییر کرده و جهت استفادهی از source mapهای تولیدی به true تنظیم شود.
- در آخر باید مسیر پوشهی خروجی js را نیز تنظیم کرد: "outDir": "${workspaceRoot}/js"
همچنین باید دقت داشت چون externalConsole به false تنظیم شدهاست، خروجی این کنسول به output ویژوال استودیوکد منتقل میشود.
اکنون اگر بر روی دکمهی سبز رنگ start کلیک کنید (دکمهی F5)، امکان دیباگ سطر به سطر کد TypeScript را خواهید یافت:
فایلهای نهایی json یاد شدهی در متن را از اینجا میتوانید دریافت کنید:
VSCodeTypeScript.zip
- TypeScript زبان توصیه شدهی توسعهی برنامههای AngularJS 2 است و همچنین با سایر کتابخانههای معروف جاوا اسکریپتی مانند ReactJS و jQuery نیز سازگاری دارد. بنابراین اگر قصد دارید به AngularJS 2 مهاجرت کنید، اکنون فرصت خوبی است تا زبان TypeScript را نیز بیاموزید. همچنین WinJS نیز با TypeScript نوشته شدهاست.
- superset زبان JavaScript بودن به این معنا است که تمام کدهای جاوا اسکریپتی موجود، به عنوان کد معتبر TypeScript نیز شناخته میشوند و همین مساله مهاجرت به آنرا سادهتر میکند. زبانهای دیگری مانند Dart و یا CoffeeScript ، نسبت به JavaScript بسیار متفاوت به نظر میرسند؛ اما Syntax زبان TypeScript شباهت بسیار زیادی به جاوا اسکریپت و خصوصا ES 6 دارد. در اینجا تنها کافی است پسوند فایلهای js را به ts تغییر دهید و از آنها به عنوان کدهای معتبر TypeScript استفاده کنید.
- strong typing و معرفی نوعها، کدهای نهایی نوشته شده را امنتر میکنند. به این ترتیب کامپایلر، پیش از اینکه کدهای شما در زمان اجرا به خطا بر بخورند، در زمان کامپایل، مشکلات موجود را گوشزد میکند. همچنین وجود نوعها، سرعت توسعه را با بهبود ابزارهای مرتبط با برنامه نویسی، افزایش میدهند؛ از این جهت که مفهوم مهمی مانند Intellisense، با وجود نوعها، پیشنهادهای بهتر و دقیقتری را ارائه میدهد. همچنین ابزارهای Refactoring نیز در صورت وجود نوعها بهتر و دقیقتر عمل میکنند. این موارد مهمترین دلایل طراحی TypeScript جهت توسعه و نگهداری برنامههای بزرگ نوشته شدهی با JavaScript هستند.
- Syntax زبان TypeScript به شدت الهام گرفته شده از زبان سیشارپ است. به همین جهت اگر با این زبان آشنایی دارید، درک مفاهیم TypeScript برایتان بسیار ساده خواهد بود.
- بهترین قسمت TypeScript، کامپایل شدن آن به ES 5 است (به این عملیات Transpile هم میگویند). در زبان TypeScript به تمام امکانات پیشرفتهی ES 6 مانند کلاسها و ماژولها دسترسی دارید، اما کد نهایی را که تولید میکند، میتواند ES 5 ایی باشد که هم اکنون تمام مرورگرهای عمده آنرا پشتیبانی میکنند. با تنظیمات کامپایلر TypeScript، امکان تولید کدهای ES 3 تا ES 5 و همچنین ES 6 نیز وجود دارد. نمونهی آنلاین این ترجمه را در TypeScript playground میتوانید مشاهده کنید.
- TypeScript چندسکویی است. امکانات و کامپایلر این زبان، برای ویندوز، مک و لینوکس طراحی شدهاند.
- TypeScript سورس باز است. طراحان اصلی آن، همان طراحان زبان سیشارپ در مایکروسافت هستند و هم اکنون این زبان به صورت سورس باز توسط این شرکت توسعه داده شده و در GitHub نگهداری میشود.
آماده سازی محیطهای کار با TypeScript
برای کار با TypeScript، یک ادیتور متنی ساده، به همراه کامپایلر آن کفایت میکند. اما همانطور که عنوان شد، یکی از مهمترین دلایل وجودی TypeScript، بهبود ابزارهای برنامه نویسی مرتبط با JavaScript است و اگر قرار باشد صرفا از یک ادیتور متنی ساده استفاده شود، فلسفهی وجودی آن زیر سؤال میرود.
نصب TypeScript در ویژوال استودیو
در نگارشهای جدید ویژوال استودیو، از VS 2013 Update 2 به بعد، قسمت ویژهی TypeScript نیز قابل مشاهدهاست. البته این قسمت با به روز رسانیهای TypeScript، نیاز به به روز رسانی دارد. به همین جهت به سایت رسمی آن مراجعه کرده و بستههای جدید مخصوص VS 2013 و یا 2015 آنرا دریافت و نصب کنید.
همچنین افزونهی Web Essentials نیز امکانات بیشتری را جهت کار با TypeScript به همراه دارد و امکان مشاهدهی خروجی جاوا اسکریپت تولیدی را در حین کار با فایل TypeScript فعلی میسر میکند. در سمت چپ صفحه TypeScript را خواهید نوشت و در سمت راست، خروجی JavaScript نهایی را بلافاصله مشاهده میکنید.
تصویر فوق مربوط به VS 2015 است. همچنین گزینهی افزودن یک فایل و آیتم جدید نیز امکان افزودن فایلهای TS را به همراه دارد.
نصب و تنظیم TypeScript در ویژوال استودیو کد
ویژوال استودیو کد، نگارش رایگان، سورس باز و چندسکویی ویژوال استودیو است که بر روی ویندوز، مک و لینوکس قابل اجرا است. ویژوال استودیو کد نیز به همراه پشتیبانی بسیار خوبی از TypeScript است، تا حدی که تمام ارائههای معرفی Anugular 2 توسط تیم مربوطهی آن از گوگل، توسط ویژوال استودیو کد و یکپارچگی آن با TypeScript انجام شدند.
ویژوال استودیو کد بر مبنای فولدرها کار میکند و با گشودن یک پوشه در آن (با کلیک بر روی دکمهی open folder آن)، امکان کار کردن با آن پوشه و فایلهای موجود در آن را خواهیم یافت.
نکتهی مهم اینجا است که پس از نصب VS Code، برای فایلهای با پسوند ts بلافاصله Intellisense مرتبط نیز مهیا است و نیاز به هیچگونه تنظیم اضافهتری ندارد. همچنین قابلیتهای type safety این زبان نیز در این ادیتور به نحو واضحی مشخص هستند:
در ادامه ابتدا یک پوشهی جدید خالی را ایجاد کنید و سپس این پوشه را در VS Code باز نمائید (از طریق منوی فایل، گزینهی گشودن پوشه). سپس ماوس را بر روی نام این پوشه حرکت دهید:
همانطور که مشاهده میکنید، دکمهی new file ظاهر میشود. در اینجا میتوانید فایل جدیدی را به نام test.ts اضافه کنید.
در ادامه با فشردن دکمههای ctrl+shift+p، امکان انتخاب یک task runner را جهت کامپایل فایلهای ts خواهیم داشت:
در اینجا ابتدا عبارت task< را وارد کنید و سپس از منوی باز شده، گزینهی rub build task را انتخاب کنید:
پس از آن، در بالای صفحه مشاهده خواهید کرد که عنوان شده: «هنوز هیچ task runner ایی برای اینکار تنظیم نشدهاست»
برای این منظور بر روی دکمهی configure task runner تصویر فوق که با رنگ آبی مشخص شدهاست، کلیک کنید. به این ترتیب یک فایل جدید به نام task.json ایجاد میشود که در پوشهای به نام vscode. در ریشهی پروژه (یا همان پوشهی جاری) قرار میگیرد:
فایل task.json دارای تعاریفی است که کامپایلر TypeScript یا همان tsc را فعال میکند:
{ "version": "0.1.0", // The command is tsc. Assumes that tsc has been installed using npm install -g typescript "command": "tsc", // The command is a shell script "isShellCommand": true, // Show the output window only if unrecognized errors occur. "showOutput": "silent", // args is the HelloWorld program to compile. "args": ["HelloWorld.ts"], // use the standard tsc problem matcher to find compile problems // in the output. "problemMatcher": "$tsc" }
در اینجا قسمتی که نیاز به تنظیم دارد، خاصیت args است. مقادیر آن، پارامترهایی هستند که به کامپایلر typescript ارسال میشوند. برای نمونه آنرا به صورت ذیل تغییر دهید:
"args": [ "--target", "ES5", "--outdir", "js", "--sourceMap", "--watch", "test.ts" ],
برای اجرای کامپایلر، ابتدا از منوی view گزینهی toggle output را انتخاب کنید تا بتوان خروجی نهایی کامپایلر را مشاهده کرد. سپس گزینهی view->command pallet و اجرا tasks< را انتخاب کنید. در ادامه همانند مرحلهی قبل، یعنی گزینهی run build task را اجرا کنید (که خلاصهی این عملیات ctrl+shift+B است).
به این ترتیب پوشهی js که در خاصیت args مشخص کردیم، تولید میشود:
البته این خطا هم در قسمت output نمایش داده میشود:
error TS5023: Unknown option 'watch' Use the '--help' flag to see options.
علت اینجا است که در تنظیمات فوق، خاصیت command به tsc تنظیم شدهاست و همانطور که در کامنت آن عنوان شدهاست، کامپایلر typescript را از طریق دستور npm install -g typescript دریافت میکند و نیازی به ذکر مسیر آن در اینجا نیست. بنابراین لازم است تا با npm و نصب typescript از طریق آن آشنا شد و به این ترتیب کامپایلر آنرا به روز کرد تا دستور watch را شناسایی کند.
نصب TypeScript از طریق npm
همانطور که عنوان شد، TypeScript چندسکویی است و این مورد را از طریق npm یا NodeJS package manager انجام میدهد. برای این منظور به آدرس https://nodejs.org/en مراجعه کرده و فایل نصاب آنرا مخصوص سیستم عامل خود دریافت و سپس نصب کنید. Node.js یک runtime سمت سرور اجرای برنامههای جاوا اسکریپتی است. از آنجائیکه TypeScript در نهایت به JavaScript تبدیل میشود، استفاده از node.js انتخاب مناسبی جهت اجرا و توزیع آن در تمام سیستم عاملها بودهاست.
پس از نصب node.js، از package manager آن که npm نام دارد، جهت نصب TypeScript استفاده میشود. چون node.js به Path و مسیرهای اصلی ویندوز اضافه میشود، تنها کافی است دستور npm install -g typescript را در خط فرمان صادر کنید. در اینجا سوئیچ g به معنای global و دسترسی عمومی است.
همانطور که در این تصویر مشخص است، پس از صدور دستور نصب TypeScript، نگارش 1.8.9 آن نصب شدهاست. اما زمانیکه کامپایلر tsc را با پارامتر version اجرا میکنیم، شماره نگارش قدیمی 1.0.3.0 را نمایش میدهد. برای رفع این مشکل به مسیر C:\Program Files (x86)\Microsoft SDKs\TypeScript مراجعه کرده و پوشهی 1.0 را به 1.0-old تغییر نام دهید.
اکنون اگر مجددا بررسی کنیم، نگارش صحیح قابل مشاهده است:
پس از این تغییرات اگر مجددا به VS Code باز گردیم و ctrl+shift+B را صادر کنیم (جهت اجرای مجدد task runner و اجرای tsc تنظیم شده) ، پیام ذیل مشاهده میشود:
15:33:52 - Compilation complete. Watching for file changes.
در اینجا چون پارامتر watch فعال شدهاست، هر تغییری که در فایل ts داده شود، بلافاصله کامپایل شده و در فایل js منعکس خواهد شد.
تنظیم VS Code جهت دیباگ کدهای TypeScript
در نوار ابزار کنار صفحهی VS Code، بر روی دکمهی دیباگ کلیک کنید:
سپس بر روی دکمهی چرخدندهی موجود که کار انجام تنظیمات را توسط آن میتوان ادامه داد، کلیک کنید. بلافاصله منویی ظاهر میشود که درخواست انتخاب محیط دیباگ را دارد:
در اینجا node.js را انتخاب کنید. با اینکار فایل جدیدی دیگری به نام launch.json به پوشهی vscode. اضافه میشود. اگر به این فایل دقت کنید دو خاصیت name به نامهای Launch و Attach در آن موجود هستند. این نامها در یک دراپ داون، در کنار دکمهی start دیباگ نیز ظاهر میشوند:
- در فایل launch.json، باید خاصیت "program": "${workspaceRoot}/app.js" را ویرایش کرد و app.js آنرا به test.ts مثال جاری تغییر داد.
- سپس خاصیت "sourceMaps" آن نیز باید تغییر کرده و جهت استفادهی از source mapهای تولیدی به true تنظیم شود.
- در آخر باید مسیر پوشهی خروجی js را نیز تنظیم کرد: "outDir": "${workspaceRoot}/js"
همچنین باید دقت داشت چون externalConsole به false تنظیم شدهاست، خروجی این کنسول به output ویژوال استودیوکد منتقل میشود.
اکنون اگر بر روی دکمهی سبز رنگ start کلیک کنید (دکمهی F5)، امکان دیباگ سطر به سطر کد TypeScript را خواهید یافت:
فایلهای نهایی json یاد شدهی در متن را از اینجا میتوانید دریافت کنید:
VSCodeTypeScript.zip
امروزه در بسیاری از محیطهای برنامه نویسی جاوا و اندروید، استفاده از این سیستم رایج است. ولی هنوز دیده میشود عدهای نسبت به آن دید روشنی ندارند و برای آنها ناشناخته است و در حد یک سیستم کانفیگ آن را میشناسند. در این مقاله قصد داریم که مفهوم روشنتری از این سیستم را داشته باشم و بدانیم هدف آن چیست و چگونه کار میکند تا از این به بعد دیگر آن را به چشم یک کانفیگ کنندهی ساده نگاه نکنیم. قبل از هر چیزی بهتر است که با تعدادی از اصطلاحات آن آشنا شویم تا در متن مقاله به مشکل برنخوریم:
DSL یا Domain Specific languages به معنی زبانهایی با دامنه محدود است که برای اهداف خاصی نوشته میشوند و تنها بر روی یک جنبه از هدف تمرکز دارند. این زبانها به شما اجازه نمیدهند که یک برنامه را به طور کامل با آن بنویسید. بلکه به شما اجازه میدهند به هدفی که برای آن نوشته شدهاند، برسید. یکی از این زبانها همان css هست که با آن کار میکنید. این زبان به صورت محدود تنها بر روی یک جنبه و آن، تزئین سازی المانهای وب، تمرکز دارد. در وقع مثل زبان سی شارپ همه منظوره نیست و محدودهای مشخص برای خود دارد. به این نوع از زبانهای DSL، نوع اکسترنال هم میگویند. چون زبانی مستقل برای خود است و به زبان دیگری وابستگی ندارد. ولی در یک زبان اینترنال، وابستگی به زبان دیگری وجود دارد. مثل Fluent Interfaceها که به ما شیوه آسانی از دسترسی به جنبههای یک شیء را میدهد. برای آشنایی هر چه بیشتر با این زبانها و ساختار آن، کتاب Domain Specific languages نوشته آقای مارتین فاولر توصیه میشود.
Groovy یک زبان شیء گرای DSL هست که برای پلتفرم جاوا ساخته شده است. برای اطلاعات بیشتر در مورد این زبان، صفحه ویکی ، میتواند مفید واقع شود.
از دیرباز سیستمهای Ant و Maven وجود داشتند و کار آنها اتوماسیون بعضی اعمال بود. ولی بعد از مدتی سیستم Gradle یا جمع کردن نقاط قوت آنها و افزودن ویژگیهای قدرتمندتری به خود، پا به میدان گذاشت تا راحتی بیشتری را برای برنامه نویس فراهم کند. از ویژگیهای گریدل میتوان داشتن زبان گرووی اشاره کرده که قدرت بیشتری را نسبت به سایر سیستمها داشت و مزیت مهم دیگر این بود که انعطاف بالایی را جهت افزودن پلاگینها داشت و گوگل با استفاده از این قابلیت، پشتیبانی از گریدل را در اندروید استادیو نیز گنجاند تا راحتی بیشتری را در اتوماسیون وظایف سیستمی ایجاد کند. در واقع آنچه شما در سیستم گریدل کار میکنید و اطلاعات خود را با آن کانفیگ میکنید، پلاگینی است که از سمت گوگل در اختیار شما قرار گرفته است و در مواقع خاص این وظایف توسط پلاگینها اجرا میشوند.
گریدل به راحتی از سایت رسمی آن قابل دریافت است و میتوان آن را در پروژههای جاوایی که مدنظر شماست، دریافت کنید و با استفاده از خط فرمان، با آن تعامل کنید. هر چند امروزه اکثر ویراستارهای جاوا از آن پشتیبانی میکنند.
گریدل یک ماهیت توصیفی دارد که شما تنها لازم است اعمالی را برای آن توصیف کنید تا بقیه کارها را انجام دهد. گریدل در پشت صحنه از یک "گراف جهت دار بدون دور" Directed Acycllic Graph یا به اختصار DAG استفاده میکند و طبق آن ترتیب وظایف یا taskها را دانسته و آنها را اجرا میکند. گریدل با این DAG، سه فاز آماده سازی، پیکربندی و اجرا را انجام میدهد.
در این فایل سه پروژه برای گریدل مشخص شدهاند. البته از نگاه Intellij سه ماژول معرفی شدهاند و این فایل برای یک پروژه اختیاری است. گریدل برای پیدا کردن این فایل، از الگوریتمهای متفاوتی استفاده میکند.
الان پروژه dbutiilities در سطح بالاتری از دایرکتوری جاری قرار گرفته است.
در کلوژر buildscript مخازنی را که کتابخانههای نامبرده (وابستگی ها) در این کلوژ قرار میگیرند، معرفی میکنیم. در کلوژر بعدی تنظمیاتی را که برای همه پروژهها اعمال میشوند، انجام میدهیم که در آن به معرفی مخزن jcenter پرداختیم. کتابخانهای که در کلوژر buildscript صدا زدیم، همان پلاگینی است که گوگل برای گریدل منتشر کرده که ما به آن ابزار بیلد میگوییم. حال به سراغ دیگر فایلهای منحصر به فرد هر پروژه بروید. در این فایلها، شما تنظیمات پیشفرضی را میبینید که یکی از آنها نسخه بندی پروژه است. پروژههای وابستهای را که از مخازن باید دریافت شوند، شامل میشود و بسیاری از گزینههای دیگری که برای شما مهیا شده است تا در فاز پیکربندی، وظایف را بسازید.
در مرحله اجرا هم این وظایف را اجرا میکنیم. تمامی این سه عملیات توسط فایل و دستوری به نام gradlew که برگرفته از gradleWrapper میباشد انجام میشود. اگر در ترمینال اندروید استادیو این عبارت را تایپ کنید، میتوانید در ادامه دستور پیامهای مربوط به این عملیات را ببینید و ترتیب اجرای فازها را مشاهده کنید.
بیایید یک task را تعریف کنیم
در ابتدا عبارت task را به عنوان معرفی task میآوریم و سپس نام آن را وارد میکنیم. بعد از آن ما از عبارتهای شیفت چپ>> استفاده کردیم. این عبارت شیفت چپ به این معناست که تسک مربوطه را آخر از همه وظایف اجرا کن که این عمل از طریق اجرای متدی به نام doLast صورت میگیرد. اگر در ترمینال اندروید عبارت زیر را تایپ کنید، متن مورد نظر باید نمایش یابد:
برای نمایش اطلاعات بیشتر میتوانید از فلگ info هم استفاده کنید:
حال شاید بگویید من در بعضی از سایتها یا مستندات و یا پروژههای دیگر دیدهام که عبارت >> را قرار نمیدهند. در این مورد باید گفت که آنها در واقع تسکهای اجرایی نیستند و برای پیکربندی به کار میروند و در فاز پیکربندی هم اجرا میشوند که در ادامه نمونه آن را خواهیم دید.
اگر بخواهید خودتان دستی یک تسک پیکربندی را به یک تسک اجرایی تبدیل کنید، میتوانید متد doLast را صدا بزنید. کد زیر را توسط gradlew اجرا کنید؛ به همراه اطلاعات verbose تا ببینید که هر کدام از پیامها در کدام بخش چاپ میشوند. پیام اول در فاز پیکربندی و پیام دوم در فاز اجرایی چاپ میشوند.
یکی از کارهایی که در یک تسک میتوانید انجام دهید این است که آن را به یک تسک دیگر وابسته کنید. به عنوان مثال ما قصد داریم بعد از تسک mytask1، تسک my task2 اجرا شود و زمان پایان تسک mytask1 را در خروجی نمایش دهیم. برای اینکار باید بین تسکها یک وابستگی ایجاد شود و سپس با متد doLast کد خودمان را اجرایی نماییم. البته توجه داشته باشید که این وابستگیها تنها به تسکهای داخل فایل گریدل انجام میشود و نه تسکهای پلاگینها یا وابستگی هایی که تعریف میکنیم.
سپس تسک شماره دو را صدا میزنیم. در اینجا جون تسک شماره دو به تسک شماره یک وابسته است، ابتدا تسک شماره یک اجرا شده و سپس نوبت تسک شماره دو میشود.
خروجی کار:
در گریدل مخالف doLast یعنی doFirst را نیز داریم ولی عملگر جایگزینی برای آن وجود ندارد و مستقیما باید آن را پیاده سازی کنید. خود گریدل به طور پیش فرض نیز تسکهای آماده ای نیز دارد که میتوانید در مستندات آن بیابید. به عنوان مثال یکی از تسکهای مفید و کاربردی آن تسک کپی کردن هست که از طریق آن میتوانید فایلی یا فایلهایی را از یک مسیر به مسیر دیگر کپی کنید. برای استفاده از چنین تسکهایی، باید تسکهای خود را به شکل زیر به شیوه اکشن بنویسید:
در تسک بالا بعد از اجرای تسک شماره یک، آخرین کاری که انجام میشود این است که فایلهای apk موجود در زیر دایرکتوریهای مسیر from به ریشه اصلی کپی خواهند شد. پس همانطور که میبینید گریدل به راحتی عملیات اتوماسیون را انجام میدهد.
برای نمایش تسکهای موجود میتوانید از گریدل درخواست کنید که لیست تمامی تسکهای موجود را به شما نشان دهد. برای اینکار میتوانید دستور زیر را صدا کنید:
بعد از مدتی تمامی تسکهای موجود به صورت گروه بندی نمایش داده شده و تسکهایی که شما جدیدا اضافه کردید را با عنوان other tasks نمایش خواهد داد:
اگر به تسکهای خود گریدل نگاه کنید برای هر کدام توضیحی هم وجود دارد؛ اگر شما هم قصد دارید توضیحی اضافه کنید از خصوصیت description استفاده کنید:
یکبار دیگر دستور نمایش تسکها را صدا بزنید تا اینبار توضیح اضافه شده نمایش داده شود.
یکی دیگر از نکات جالب در مورد گریدل این است که میتواند برای شما callback ارسال کند. بدین صورت که اگر اتفاقی خاصی افتاد، تسک خاصی را اجرا کند. به عنوان مثال ما در کد پایین تسکی را ایجاد کردهایم که به ما این اجازه را میدهد، هر موقع تسکی در مرحله پیکربندی به بیلد اضافه میشود، تسک ما هم اجرا شود و نام تسک اضافه شده به بیلد را چاپ میکند.
گریدل امکانات دیگری چون بررسی استثناءها و ایجاد استثناءها را هم پوشش میدهد که میتوانید در این صفحه آن را پیگیری کنید.
Gradle Wrapper
گریدل در حال حاضر مرتبا در حال تغییر و به روز رسانی است و اگر بخواهیم مستقیما با گریدل کار کنیم ممکن است که به مشکلاتی که در نسخه بندی است برخورد کنیم. از آنجا که هر پروژهای که روی سیستم شما قرار بگیرد از نسخهای متفاوتی از گریدل استفاده کند، باعث میشود که نتوانید نسخه مناسبی از گریدل را برای سیستم خود دانلود کنید. بدین جهت wrapper ایجاد شد تا دیگر نیازی به نصب گریدل پیدا نکنید. wrapper در هر پروژه میداند که که به چه نسخهای از گریدل نیاز است. پس موقعی که شما دستور gradlew را صدا میزنید در ویندوز فایل gradlew.bat صدا زده شده و یا در لینوکس و مک فایل شِل اسکریپت gradlew صدا زده میشود و wrapper به خوبی میداند که به چه نسخهای از گریدل برای اجرا نیاز دارد و آن را از طریق دانلود فراهم میکند. اگر همینک دایرکتوری والد پروژه اندرویدی خود را نگاه کنید میتوانید این دو فایل را ببینید.
از آنجا که خود اندروید استادیو به ساخت wrapper اقدام میکند، شما راحت هستید. ولی اگر دوست دارید خودتان برای پروژهای wrapper تولید کنید، مراحل زیر را دنبال کنید:
برای ایجاد wrapper توسط خودتان باید گریدل را دانلود و روی سیستم نصب کنید و سپس دستور زیر را صادر کنید:
دستور بالا یک wrapper برای نسخه 2.4 ایجاد میکند.
اگر میخواهید ببینید wrapper که اندروید استادیو شما دارد چه نسخه از گردیل را صدا میزند مسیر را از دایرکتوری پروژه دنبال کنید و فایل زیر را بگشایید:
هنگامی که گوگل قصد آپدیت نسخه گریدل شما را بکند این فایل را باز کرده و نسخه داخل آن را ویرایش میکند.
اینها فقط مختصراتی از آشنایی با نحوه عملکر گریدل برای داشتن دیدی روشنتر نسبت به آن بود. برای آشنایی بیشتر با گریدل، باید مستندات رسمی آن را دنبال کنید.
DSL یا Domain Specific languages به معنی زبانهایی با دامنه محدود است که برای اهداف خاصی نوشته میشوند و تنها بر روی یک جنبه از هدف تمرکز دارند. این زبانها به شما اجازه نمیدهند که یک برنامه را به طور کامل با آن بنویسید. بلکه به شما اجازه میدهند به هدفی که برای آن نوشته شدهاند، برسید. یکی از این زبانها همان css هست که با آن کار میکنید. این زبان به صورت محدود تنها بر روی یک جنبه و آن، تزئین سازی المانهای وب، تمرکز دارد. در وقع مثل زبان سی شارپ همه منظوره نیست و محدودهای مشخص برای خود دارد. به این نوع از زبانهای DSL، نوع اکسترنال هم میگویند. چون زبانی مستقل برای خود است و به زبان دیگری وابستگی ندارد. ولی در یک زبان اینترنال، وابستگی به زبان دیگری وجود دارد. مثل Fluent Interfaceها که به ما شیوه آسانی از دسترسی به جنبههای یک شیء را میدهد. برای آشنایی هر چه بیشتر با این زبانها و ساختار آن، کتاب Domain Specific languages نوشته آقای مارتین فاولر توصیه میشود.
Groovy یک زبان شیء گرای DSL هست که برای پلتفرم جاوا ساخته شده است. برای اطلاعات بیشتر در مورد این زبان، صفحه ویکی ، میتواند مفید واقع شود.
از دیرباز سیستمهای Ant و Maven وجود داشتند و کار آنها اتوماسیون بعضی اعمال بود. ولی بعد از مدتی سیستم Gradle یا جمع کردن نقاط قوت آنها و افزودن ویژگیهای قدرتمندتری به خود، پا به میدان گذاشت تا راحتی بیشتری را برای برنامه نویس فراهم کند. از ویژگیهای گریدل میتوان داشتن زبان گرووی اشاره کرده که قدرت بیشتری را نسبت به سایر سیستمها داشت و مزیت مهم دیگر این بود که انعطاف بالایی را جهت افزودن پلاگینها داشت و گوگل با استفاده از این قابلیت، پشتیبانی از گریدل را در اندروید استادیو نیز گنجاند تا راحتی بیشتری را در اتوماسیون وظایف سیستمی ایجاد کند. در واقع آنچه شما در سیستم گریدل کار میکنید و اطلاعات خود را با آن کانفیگ میکنید، پلاگینی است که از سمت گوگل در اختیار شما قرار گرفته است و در مواقع خاص این وظایف توسط پلاگینها اجرا میشوند.
گریدل به راحتی از سایت رسمی آن قابل دریافت است و میتوان آن را در پروژههای جاوایی که مدنظر شماست، دریافت کنید و با استفاده از خط فرمان، با آن تعامل کنید. هر چند امروزه اکثر ویراستارهای جاوا از آن پشتیبانی میکنند.
گریدل یک ماهیت توصیفی دارد که شما تنها لازم است اعمالی را برای آن توصیف کنید تا بقیه کارها را انجام دهد. گریدل در پشت صحنه از یک "گراف جهت دار بدون دور" Directed Acycllic Graph یا به اختصار DAG استفاده میکند و طبق آن ترتیب وظایف یا taskها را دانسته و آنها را اجرا میکند. گریدل با این DAG، سه فاز آماده سازی، پیکربندی و اجرا را انجام میدهد.
- در مرحله آماده سازی ما به گریدل میگوییم چه پروژه یا پروژههایی نیاز به بیلد شدن دارند. در اندروید استادیو، این مرحله در فایل settings.gradle انجام میشود؛ شما در این فایل مشخص میکنید چه پروژههای نیاز به بیلد شدن توسط گریدل دارند. ساختار این فایل به این شکل است:
include ':ActiveAndroid-master', ':app', ':dbutilities'
-
در اولین مرحله انتظار دارد که فایل settings در دایرکتوری جاری باشد و اگر آن را پیدا کرد آن را مورد استفاده قرار میدهد؛ در غیر اینصورت مرحله بعدی را آغاز میکند.
- در مرحله دوم، در این دایرکتوری به دنبال دایرکتوری به نام master میگردد و اگر در آن هم یافت نکرد مرحله سوم را آغاز میکند.
- در مرحله سوم، جست و جو در دایرکتوری والد انجام میشود
- چنانچه این فایل را در هیچ یک از احتمالات بالا نیابد، همین پروژه جاری را تشخیص خواهد داد.
include ':ActiveAndroid-master', ':app', ':dbutilities' project('dbutilities').projectDir=new File(settingsDir,'../dir1/dir2');
-
در مرحله پیکربندی، وظایف یا taskها را معرفی میکنیم. این عمل پیکربندی توسط فایل build.gradle که برای پروژه اصلی و هر زیر پروژهای که مشخص شدهاند، صورت میگیرد. در این فایل شما میتوانید خواص و متدهایی را تعریف و و ظایفی را مشخص کنید.
در پروژه اصلی، فایل BuildGradle شامل خطوط زیر است:
buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.5.0' } } allprojects { repositories { jcenter() } }
در مرحله اجرا هم این وظایف را اجرا میکنیم. تمامی این سه عملیات توسط فایل و دستوری به نام gradlew که برگرفته از gradleWrapper میباشد انجام میشود. اگر در ترمینال اندروید استادیو این عبارت را تایپ کنید، میتوانید در ادامه دستور پیامهای مربوط به این عملیات را ببینید و ترتیب اجرای فازها را مشاهده کنید.
بیایید یک task را تعریف کنیم
task mytask <<{ println ".net tips task in config phase" }
gradlew mytask
gradlew --info mytask
اگر بخواهید خودتان دستی یک تسک پیکربندی را به یک تسک اجرایی تبدیل کنید، میتوانید متد doLast را صدا بزنید. کد زیر را توسط gradlew اجرا کنید؛ به همراه اطلاعات verbose تا ببینید که هر کدام از پیامها در کدام بخش چاپ میشوند. پیام اول در فاز پیکربندی و پیام دوم در فاز اجرایی چاپ میشوند.
task mytask { println ".net tips task in config phase" doLast{ println ".net tips task in exe phase" } }
یکی از کارهایی که در یک تسک میتوانید انجام دهید این است که آن را به یک تسک دیگر وابسته کنید. به عنوان مثال ما قصد داریم بعد از تسک mytask1، تسک my task2 اجرا شود و زمان پایان تسک mytask1 را در خروجی نمایش دهیم. برای اینکار باید بین تسکها یک وابستگی ایجاد شود و سپس با متد doLast کد خودمان را اجرایی نماییم. البته توجه داشته باشید که این وابستگیها تنها به تسکهای داخل فایل گریدل انجام میشود و نه تسکهای پلاگینها یا وابستگی هایی که تعریف میکنیم.
task mytask1 << { println ".net tips is the best" } task mytask2() { dependsOn mytask1 doLast{ Date time=Calendar.getInstance().getTime(); SimpleDateFormat formatter=new SimpleDateFormat("HH:mm:ss , YYYY/MM/dd"); println "mytask1 is done at " + formatter.format(time); } }
gradlew --info mytask2
Executing task ':app:mytask1' (up-to-date check took 0.003 secs) due to: Task has not declared any outputs. خروجی تسک شماره یک .net tips is the best :app:mytask1 (Thread[main,5,main]) completed. Took 0.046 secs. :app:mytask2 (Thread[main,5,main]) started. :app:mytask2 Executing task ':app:mytask2' (up-to-date check took 0.0 secs) due to: Task has not declared any outputs. خروجی تسک شماره دو mytask1 is done at 04:03:09 , 2016/07/07 :app:mytask2 (Thread[main,5,main]) completed. Took 0.075 secs. BUILD SUCCESSFUL
در گریدل مخالف doLast یعنی doFirst را نیز داریم ولی عملگر جایگزینی برای آن وجود ندارد و مستقیما باید آن را پیاده سازی کنید. خود گریدل به طور پیش فرض نیز تسکهای آماده ای نیز دارد که میتوانید در مستندات آن بیابید. به عنوان مثال یکی از تسکهای مفید و کاربردی آن تسک کپی کردن هست که از طریق آن میتوانید فایلی یا فایلهایی را از یک مسیر به مسیر دیگر کپی کنید. برای استفاده از چنین تسکهایی، باید تسکهای خود را به شکل زیر به شیوه اکشن بنویسید:
task mytask(type:Copy) { dependsOn mytask1 doLast{ from('build/apk') { include '**/*.apk' } into '.' } }
برای نمایش تسکهای موجود میتوانید از گریدل درخواست کنید که لیست تمامی تسکهای موجود را به شما نشان دهد. برای اینکار میتوانید دستور زیر را صدا کنید:
gradlew --info tasks
Other tasks ----------- clean jarDebugClasses jarReleaseClasses mytask mytask2 transformResourcesWithMergeJavaResForDebugUnitTest transformResourcesWithMergeJavaResForReleaseUnitTest
task mytask(type:Copy) { description "copy apk files to root directory" dependsOn mytask1 doLast{ from('build/apk') { include '**/*.apk' } into '.' } }
یکی دیگر از نکات جالب در مورد گریدل این است که میتواند برای شما callback ارسال کند. بدین صورت که اگر اتفاقی خاصی افتاد، تسک خاصی را اجرا کند. به عنوان مثال ما در کد پایین تسکی را ایجاد کردهایم که به ما این اجازه را میدهد، هر موقع تسکی در مرحله پیکربندی به بیلد اضافه میشود، تسک ما هم اجرا شود و نام تسک اضافه شده به بیلد را چاپ میکند.
tasks.whenTaskAdded{ task-> println "task is added $task.name" }
گریدل امکانات دیگری چون بررسی استثناءها و ایجاد استثناءها را هم پوشش میدهد که میتوانید در این صفحه آن را پیگیری کنید.
Gradle Wrapper
گریدل در حال حاضر مرتبا در حال تغییر و به روز رسانی است و اگر بخواهیم مستقیما با گریدل کار کنیم ممکن است که به مشکلاتی که در نسخه بندی است برخورد کنیم. از آنجا که هر پروژهای که روی سیستم شما قرار بگیرد از نسخهای متفاوتی از گریدل استفاده کند، باعث میشود که نتوانید نسخه مناسبی از گریدل را برای سیستم خود دانلود کنید. بدین جهت wrapper ایجاد شد تا دیگر نیازی به نصب گریدل پیدا نکنید. wrapper در هر پروژه میداند که که به چه نسخهای از گریدل نیاز است. پس موقعی که شما دستور gradlew را صدا میزنید در ویندوز فایل gradlew.bat صدا زده شده و یا در لینوکس و مک فایل شِل اسکریپت gradlew صدا زده میشود و wrapper به خوبی میداند که به چه نسخهای از گریدل برای اجرا نیاز دارد و آن را از طریق دانلود فراهم میکند. اگر همینک دایرکتوری والد پروژه اندرویدی خود را نگاه کنید میتوانید این دو فایل را ببینید.
از آنجا که خود اندروید استادیو به ساخت wrapper اقدام میکند، شما راحت هستید. ولی اگر دوست دارید خودتان برای پروژهای wrapper تولید کنید، مراحل زیر را دنبال کنید:
برای ایجاد wrapper توسط خودتان باید گریدل را دانلود و روی سیستم نصب کنید و سپس دستور زیر را صادر کنید:
gradle wrapper --gradle-version 2.4
اگر میخواهید ببینید wrapper که اندروید استادیو شما دارد چه نسخه از گردیل را صدا میزند مسیر را از دایرکتوری پروژه دنبال کنید و فایل زیر را بگشایید:
\gradle\wrapper\gradle-wrapper.properties
اینها فقط مختصراتی از آشنایی با نحوه عملکر گریدل برای داشتن دیدی روشنتر نسبت به آن بود. برای آشنایی بیشتر با گریدل، باید مستندات رسمی آن را دنبال کنید.
در این مطلب مثالی را در مورد نحوهی تنظیمات یک پروژهی خالی ASP.NET Core، جهت استفادهی از یک پروژهی Angular CLI قرار گرفتهی در پوشهی آنرا بررسی خواهیم کرد.
پیشنیازها
- مطالعهی سری کار با Angular CLI خصوصا قسمت نصب و قسمت ساخت برنامههای آن، پیش از مطالعهی این مطلب ضروری است.
- همچنین فرض بر این است که سری ASP.NET Core را نیز یکبار مرور کردهاید و با نحوهی برپایی یک برنامهی MVC آن و ارائهی فایلهای استاتیک توسط یک پروژهی ASP.NET Core آشنایی دارید.
ایجاد یک پروژهی جدید ASP.NET Core در VS 2017
در ابتدا یک پروژهی خالی ASP.NET Core را در VS 2017 ایجاد خواهیم کرد. برای این منظور:
- ابتدا از طریق منوی File -> New -> Project (Ctrl+Shift+N) گزینهی ایجاد یک ASP.NET Core Web application را انتخاب کنید.
- در صفحهی بعدی آن هم گزینهی «empty template» را انتخاب نمائید.
تنظیمات یک برنامهی ASP.NET Core خالی برای اجرای یک برنامهی Angular CLI
برای اجرای یک برنامهی مبتنی بر Angular CLI، نیاز است بر روی فایل csproj برنامهی ASP.NET Core کلیک راست کرده و گزینهی Edit آنرا انتخاب کنید.
سپس محتوای این فایل را به نحو ذیل تکمیل نمائید:
الف) درخواست عدم کامپایل فایلهای TypeScript
چون نحوهی کامپایل پروژههای Angular CLI صرفا مبتنی بر کامپایل مستقیم فایلهای TypeScript آن نیست و در اینجا از یک گردش کاری توکار مبتنی بر webpack، به صورت خودکار استفاده میکند، کامپایل فایلهای TypeScript توسط ویژوال استودیو، مفید نبوده و صرفا سبب دریافت گزارشهای خطای بیشماری به همراه کند کردن پروسهی Build آن خواهد شد. بنابراین با افزودن تنظیم TypeScriptCompileBlocked به true، از VS 2017 خواهیم خواست تا در این زمینه دخالت نکند.
ب) مشخص کردن پوشههایی که باید الحاق و یا حذف شوند
در اینجا پوشههای کنترلرها و wwwroot به پروژه الحاق شدهاند. پوشهی wwwroot جایی است که فایلهایی خروجی را Angular CLI ارائه خواهد کرد.
سپس دو پوشهی node_modules و src واقع در ریشهی پروژه را نیز به طور کامل از سیستم ساخت و توزیع VS 2017 حذف کردهایم. پوشهی node_modules وابستگیهای Angular را به همراه دارد و src همان پوشهی برنامهی Angular ما خواهد بود.
ج) افزودن وابستگیهای سمت سرور مورد نیاز
برای اجرای یک برنامهی تک صفحهای وب Angular، صرفا به وابستگی MVC و StaticFiles آن نیاز است.
در اینجا Watcher.Tools هم به همراه تنظیمات آن اضافه شدهاند که در ادامهی بحث به آن اشاره خواهد شد.
افزودن یک کنترلر Web API جدید
با توجه به اینکه دیگر در اینجا قرار نیست با فایلهای cshtml و razor کار کنیم، کنترلرهای ما نیز از نوع Web API خواهند بود. البته در ASP.NET Core، کنترلرهای معمولی آن، توانایی ارائهی Web API و همچنین فایلهای Razor را دارند و از این لحاظ تفاوتی بین این دو نیست و یکپارچگی کاملی صورت گرفتهاست.
در اینجا کدهای یک کنترلر نمونه را جهت بازگشت یک خروجی JSON ساده مشاهده میکنید که در ادامه، در برنامهی Angular CLI تهیه شده از آن استفاده خواهیم کرد.
تنظیمات فایل آغازین یک برنامهی ASP.NET Core جهت ارائهی برنامههای Angular
در ادامه به فایل Startup.cs برنامهی خالی جاری، مراجعه کرده و آنرا به نحو ذیل تغییر دهید:
در اینجا برای ارائهی کنترلر Web API، نیاز به ثبت سرویسهای MVC است. همچنین ارائهی فایلهای پیش فرض و فایلهای استاتیک (همان پوشهی wwwroot برنامه) نیز فعال شدهاند.
در قسمت app.Use آن، تنظیمات URL Rewriting مورد نیاز جهت کار با مسیریابی برنامههای Angular را مشاهده میکنید. برای نمونه اگر کاربری در ابتدای کار آدرس /products را درخواست کند، این درخواست به سمت سرور ارسال میشود و چون چنین صفحهای در سمت سرور وجود ندارد، خطای 404 بازگشت داده میشود و کار به پردازش برنامهی Angular نخواهد رسید. اینجا است که تنظیم میانافزار فوق، کار مدیریت خروجیهای 404 را بر عهده گرفته و کاربر را به فایل index.html برنامهی تک صفحهای وب، هدایت میکند. به علاوه در اینجا اگر درخواست وارد شده، دارای پسوند باشد (یک فایل باشد) و یا با api/ شروع شود (اشاره کنندهی به کنترلرهای Web API برنامه)، از این پردازش و هدایت به صفحهی index.html معاف خواهد شد.
ایجاد ساختار اولیهی برنامهی Angular CLI در داخل پروژهی جاری
اکنون از طریق خط فرمان به پوشهی ریشهی برنامهی ASP.NET Core، جائیکه فایل Startup.cs قرار دارد، وارد شده و دستور ذیل را اجرا کنید:
به این ترتیب پوشهی جدید ClientApp، در داخل پوشهی برنامه اضافه خواهد شد که در آن تنظیمات اولیهی مسیریابی Angular نیز انجام شدهاست؛ از دریافت وابستگیهای npm آن صرفنظر شده و همچنین کار تنظیمات git آن نیز صورت نگرفتهاست (تا از تنظیمات git پروژهی اصلی استفاده شود).
پس از تولید ساختار برنامهی Angular CLI، به پوشهی آن وارد شده و تمام فایلهای آن را Cut کنید. سپس به پوشهی ریشهی برنامهی ASP.NET Core جاری، وارد شده و این فایلها را در آنجا paste نمائید. به این ترتیب به حداکثر سازگاری ساختار پروژههای Angular CLI و VS 2017 خواهیم رسید. زیرا اکثر فایلهای تنظیمات آنرا میشناسد و قابلیت پردازش آنها را دارد.
پس از این cut/paste، پوشهی خالی ClientApp را نیز حذف کنید.
تنظیم محل خروجی نهایی Angular CLI به پوشهی wwwroot
برای اینکه سیستم Build پروژهی Angular CLI جاری، خروجی خود را در پوشهی wwwroot قرار دهد، تنها کافی است فایل .angular-cli.json را گشوده و outDir آنرا به wwwroot تنظیم کنیم:
به این ترتیب پس از هر بار build آن، فایلهای index.html و تمام فایلهای js نهایی، در پوشهی wwwroot که در فایل Startup.cs، کار عمومی کردن آن انجام شد، تولید میشوند.
فراخوانی کنترلر Web API برنامه در برنامهی Angular CLI
در ادامه صرفا جهت آزمایش برنامه، فایل src\app\app.component.ts را گشوده و به نحو ذیل تکمیل کنید:
در اینجا خروجی JSON کنترلر Web API برنامه دریافت شده و به آرایهی apiValues انتساب داده میشود.
سپس این آرایه را در فایل قالب این کامپوننت (src\app\app.component.html) استفاده خواهیم کرد:
در اینجا یک حلقه ایجاد شده و عناصر آرایهی apiValues به صورت یک لیست نمایش داده میشوند.
نصب وابستگیهای برنامهی Angular CLI
در ابتدای ایجاد پوشهی ClientApp، از پرچم skip-install استفاده شد، تا صرفا ساختار پروژه، جهت cut/paste آن با سرعت هر چه تمامتر، ایجاد شود. اکنون برای نصب وابستگیهای آن یا میتوان در solution explorer به گره dependencies مراجعه کرده و npm را انتخاب کرد. در ادامه با کلیک راست بر روی آن، گزینهی restore packages ظاهر میشود. و یا میتوان به روش متداول این نوع پروژهها، از طریق خط فرمان به پوشهی ریشهی پروژه وارد شد و دستور npm install را صادر کرد. بهتر است اینکار را از طریق خط فرمان انجام دهید تا مطمئن شوید که از آخرین نگارشهای این ابزار که بر روی سیستم نصب شدهاست، استفاده میکنید.
روش اول اجرای برنامههای مبتنی بر ASP.NET Core و Angular CLI
تا اینجا اگر برنامه را از طریق VS 2017 اجرا کنید، خروجی را مشاهده نخواهید کرد. چون هنوز فایل index.html آن تولید نشدهاست.
بنابراین روش اول اجرای این نوع برنامهها، شامل مراحل ذیل است:
الف) ساخت پروژهی Angular CLI در حالت watch
برای اجرای آن از طریق خط فرمان، به پوشهی ریشهی پروژه وارد شده و دستور فوق را وارد کنید. به این ترتیب کار build پروژه انجام شده و همچنین فایلهای نهایی آن در پوشهی wwwroot قرار میگیرند. به علاوه چون از پرچم watch استفاده شدهاست، با هر تغییری در پوشهی src برنامه، این فایلها به صورت خودکار به روز رسانی میشوند. بنابراین این پنجرهی خط فرمان را باید باز نگه داشت تا watcher آن بتواند کارش را به صورت مداوم انجام دهد.
ب) اجرای برنامه از طریق ویژوال استودیو
اکنون که کار ایجاد محتوای پوشهی wwwroot برنامه انجام شدهاست، میتوان برنامه را از طریق VS 2017 به روش متداولی اجرا کرد:
یک نکته: میتوان قسمت الف را تبدیل به یک Post Build Event هم کرد. برای این منظور باید فایل csproj را به نحو ذیل تکمیل کرد:
به این ترتیب با هربار Build پروژه در VS 2017، کار تولید مجدد محتوای پوشهی wwwroot نیز انجام خواهد شد.
تنها مشکل روش Post Build Event، کند بودن آن است. زمانیکه از روش ng build --watch به صورت مستقل استفاده میشود، برای بار اول اجرا، اندکی زمان خواهد برد؛ اما اعمال تغییرات بعدی به آن بسیار سریع هستند. چون صرفا نیاز دارد این تغییرات اندک و تدریجی را کامپایل کند و نه کامپایل کل پروژه را از ابتدا.
روش دوم اجرای برنامههای مبتنی بر ASP.NET Core و Angular CLI
روش دومی که در اینجا بررسی خواهد شد، مستقل است از قسمت «ب» روش اول که توضیح داده شد. برنامههای NET Core. نیز به همراه CLI خاص خودشان هستند و نیازی نیست تا حتما از VS 2017 برای اجرای آنها استفاده کرد. به همین جهت وابستگی Microsoft.DotNet.Watcher.Tools را نیز در ابتدای کار به وابستگیهای برنامه اضافه کردیم.
الف) در ادامه، VS 2017 را به طور کامل ببندید؛ چون نیازی به آن نیست. سپس دستور ذیل را در خط فرمان، در ریشهی پروژه، صادر کنید:
این دستور پروژهی ASP.NET Core را کامپایل کرده و بر روی پورت 5000 ارائه میدهد:
به علاوه پارامتر watch آن سبب خواهد شد تا هر تغییری که در کدهای پروژهی ASP.NET Core صورت گیرند، بلافاصله کامپایل شده و قابل استفاده شوند.
ب) در اینجا چون برنامه بر روی پورت 5000 ارائه شدهاست، بهتر است دستور ng serve -o را صادر کرد تا بتوان به نحو سادهتری از سرور وب ASP.NET Core استفاده نمود. در این حالت برنامهی Angular CLI بر روی پورت 4200 ارائه شده و بلافاصله در مرورگر نیز نمایش داده میشود.
مشکل! سرور وب ما بر روی پورت 5000 است و سرور آزمایشی Angular CLI بر روی پورت 4200. اکنون برنامهی Angular ما، یک چنین درخواستهایی را به سمت سرور، جهت دریافت اطلاعات ارسال میکند: localhost:4200/api
برای رفع این مشکل میتوان فایلی را به نام proxy.config.json با محتویات ذیل ایجاد کرد:
سپس دستور ng server صادر شده، اندکی متفاوت خواهد شد:
در اینجا به ng serve اعلام کردهایم که تمامی درخواستهای ارسالی به مسیر api/ (و یا همان localhost:4200/api جاری) را به سرور وب ASP.NET Core، بر روی پورت 5000 ارسال کن و نتیجه را در همینجا بازگشت بده. به این ترتیب مشکل عدم دسترسی به سرور وب، جهت تامین اطلاعات برطرف خواهد شد.
مزیت این روش، به روز رسانی خودکار مرورگر با انجام هر تغییری در کدهای قسمت Angular برنامه است.
نکته 1: بدیهی است میتوان قسمت «ب» روش دوم را با قسمت «الف» روش اول نیز جایگزین کرد (ساخت پروژهی Angular CLI در حالت watch). اینبار گشودن مرورگر بر روی پورت 5000 (و یا آدرس http://localhost:5000) را باید به صورت دستی انجام دهید. همچنین هربار تغییر در کدهای Angular، سبب refresh خودکار مرورگر نیز نمیشود که آنرا نیز باید خودتان به صورت دستی انجام دهید (کلیک بر روی دکمهی refresh پس از هر بار پایان کار ng build).
نکته 2: میتوان قسمت «الف» روش دوم را حذف کرد (حذف dotnet run در حالت watch). یعنی میخواهیم هنوز هم ویژوال استودیو کار آغاز IIS Express را انجام دهد. به علاوه میخواهیم برنامه را توسط ng serve مشاهده کنیم (با همان پارامترهای قسمت «ب» روش دوم). در این حالت تنها موردی را که باید تغییر دهید، پورتی است که برای IIS Express تنظیم شدهاست. عدد این پورت را میتوان در فایل Properties\launchSettings.json مشاهده کرد و سپس به تنظیمات فایل proxy.config.json اعمال نمود.
کدهای کامل این مطلب را از اینجا میتوانید دریافت کنید: ASPNETCoreIntegrationWithAngularCLI.zip
به همراه این کدها تعدادی فایل bat نیز وجود دارند که جهت ساده سازی عملیات یاد شدهی در این مطلب، میتوان از آنها استفاده کرد:
- فایل restore.bat کار بازیابی و نصب وابستگیهای پروژهی دات نتی و همچنین Angular CLI را انجام میدهد.
- دو فایل ng-build-dev.bat و ng-build-prod.bat بیانگر قسمت «الف» روش اول هستند. فایل dev مخصوص حالت توسعه است و فایل prod مخصوص ارائهی نهایی.
- دو فایل dotnet_run.bat و ng-serve-proxy.bat خلاصه کنندهی قسمتهای «الف» و «ب» روش دوم هستند.
پیشنیازها
- مطالعهی سری کار با Angular CLI خصوصا قسمت نصب و قسمت ساخت برنامههای آن، پیش از مطالعهی این مطلب ضروری است.
- همچنین فرض بر این است که سری ASP.NET Core را نیز یکبار مرور کردهاید و با نحوهی برپایی یک برنامهی MVC آن و ارائهی فایلهای استاتیک توسط یک پروژهی ASP.NET Core آشنایی دارید.
ایجاد یک پروژهی جدید ASP.NET Core در VS 2017
در ابتدا یک پروژهی خالی ASP.NET Core را در VS 2017 ایجاد خواهیم کرد. برای این منظور:
- ابتدا از طریق منوی File -> New -> Project (Ctrl+Shift+N) گزینهی ایجاد یک ASP.NET Core Web application را انتخاب کنید.
- در صفحهی بعدی آن هم گزینهی «empty template» را انتخاب نمائید.
تنظیمات یک برنامهی ASP.NET Core خالی برای اجرای یک برنامهی Angular CLI
برای اجرای یک برنامهی مبتنی بر Angular CLI، نیاز است بر روی فایل csproj برنامهی ASP.NET Core کلیک راست کرده و گزینهی Edit آنرا انتخاب کنید.
سپس محتوای این فایل را به نحو ذیل تکمیل نمائید:
الف) درخواست عدم کامپایل فایلهای TypeScript
<PropertyGroup> <TargetFramework>netcoreapp1.1</TargetFramework> <TypeScriptCompileBlocked>true</TypeScriptCompileBlocked> </PropertyGroup>
ب) مشخص کردن پوشههایی که باید الحاق و یا حذف شوند
<ItemGroup> <Folder Include="Controllers\" /> <Folder Include="wwwroot\" /> </ItemGroup> <ItemGroup> <Compile Remove="node_modules\**" /> <Content Remove="node_modules\**" /> <EmbeddedResource Remove="node_modules\**" /> <None Remove="node_modules\**" /> </ItemGroup> <ItemGroup> <Compile Remove="src\**" /> <Content Remove="src\**" /> <EmbeddedResource Remove="src\**" /> </ItemGroup>
سپس دو پوشهی node_modules و src واقع در ریشهی پروژه را نیز به طور کامل از سیستم ساخت و توزیع VS 2017 حذف کردهایم. پوشهی node_modules وابستگیهای Angular را به همراه دارد و src همان پوشهی برنامهی Angular ما خواهد بود.
ج) افزودن وابستگیهای سمت سرور مورد نیاز
<ItemGroup> <PackageReference Include="Microsoft.AspNetCore" Version="1.1.1" /> <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" /> <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.1" /> </ItemGroup> <ItemGroup> <DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="1.0.0" /> </ItemGroup> <ItemGroup> <!-- extends watching group to include *.js files --> <Watch Include="**\*.js" Exclude="node_modules\**\*;**\*.js.map;obj\**\*;bin\**\*" /> </ItemGroup>
در اینجا Watcher.Tools هم به همراه تنظیمات آن اضافه شدهاند که در ادامهی بحث به آن اشاره خواهد شد.
افزودن یک کنترلر Web API جدید
با توجه به اینکه دیگر در اینجا قرار نیست با فایلهای cshtml و razor کار کنیم، کنترلرهای ما نیز از نوع Web API خواهند بود. البته در ASP.NET Core، کنترلرهای معمولی آن، توانایی ارائهی Web API و همچنین فایلهای Razor را دارند و از این لحاظ تفاوتی بین این دو نیست و یکپارچگی کاملی صورت گرفتهاست.
using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; namespace ASPNETCoreIntegrationWithAngularCLI.Controllers { [Route("api/[controller]")] public class ValuesController : Controller { // GET: api/values [HttpGet] [ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)] public IEnumerable<string> Get() { return new string[] { "Hello", "DNT" }; } } }
تنظیمات فایل آغازین یک برنامهی ASP.NET Core جهت ارائهی برنامههای Angular
در ادامه به فایل Startup.cs برنامهی خالی جاری، مراجعه کرده و آنرا به نحو ذیل تغییر دهید:
using System; using System.IO; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace ASPNETCoreIntegrationWithAngularCLI { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.Use(async (context, next) => { await next(); if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value) && !context.Request.Path.Value.StartsWith("/api/", StringComparison.OrdinalIgnoreCase)) { context.Request.Path = "/index.html"; await next(); } }); app.UseMvcWithDefaultRoute(); app.UseDefaultFiles(); app.UseStaticFiles(); } } }
در قسمت app.Use آن، تنظیمات URL Rewriting مورد نیاز جهت کار با مسیریابی برنامههای Angular را مشاهده میکنید. برای نمونه اگر کاربری در ابتدای کار آدرس /products را درخواست کند، این درخواست به سمت سرور ارسال میشود و چون چنین صفحهای در سمت سرور وجود ندارد، خطای 404 بازگشت داده میشود و کار به پردازش برنامهی Angular نخواهد رسید. اینجا است که تنظیم میانافزار فوق، کار مدیریت خروجیهای 404 را بر عهده گرفته و کاربر را به فایل index.html برنامهی تک صفحهای وب، هدایت میکند. به علاوه در اینجا اگر درخواست وارد شده، دارای پسوند باشد (یک فایل باشد) و یا با api/ شروع شود (اشاره کنندهی به کنترلرهای Web API برنامه)، از این پردازش و هدایت به صفحهی index.html معاف خواهد شد.
ایجاد ساختار اولیهی برنامهی Angular CLI در داخل پروژهی جاری
اکنون از طریق خط فرمان به پوشهی ریشهی برنامهی ASP.NET Core، جائیکه فایل Startup.cs قرار دارد، وارد شده و دستور ذیل را اجرا کنید:
>ng new ClientApp --routing --skip-install --skip-git --skip-commit
پس از تولید ساختار برنامهی Angular CLI، به پوشهی آن وارد شده و تمام فایلهای آن را Cut کنید. سپس به پوشهی ریشهی برنامهی ASP.NET Core جاری، وارد شده و این فایلها را در آنجا paste نمائید. به این ترتیب به حداکثر سازگاری ساختار پروژههای Angular CLI و VS 2017 خواهیم رسید. زیرا اکثر فایلهای تنظیمات آنرا میشناسد و قابلیت پردازش آنها را دارد.
پس از این cut/paste، پوشهی خالی ClientApp را نیز حذف کنید.
تنظیم محل خروجی نهایی Angular CLI به پوشهی wwwroot
برای اینکه سیستم Build پروژهی Angular CLI جاری، خروجی خود را در پوشهی wwwroot قرار دهد، تنها کافی است فایل .angular-cli.json را گشوده و outDir آنرا به wwwroot تنظیم کنیم:
"apps": [ { "root": "src", "outDir": "wwwroot",
فراخوانی کنترلر Web API برنامه در برنامهی Angular CLI
در ادامه صرفا جهت آزمایش برنامه، فایل src\app\app.component.ts را گشوده و به نحو ذیل تکمیل کنید:
import { Component, OnInit } from '@angular/core'; import { Http } from '@angular/http'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { constructor(private _httpService: Http) { } apiValues: string[] = []; ngOnInit() { this._httpService.get('/api/values').subscribe(values => { this.apiValues = values.json() as string[]; }); } }
سپس این آرایه را در فایل قالب این کامپوننت (src\app\app.component.html) استفاده خواهیم کرد:
<h1>Application says:</h1> <ul *ngFor="let value of apiValues"> <li>{{value}}</li> </ul> <router-outlet></router-outlet>
نصب وابستگیهای برنامهی Angular CLI
در ابتدای ایجاد پوشهی ClientApp، از پرچم skip-install استفاده شد، تا صرفا ساختار پروژه، جهت cut/paste آن با سرعت هر چه تمامتر، ایجاد شود. اکنون برای نصب وابستگیهای آن یا میتوان در solution explorer به گره dependencies مراجعه کرده و npm را انتخاب کرد. در ادامه با کلیک راست بر روی آن، گزینهی restore packages ظاهر میشود. و یا میتوان به روش متداول این نوع پروژهها، از طریق خط فرمان به پوشهی ریشهی پروژه وارد شد و دستور npm install را صادر کرد. بهتر است اینکار را از طریق خط فرمان انجام دهید تا مطمئن شوید که از آخرین نگارشهای این ابزار که بر روی سیستم نصب شدهاست، استفاده میکنید.
روش اول اجرای برنامههای مبتنی بر ASP.NET Core و Angular CLI
تا اینجا اگر برنامه را از طریق VS 2017 اجرا کنید، خروجی را مشاهده نخواهید کرد. چون هنوز فایل index.html آن تولید نشدهاست.
بنابراین روش اول اجرای این نوع برنامهها، شامل مراحل ذیل است:
الف) ساخت پروژهی Angular CLI در حالت watch
> ng build --watch
ب) اجرای برنامه از طریق ویژوال استودیو
اکنون که کار ایجاد محتوای پوشهی wwwroot برنامه انجام شدهاست، میتوان برنامه را از طریق VS 2017 به روش متداولی اجرا کرد:
یک نکته: میتوان قسمت الف را تبدیل به یک Post Build Event هم کرد. برای این منظور باید فایل csproj را به نحو ذیل تکمیل کرد:
<Target Name="AngularBuild" AfterTargets="Build"> <Exec Command="ng build" /> </Target>
تنها مشکل روش Post Build Event، کند بودن آن است. زمانیکه از روش ng build --watch به صورت مستقل استفاده میشود، برای بار اول اجرا، اندکی زمان خواهد برد؛ اما اعمال تغییرات بعدی به آن بسیار سریع هستند. چون صرفا نیاز دارد این تغییرات اندک و تدریجی را کامپایل کند و نه کامپایل کل پروژه را از ابتدا.
روش دوم اجرای برنامههای مبتنی بر ASP.NET Core و Angular CLI
روش دومی که در اینجا بررسی خواهد شد، مستقل است از قسمت «ب» روش اول که توضیح داده شد. برنامههای NET Core. نیز به همراه CLI خاص خودشان هستند و نیازی نیست تا حتما از VS 2017 برای اجرای آنها استفاده کرد. به همین جهت وابستگی Microsoft.DotNet.Watcher.Tools را نیز در ابتدای کار به وابستگیهای برنامه اضافه کردیم.
الف) در ادامه، VS 2017 را به طور کامل ببندید؛ چون نیازی به آن نیست. سپس دستور ذیل را در خط فرمان، در ریشهی پروژه، صادر کنید:
> dotnet watch run
>dotnet watch run [90mwatch : [39mStarted Hosting environment: Production Now listening on: http://localhost:5000 Application started. Press Ctrl+C to shut down.
ب) در اینجا چون برنامه بر روی پورت 5000 ارائه شدهاست، بهتر است دستور ng serve -o را صادر کرد تا بتوان به نحو سادهتری از سرور وب ASP.NET Core استفاده نمود. در این حالت برنامهی Angular CLI بر روی پورت 4200 ارائه شده و بلافاصله در مرورگر نیز نمایش داده میشود.
مشکل! سرور وب ما بر روی پورت 5000 است و سرور آزمایشی Angular CLI بر روی پورت 4200. اکنون برنامهی Angular ما، یک چنین درخواستهایی را به سمت سرور، جهت دریافت اطلاعات ارسال میکند: localhost:4200/api
برای رفع این مشکل میتوان فایلی را به نام proxy.config.json با محتویات ذیل ایجاد کرد:
{ "/api": { "target": "http://localhost:5000", "secure": false } }
>ng serve --proxy-config proxy.config.json -o
مزیت این روش، به روز رسانی خودکار مرورگر با انجام هر تغییری در کدهای قسمت Angular برنامه است.
نکته 1: بدیهی است میتوان قسمت «ب» روش دوم را با قسمت «الف» روش اول نیز جایگزین کرد (ساخت پروژهی Angular CLI در حالت watch). اینبار گشودن مرورگر بر روی پورت 5000 (و یا آدرس http://localhost:5000) را باید به صورت دستی انجام دهید. همچنین هربار تغییر در کدهای Angular، سبب refresh خودکار مرورگر نیز نمیشود که آنرا نیز باید خودتان به صورت دستی انجام دهید (کلیک بر روی دکمهی refresh پس از هر بار پایان کار ng build).
نکته 2: میتوان قسمت «الف» روش دوم را حذف کرد (حذف dotnet run در حالت watch). یعنی میخواهیم هنوز هم ویژوال استودیو کار آغاز IIS Express را انجام دهد. به علاوه میخواهیم برنامه را توسط ng serve مشاهده کنیم (با همان پارامترهای قسمت «ب» روش دوم). در این حالت تنها موردی را که باید تغییر دهید، پورتی است که برای IIS Express تنظیم شدهاست. عدد این پورت را میتوان در فایل Properties\launchSettings.json مشاهده کرد و سپس به تنظیمات فایل proxy.config.json اعمال نمود.
کدهای کامل این مطلب را از اینجا میتوانید دریافت کنید: ASPNETCoreIntegrationWithAngularCLI.zip
به همراه این کدها تعدادی فایل bat نیز وجود دارند که جهت ساده سازی عملیات یاد شدهی در این مطلب، میتوان از آنها استفاده کرد:
- فایل restore.bat کار بازیابی و نصب وابستگیهای پروژهی دات نتی و همچنین Angular CLI را انجام میدهد.
- دو فایل ng-build-dev.bat و ng-build-prod.bat بیانگر قسمت «الف» روش اول هستند. فایل dev مخصوص حالت توسعه است و فایل prod مخصوص ارائهی نهایی.
- دو فایل dotnet_run.bat و ng-serve-proxy.bat خلاصه کنندهی قسمتهای «الف» و «ب» روش دوم هستند.
هنگامیکه از روش AOP استفاده میکنیم گاهی نیاز است متد تزیینشده را از متدی درون خود کلاس فراخوانی کنیم و میخواهیم aspectهای آن متد نیز فراخوانی شوند.
آمادهسازی Interceptor
معرفی Interceptor به سیستم
پیشنیاز: دورهی AOP
(برای سادگی کار از تعریف attribute خودداری کردم. شما میتوانید با توجه به آموزش، attributeهای دلخواه را به متدها بیافزایید).
Interface و کلاس پیادهسازیشدهی آن در لایه سرویس:
public interface IMyService { void foo(); void bar(); } public class MyService : IMyService { public void foo() { Console.Write("foo"); bar(); } public void bar() { Console.Write("bar"); } }
نام متد در خروجی نوشته میشود. همچنین میخواهیم پیش از فراخوانی این متدها، متنی در خروجی نوشته شود.
یک interceptor ساده که نام متد را در خروجی مینویسد.
//using Castle.DynamicProxy; public class Interceptor : IInterceptor { public void Intercept(IInvocation invocation) { Console.WriteLine("Intercepted: " + invocation.Method.Name); invocation.Proceed(); } }
همانند قبل:
//using System; //using Castle.DynamicProxy; //using StructureMap; class Program { static void Main(string[] args) { ObjectFactory.Initialize(x => { var dynamicProxy = new ProxyGenerator(); x.For<IMyService>() .EnrichAllWith(myTypeInterface => dynamicProxy.CreateInterfaceProxyWithTarget(myTypeInterface, new Intercept())) .Use<MyService>(); }); var myService = ObjectFactory.GetInstance<IMyService>(); myService.foo(); } }
انتظار ما این است که خروجی زیر تولید شود:
Intercepted foo foo Intercepted bar bar
اما نتیجه این میشود که دلخواه ما نیست:
Intercepted foo foo bar
راهحل
برای حل این مشکل دو کار باید انجام داد:
1- متد تزیینشده باید virtual باشد.
public class MyService : IMyService { public virtual void foo() { Console.Write("foo"); bar(); } public virtual void bar() { Console.Write("foo"); bar(); } }
2- شیوه معرفی متد به سیستم باید به روش زیر باشد:
// جایگزین روش پیشین در متد Main x.For<IMyService>() .EnrichAllWith(myTypeInterface => dynamicProxy.CreateClassProxy<MyService>(new Intercept())) .Use<MyService>();
دلیل این مسئله به دو روش proxy برمیگردد که برای اطلاع بیشتر به مستندات پروژه Castle مراجعه کنید.
در اینجا روش Inheritance-based به کار رفته است. در این روش، تنها متدهای virtual را میتوان intercept کرد. در روش پیشین(Composition-based) برای همهی متدها عملیات intercept انجام میشد (کلاس proxy پیادهسازیشدهی interface ما بود) که در اینجا اینگونه نیست و میتواند به سرعت برنامه کمک کند.
اشتراکها