ASP.NET Core で Riot.js その1

  • 13
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

ASP.NET Core が RTM になったので試しに Riot.js を使ってみます。
今回はプロジェクトを作成して Riot.js を使って Hello World するところまでやります。

開発環境

Windows 10 Pro
Visual Studio Code

必要なもの

以下のツールが必要ですのでインストールしておいてください。

  • Node.js
  • Yeoman
  • Bower
  • generator-aspnet
  • .NET Core

プロジェクトの作成

Web API アプリケーションのプロジェクトを作成します。

yo aspnet webapi [作成するプロジェクト名]

作成したプロジェクトのディレクトリに移動して Visual Studio Code で開きます。

cd [作成するプロジェクト名] & code .

Visual Studio Code が起動したら、ショートカットキーか [表示] - [Toggle Integrated Terminal] で エディタ内にターミナルを開いておきます。

OS ショートカットキー
Win Ctrl + @
Mac ^`
Linux Ctrl + `

パッケージの追加

実行時に html ファイルを表示したいので project.json の dependencies に Microsoft.AspNetCore.StaticFiles を追加します。

project.jsonの一部
  "dependencies": {
    "Microsoft.NETCore.App": {
      "version": "1.0.0",
      "type": "platform"
    },
    "Microsoft.AspNetCore.Mvc": "1.0.0",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
    "Microsoft.AspNetCore.StaticFiles": "1.0.0",
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
    "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
    "Microsoft.Extensions.Configuration.Json": "1.0.0",
    "Microsoft.Extensions.Configuration.CommandLine": "1.0.0",
    "Microsoft.Extensions.Logging": "1.0.0",
    "Microsoft.Extensions.Logging.Console": "1.0.0",
    "Microsoft.Extensions.Logging.Debug": "1.0.0",
    "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0"
  },

保存したらターミナルで以下のコマンドを入力してパッケージを入手します。

dotnet restore

Startup.cs の変更

静的ファイルを扱うように Startup.cs を変更します。

Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace AspRiotApp
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddMvc();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            app.UseMvc();

            // wwwroot/index.html を起動時に表示するようにする
            app.UseDefaultFiles();

            // 静的ファイルを扱えるようにする
            app.UseStaticFiles();
        }
    }
}

UseDefaultFiles() 拡張メソッドで実行時に index.html を呼び出すようにして UseStaticFiles() 拡張メソッドを呼んで静的コンテンツを扱えるようにしています。

index.html の追加

wwwroot フォルダに index.html を追加します。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>ASP.NET Core で Riot.js</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/riot/2.5.0/riot+compiler.min.js"></script>
</head>
<body>
    <!-- app タグ -->
    <app title="ASP.NET Core"></app>

    <!-- app タグを作成 -->
    <script type="riot/tag">
        <app>
            <h1>Hello { title } With RiotJS</h1>
            this.title = opts.title;
        </app>
    </script>

    <!-- 作成したタグをマウントする -->
    <script>
        riot.mount('*');
    </script>
</body>
</html>

app タグを追加して title 属性に値をセットしています。

<app title="ASP.NET Core"></app>

タグを作成する場合は script タグの type 属性に "riot/tag" を指定します。

<script type="riot/tag">
...
</script>

上記 script タグ にタグとして展開する内容を記述します。html 内で タグを定義する場合はタグ内の script タグは省略します。省略しないで記述する場合は以下のようになります。

<app>
    <h1>Hello { title } with RiotJS</h1>
    <script>
        this.title = opts.title;
    </script>
</app>

属性に設定されている値は opts でアクセスします。テンプレートへの値のバインディングは {...} でおこないます。

とりあえずこの状態で実行します。ターミナルから以下のコマンドを入力します。

dotnet run

実行した状態でブラウザから localhost に接続すると

Hello ASP.NET Core with RiotJS

と表示されます。

localhost を停止するときはターミナル上で Ctrl + C すれば停止できます。

tag ファイルを作成して読込ませる

tag はindex.html 内だけではなくて、別のファイルに定義して使用することもできます。
試しに index.html 内で定義している app タグを app.tag ファイルを作成して移動してみます。

app.tag の作成

wwwroot フォルダに app.tag を追加します。

app.tag
<app>
    <h1>Hello { title } with RiotJS</h1>
    this.title = opts.title;
</app>

index.html の修正

合わせてapp.tag を読込むように index.html を修正します。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>ASP.NET Core で Riot.js</title>
    <!-- app.tag の読込み -->
    <script src="app.tag" type="riot/tag"></script>
    <!-- riot+compiler.min.js の読込み -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/riot/2.5.0/riot+compiler.min.js"></script>
</head>
<body>
    <!-- app タグ -->
    <app title="ASP.NET Core"></app>

    <!-- 作成したタグをマウントする -->
    <script>
        riot.mount('*');
    </script>
</body>
</html>

app.tag を読込むように script タグを追加しています。tag ファイルの読込は riot+compiler.min.js ファイルよりも先となるようにしておきます。

この状態で実行して localhost に接続すると何も表示されないと思います。

ブラウザコンソールを開くと

HTTP404: 見つかりません - 要求された URI (Uniform Resource Identifier) に一致するものがサーバーに見つかりませんでした。

と表示されるかと思います。デフォルトの状態だと tag ファイルを静的コンテンツとして扱ってもらえないので Startup.cs に tag ファイル を扱えるように処理を追加する必要があります。

Statup.cs の修正

Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace AspRiotApp
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddMvc();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            app.UseMvc();

            // .tag ファイルを扱えるようにする
            var provider = new FileExtensionContentTypeProvider();
            provider.Mappings[".tag"] = "riot/tag";

            // wwwroot/index.html を起動時に表示するようにする
            app.UseDefaultFiles();

            // 静的ファイルを扱えるようにする            
            app.UseStaticFiles(new StaticFileOptions
            {
                ContentTypeProvider = provider
            });
        }
    }
}

FileExtensionContentTypeProvider インスタンスを作成して .tag 拡張子のファイルをマッピングしてあげます。

var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".tag"] = "riot/tag";

次に、 StaticFileOptions インスタンスを作成して ContentTypeProvider プロパティ に先ほど作成した provider を設定して UseStaticFiles() に引数で渡してあげれば .tag ファイルを静的コンテンツとして扱えるようになります。

app.UseStaticFiles(new StaticFileOptions { ContentTypeProvider = provider });

これでエラーなく最初に実行したときに表示された内容が表示されるようになります。

次回

Web API から データを取得して一覧を表示するところをやります。