webpack
設定の_ASP.NET Core 2.0 Angular 5
_アプリケーションを_ASP.NET Core 2.1 Angular 6
_の_Angular-Cli
_に移行しようとしています。
短い質問:
_Microsoft.AspNetCore.SpaServices.Extensions
_を使用してcshtml
からかみそりページのディレクティブを強制的に解析するにはどうすればよいですか?
_index.html
_の_Angular.json
_を使用したくありませんが、_index.cshtml
_は使用しません。
長い説明:
Angular template から新しいASP.NET Coreプロジェクトを開始しました。魔法のように機能するものがかなりあります。
index.html
_フォルダー内には、アプリケーションの起動時に自動的に提供される_ClientApp/src
_ファイルがあります。</body>
_の_index.html
_タグの前に(最初のポイントから)いくつかのスクリプトが挿入されます:_inline.bundle.js
_、_polyfills.bundle.js
_、_vendor.bundle.js
_、_main.bundle.js
_および_styles.bundle.css
_タグの前の_</head>
_。これらのスクリプトを誰が挿入したかはわかりませんが、Razorページ(cshtml
)に挿入したいです。
古いプロジェクトのコードを使用しようとしました:
_<!DOCTYPE html>
<html>
<head>
<base href="/" />
<title>@ViewData["Title"]</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
@{string googleAnalyticsId = Html.Raw(ViewData["GoogleAnalyticsId"]).ToString();}
@if (!string.IsNullOrEmpty(googleAnalyticsId))
{
<script>
(function(i, s, o, g, r, a, m)
{
...
})(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
ga('create', '@googleAnalyticsId', 'auto');
</script>
}
<script>
@Html.Raw(ViewData["TransferData"])
</script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/0.8.2/css/flag-icon.min.css" async defer />
<script src="https://apis.google.com/js/platform.js" async defer></script>
<app>
<!-- loading layout replaced by app after startupp -->
<div class="page-loading">
<div class="bar">
<i class="sphere"></i>
</div>
</div>
</app>
</body>
</html>
_
_Angular.json
_のインデックスオプションをこの_index.cshtml
_にポイントします。
_ "architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "wwwroot/dist",
"index": "Views/Home/Index.cshtml", //<----- here
_
問題は、コンテンツ(すべての@タグ)がASP.NET Coreによって処理されないが、直接コンテンツを出力することです:
_<!DOCTYPE html>
<html>
<head>
<base href="/" />
<title>@ViewData["Title"]</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
@{string googleAnalyticsId = Html.Raw(ViewData["GoogleAnalyticsId"]).ToString();}
@if (!string.IsNullOrEmpty(googleAnalyticsId))
{
<script>
...
_
ただし、次のようにする必要があります。
_<!DOCTYPE html>
<html>
<head>
<base href="/" />
<title>Test title</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<script>
_
いくつかの変数(appsettings.jsonから)をhtmlページの最後に出力したい。私はすでにASP.NET Coreを使用しているので、Razorページは良い解決策のようです。
私も試してみます:
新しいRazorPageを追加するには、C#コンテンツ(@ディレクティブ)が処理されますが、誰もAngularスクリプトを挿入していません。
AndyCunninghamの回答に対する回答:
_ng build --prod
_は次のファイルを書き込みます。
_<script type="text/javascript" src="runtime.b38c91f828237d6db7f0.js"></script><script type="text/javascript" src="polyfills.2fc3e5708eb8f0eafa68.js"></script><script type="text/javascript" src="main.16911708c355ee56ac06.js"></script>
_
_index.html
_に。かみそりのページにこれを書く方法。
それは古い質問ですが、答えが誰かを助けることを願っています
まあ、difficutはwebpackがindex.cshtmlにscriptsタグを挿入するようにしていますが、index.cshtmlにタグを含めることができます
@{
ViewData["title"] = "I'am from cshtml";
}
<app-root>Loading...</app-root>
<script type="text/javascript" src="/runtime.js"></script>
<script type="text/javascript" src="/polyfills.js"></script>
<script type="text/javascript" src="/styles.js"></script>
<script type="text/javascript" src="/vendor.js"></script>
<script type="text/javascript" src="/main.js"></script>
その後、あなたのようなMVCをルータすることができます
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
routes.MapRoute(
name: "spa-fallback",
template: "{*url:regex(^((?!.css|.map|.js|sockjs).)*$)}",
defaults: new { controller = "Home", action = "Index" });
});
{controller} {action = Index}/{id?}に対応しないすべてのルートが「spa-fallback」に分類され、ファイルに.cssまたは.mapまたは.jsまたは.sockjsが含まれていない場合、ホーム/インデックス。 .NETの「正規表現」がスクリプトファイルを提供することが必要です。
最後のステップは、outputHashing:allを使用してスクリプトの名前を維持するように、angular.jsonを構成します
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"ClientApp": {
...
"architect": {
"build": {
...
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all", //<--add this line
...
},
....
},
"defaultProject": "ClientApp"
}
最後に、startup.csで使用できるURLが有効かどうか(他のURLサーバーのインデックスページ)を確認できます。
app.Use(async (context, next) =>
{
string path = context.Request.Path.Value.Substring(1);
bool encontrado = path.EndsWith(".js") || path.EndsWith(".css") || path.EndsWith(".map") || path.StartsWith("sockjs");
if (!encontrado)
{
..use your code to check the url...
}
if (encontrado)
await next.Invoke(); //<--continue
else
{ //send to an error404 page
context.Response.ContentType = "text/html";
await context.Response.SendFileAsync(Path.Combine(env.WebRootPath, "error404.html"));
}
});
注:スクリプトのhrefを絶対パスに配置します(例:src = "/ runtime.js")。パッケージjsonには、次のようないくつかのスクリプトを含めることができます。
"scripts": {
"ng": "ng",
"start": "ng serve --base-href=/ --serve-path=/",
"start:fr": "ng serve --base-href=/fr-FR/ --configuration=fr --serve-path=/fr-FR",
"build": "ng build",
...
},
--serve-path = fr-FRを使用する場合、スクリプトのhrefはこのserve-pathを使用する必要があります。 src = "/ fr-FR/runtime.js"
私はこの答えをReact SPA拡張機能での経験に基づいていますが、Angular、同様に 同じ_ClientApp/index.html
_ミドルウェアメカニズム 、および同じ _IApplicationBuilder.UseSpa
_ エントリポイント。
問題は、app.UseSpa(...)
を使用すると、この拡張機能のデフォルト実装 が構成することですaすべてのUI要求をリッスンし、それらをindex.html に転送するミドルウェア。
プロジェクトでこれを回避する方法の簡単な例を作成しました: https://github.com/andycmaj/aspnet_spa_without_indexhtml/pull/1/files index.htmlを無視し、代わりにカミソリビューを使用するために何を変更する必要があるかを示します。
基本的に、UseSpa
が行うことを再実装しましたが、インターセプトや障害のあるミドルウェアをindex.htmlにアタッチしませんでした。
Home
剃刀ビューは、index.htmlが行っていたより重要なことを行う必要があることに注意してください。最も重要なことは、SPA静的コンテンツミドルウェアによって提供される _bundle.js
_ を含める必要があることです。