ASP.NET CoreのScriptTagHelperについて調べてみる

[ASP.NET Core](https://www.asp.net/core/overview/aspnet-vnext)の[ScriptTagHelper](https://docs.microsoft.com/en-us/aspnet/core/api/microsoft.aspnetcore.mvc.taghelpers.scripttaghelper)について調べたこと。

## 履歴
2017/05/26 初版
2019/03/15 環境ASP.NET Coreバージョン追加

## 環境
Visual Studio 2017
ASP.NET Core 1.1, 2.1, 2.2

# ScriptTagHelperとは

ASP.NET Coreの新規プロジェクト作成時に出来る_Layout.htmlに記述されている以下のようなコードのこと。

```html:Views/Shared/_Layout.cshtml
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
        asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
        asp-fallback-test="window.jQuery"
        crossorigin="anonymous"
        integrity="sha384-K+ctZQ+LL8q6tP7I94W+qzQsfRV2a+AfHIi9k8z8l9ggpc8X+Ytst4yBo/hH+8Fk">
</script>
```

# ScriptTagHelperの機能

ScriptTagHelperには以下の属性を指定できる。

| 属性名 |
|:-----------|
|asp-src-include|
|asp-src-exclude|
|asp-fallback-src|
|asp-fallback-src-include|
|asp-fallback-src-exclude|
|asp-fallback-test|
|asp-append-version|

以下、サンプルコードのソリューション構成
![image.png](https://qiita-image-store.s3.amazonaws.com/0/76153/ba4e7fbb-4e40-cbca-73c5-70a2fbf849b2.png)

## asp-src-include
複数のファイルを読み込む。[Globbing patterns](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/file-providers#globbing-patterns)による指定が可能。

```html:Views/Shared/_Layout.cshtml
<script asp-src-include="~/js/sample/**/*.js"></script>
```

```html:結果
<script src="/js/sample/test4.js"></script><script src="/js/sample/test5.js"></script><script src="/js/sample/calc/test1.js"></script><script src="/js/sample/calc/test2.js"></script><script src="/js/sample/calc/test3.js"></script>
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/76153/9743ae82-f5ec-117f-85ef-4e088fc85866.png)

## asp-src-exclude
複数のファイルを除外する。asp-src-includeと組み合わせて使用する。[Globbing patterns](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/file-providers#globbing-patterns)による指定が可能。

```html:Views/Shared/_Layout.cshtml
<script asp-src-include="~/js/sample/**/*.js" asp-src-exclude="~/js/sample/calc/*.js"></script>
```

```html:結果
<script src="/js/sample/test4.js"></script><script src="/js/sample/test5.js"></script>
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/76153/98525271-81c9-2500-828c-16f22e9e682b.png)

## asp-fallback-src
src属性に指定したファイルの読み込みに失敗した場合に読み込む代替ファイル。asp-fallback-testと組み合わせて使用する。

```html:Views/Shared/_Layout.cshtml
<script src="https://example.com/test.js" asp-fallback-src="~/js/sample/calc/test1.js" asp-fallback-test="window.test"></script>
```

```html:結果
<script src="https://example.com/test.js"></script>
<script>(window.test||document.write("\u003Cscript src=\u0022\/js\/sample\/calc\/test1.js\u0022\u003E\u003C\/script\u003E"));</script>
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/76153/3d32e938-be19-d09b-2edf-3b84cb755a5c.png)

### asp-fallback-test
読み込みに失敗したかどうかの判定を行うためのスクリプト。

例えばjQueryの場合は、

```html:Views/Shared/_Layout.cshtml
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
        asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
        asp-fallback-test="window.jQuery">
</script>
```

といった具合に記述することで、「"window.jQuery"というオブジェクトが定義された＝読み込みに成功した」とみなして判定することができる。

## asp-fallback-src-include
src属性に指定したファイルの読み込みに失敗した場合に読み込む代替ファイル一式。[Globbing patterns](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/file-providers#globbing-patterns)による指定が可能。

```html:Views/Shared/_Layout.cshtml
<script src="https://example.com/test.js" asp-fallback-src-include="~/js/sample/**/*.js" asp-fallback-test="window.test"></script>
```

```html:結果
<script src="https://example.com/test.js"></script>
<script>(window.test||document.write("\u003Cscript src=\u0022\/js\/sample\/test4.js\u0022\u003E\u003C\/script\u003E\u003Cscript src=\u0022\/js\/sample\/test5.js\u0022\u003E\u003C\/script\u003E\u003Cscript src=\u0022\/js\/sample\/calc\/test1.js\u0022\u003E\u003C\/script\u003E\u003Cscript src=\u0022\/js\/sample\/calc\/test2.js\u0022\u003E\u003C\/script\u003E\u003Cscript src=\u0022\/js\/sample\/calc\/test3.js\u0022\u003E\u003C\/script\u003E"));</script>
```

## asp-fallback-src-include
src属性に指定したファイルの読み込みに失敗した場合に読み込む代替ファイル一式。[Globbing patterns](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/file-providers#globbing-patterns)による指定が可能。

```html:Views/Shared/_Layout.cshtml
<script src="https://example.com/test.js" asp-fallback-src-include="~/js/sample/**/*.js" asp-fallback-test="window.test"></script>
```

```html:結果
<script src="https://example.com/test.js"></script>
<script>(window.test||document.write("\u003Cscript src=\u0022\/js\/sample\/test4.js\u0022\u003E\u003C\/script\u003E\u003Cscript src=\u0022\/js\/sample\/test5.js\u0022\u003E\u003C\/script\u003E\u003Cscript src=\u0022\/js\/sample\/calc\/test1.js\u0022\u003E\u003C\/script\u003E\u003Cscript src=\u0022\/js\/sample\/calc\/test2.js\u0022\u003E\u003C\/script\u003E\u003Cscript src=\u0022\/js\/sample\/calc\/test3.js\u0022\u003E\u003C\/script\u003E"));</script>
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/76153/7999512d-44f8-f384-2b52-80eac88cc337.png)

## asp-fallback-src-exclude
src属性に指定したファイルの読み込みに失敗した場合に除外する代替ファイル一式。asp-fallback-src-includeと組み合わせて使用する。[Globbing patterns](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/file-providers#globbing-patterns)による指定が可能。

```html:Views/Shared/_Layout.cshtml
<script src="https://example.com/test.js" asp-fallback-src-include="~/js/sample/**/*.js" asp-fallback-src-exclude="~/js/sample/calc/*.js" asp-fallback-test="window.test"></script>
```

```html:結果
<script src="https://example.com/test.js"></script>
<script>(window.test||document.write("\u003Cscript src=\u0022\/js\/sample\/test4.js\u0022\u003E\u003C\/script\u003E\u003Cscript src=\u0022\/js\/sample\/test5.js\u0022\u003E\u003C\/script\u003E"));</script>
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/76153/66745b6c-65cc-d9cf-f8ba-be68aef3eaab.png)

## asp-append-version
ファイルのURLパス末尾にバージョン番号をハッシュ化した文字列を付加する。ファイル変更時のキャッシュ対策用。

```html:Views/Shared/_Layout.cshtml
<script src="~/js/sample/calc/test1.js" asp-append-version="true"></script>
```

```html:結果
<script src="/js/sample/calc/test1.js?v=2E3m_HZUu6HkFSgIsMaGLZTvfcps4WXJN9e69ag9h6I"></script>
```

## おまけ
### integrityのハッシュ文字列生成

https://www.srihash.org/
が便利です。