در مطلب «
Angular CLI - قسمت پنجم - ساخت و توزیع برنامه» با نحوهی ساخت و توزیع برنامههای Angular، در دو حالت محیط توسعه و محیط ارائهی نهایی آشنا شدیم. همچنین در مطلب «
یکپارچه سازی Angular CLI و ASP.NET Core در VS 2017» نحوهی ترکیب یک برنامهی ASP.NET Core و Angular را بررسی کردیم. در اینجا میخواهیم فایل index.html ایی را که Angular CLI تولید میکند، با فایل Layout برنامههای ASP.NET Core جایگزین کنیم؛ تا بتوانیم در صورت نیاز، سفارشی سازیهای بیشتری را به صفحهی اول سایت اعمال نمائیم.
استفاده از Tag Helpers ویژهی ASP.NET Core برای مدیریت محیطهای توسعه و تولید
فایلهای برنامهی تک صفحهای تولید شدهی توسط Angular CLI، در نهایت یک چنین شکلی را خواهند داشت:
این فایلها نیز در حالت توسعه تهیه شدهاند. در یک برنامهی واقعی، صفحهی سادهی index.html تولیدی آن، تنها میتواند یک قالب شروع به کار باشد و نه فایل نهایی که قرار است ارائه شود. نیاز است به این فایل تگهای بیشتری را اضافه کرد و سفارشی سازیهای خاصی را به آن اعمال نمود. در این حالت با توجه به بازنویسی و تولید مجدد این فایل در هر بار ساخت برنامه، میتوان از فایل Layout پروژهی ASP.NET Core جاری استفاده کرد. به این ترتیب از مزایای Razor و تمام زیرساختی که در اختیار داریم نیز محروم نخواهیم شد.
بنابراین تنها کاری را که باید انجام دهیم، کپی ساختار فایل index.html تولیدی به فایل Layout برنامه است.
مشکل! در حالت توسعه، نام فایلهای تولید شده به همین سادگی است که ملاحظه میکنید. اما در حالت ارائهی نهایی، این فایلها به همراه یک هش نیز تولید میشوند (پیاده سازی مفهوم cache busting و اجبار به بهروز رسانی کش مرورگر، باتوجه به تغییر آدرس فایلها)؛ مانند vendor.
ea3f8329096dbf5632af.bundle.js
راه حل اول: تولید فایلهای نهایی بدون هش ng build -prod --output-hashing=none
در حین ساخت و تولید یک برنامهی Angular CLI در حالت ارائهی نهایی، تنها کافی است سوئیچ output-hashing، به none تنظیم شود، تا این هشها به نام فایلهای تولیدی اضافه نشوند.
درکل بهتر است از این روش استفاده نشود، چون با وجود پروکسیهای کش کردن اطلاعات در بین راه، احتمال اینکه کاربران نگارشهای قدیمی برنامه را مشاهده کنند، بسیار زیاد است.
راه حل دوم: تگ Script در ASP.NET Core اجازهی ذکر تمام فایلهای اسکریپت یک پوشه را نیز میدهد <script type="text/javascript" asp-src-include="*.js"></script>
هرچند این قابلیت جالب است و سبب الحاق یکجای تمام فایلهای js موجود در پوشهی wwwroot خواهد شد، اما پاسخگوی کار ما نخواهد بود؛ چون ترتیب قرارگیری این فایلها مهم است.
راه حل واقعی
در اینجا کدهای کامل فایل Views\Shared\_Layout.cshtml را که میتواند جایگزین فایل index.html تولیدی توسط Angular CLI باشد، ملاحظه میکنید:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/x-icon" href="favicon.ico">
<title>ng2-lab</title>
<base href="/">
<environment names="Development">
</environment>
<environment names="Staging,Production">
<link rel="stylesheet" asp-href-include="~/styles*.css" />
</environment>
</head>
<body>
@RenderBody()
<app-root></app-root>
<environment names="Development">
<script type="text/javascript" src="/inline.bundle.js"></script>
<script type="text/javascript" src="/polyfills.bundle.js"></script>
<script type="text/javascript" src="/scripts.bundle.js"></script>
<script type="text/javascript" src="/styles.bundle.js"></script>
<script type="text/javascript" src="/vendor.bundle.js"></script>
<script type="text/javascript" src="/main.bundle.js"></script>
</environment>
<environment names="Production,Staging">
<script type="text/javascript" asp-src-include="~/inline*.js"></script>
<script type="text/javascript" asp-src-include="~/polyfills*.js"></script>
<script type="text/javascript" asp-src-include="~/scripts*.js"></script>
<script type="text/javascript" asp-src-include="~/vendor*.js"></script>
<script type="text/javascript" asp-src-include="~/main*.js"></script>
</environment>
</body>
</html>
در اینجا دو حالت توسعه و همچنین ارائهی نهایی مدنظر قرار گرفتهاند. در حالت توسعه، دقیقا از همان نامهای سادهی تولیدی استفاده شدهاست و در حالت ارائهی نهایی چون نام فایلها به صورت
تولید میشوند، میتوان قسمت هش را با * جایگزین کرد؛ مانند "asp-src-include="~/vendor*.js
همچنین باید دقت داشت که در حالت توسعه، تمام شیوه نامههای برنامه در فایل styles.bundle.js قرار میگیرند. اما در حالت ارائهی نهایی، این فایل وجود نداشته و با نام کلی styles*.css تولید میشود که باید در head صفحه قرار گیرد (مانند تنظیمات حالت تولید در Layout فوق).
اصلاح قسمت URL Rewrite برنامه
در حالت کار با برنامههای تک صفحهای وب، در اولین درخواست رسیدهی به برنامه ممکن است آدرسی درخواست شود که معادل کنترلر و اکشن متدی را در برنامهی سمت سرور نداشته باشد. در این حالت کاربر را به همان صفحهی index.html هدایت میکنیم تا سیستم مسیریابی سمت کلاینت، کار نمایش آن صفحه را انجام دهد:
app.Use(async (context, next) =>
{
await next();
var path = context.Request.Path.Value;
if (path != null &&
context.Response.StatusCode == 404 &&
!Path.HasExtension(path) &&
!path.StartsWith("/api/", StringComparison.OrdinalIgnoreCase))
{
context.Request.Path = "/index.html";
await next();
}
});
از آنجائیکه پس از اصلاحات فوق دیگر از این فایل استفاده نمیشود، باید تغییر ذیل را نیز اعمال کرد:
//context.Request.Path = "/index.html";
context.Request.Path = "/"; // since we are using views/shared/_layout.cshtml now.
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید.