雑記
 

Visual StudioでTypeScript+React+C#を開発する

2021/1/31

この記事が対象とする製品・バージョン

VS2019 Visual Studio 2019 対象です。
VS2017 Visual Studio 2017 × 対象外です。
VS2015 Visual Studio 2015 × 対象外です。
VS2013 Visual Studio 2013 × 対象外です。
VS2012 Visual Studio 2012 × 対象外です。
VS2010 Visual Studio 2010 × 対象外です。
VS2008 Visual Studio 2008 × 対象外です。
VS2005 Visual Studio 2005 × 対象外です。
VS.NET 2003 Visual Studio 2003 × 対象外です。
VS.NET 2002 Visual Studio (2002) × 対象外です。

目次

 

 

 

概要

この記事では Visual Studio を使って、TypeScript + React でWeb画面を作成し、C#で作ったWebAPIを呼び出す簡単なプログラムを作成する手順を紹介します。

ポイントは Visual Studio をどう使うかという点です。Visual Studioを使うことでアプリケーションを効率的に開発できることが明らかになります。

最終的には次のようなプログラムが完成します。

TypeScriptで作ったapp.tsxとTest.tsxは1つのJavaScriptファイル app-bundle.jsとなります。ここには React を使って画面を描画し、WebAPIを呼び出すプログラムを記述します。

このapp-bundle.jsは index.htmlからscriptタグで参照されます。一方、呼び出されるWebAPIはパラメーターを基にごく単純な文字列を生成する Echo という名前にします。これはC#でプログラムします。

この記事の第1段階(手順1)ではWebAPIなしで、TypeScript + React で静的な画面を描画します。第2段階(手順2)でC#でWebAPIを作成し、TypeScriptにその呼び出しを記述します。

 

前提

前提1.Visual Studio 2019

この記事の内容を実際に試すには、Visual Studio 2019が必要です。 この記事の内容は Visual Studio 2019 (16.8.3)で確認しています。

 

前提2.Node.js がインストールされている

Node.js がインストールされているかは、PowerShellまたはコマンドプロンプトで Node --version と入力して、バージョンが表示されるかどうかでわかります。

Node.js をインストールするには、https://nodejs.org/ja/ から、インストーラーをダウンロードして次へ次へとするだけです。Visual Studioを起動している場合、Node.jsをインストールした後Visual Studioを再起動してください。

 

手順1.TypeScript のプログラムを作成

 

手順1-1.新しいプロジェクトの作成 > ASP.NET Core Webアプリケーション > 「次へ」ボタンクリック

ASP.NET Core Web アプリケーションを新規作成

メモ メモ  - Visual Basic は使用できません

この記事では C# を扱います。Visual Baisc でこの記事で説明することを実現することは可能ですが、Visual Studioが VB + ASP.NET Core をサポートしてくれないので、いろいろと自力でやることになります。そのためこの記事で説明する手順では通用しません。(Visual Studio 2019 16.8.3で確認しています。)

VBでやる場合は、一度C#でプロジェクトを作ってから、Visual Studioを閉じてプロジェクトの拡張子を csproj から vbproj に変更。slnファイルが参照しているプロジェクト名も変更し、Visual Studio再起動。プロジェクトに含まれるcsファイルをVisual Basicに翻訳し、vbファイルに置き換えるという流れになります・・・。

 

手順1-2.プロジェクト名に「TsReactCs」を入力し、「作成」ボタンクリック

プロジェクト名は重要ではありません。プロジェクト名によって何かの設定が変わるということはありません。

 

手順1-3..NET Core, ASP.NET Core 5.0ASP.NET Core (空) を選択し、「作成」ボタンクリック

ASP.NET Core 3.1 を選択しても問題ないと思います。

他はデフォルトのままです。

 

手順1-4.wwwroot フォルダー を追加

ソリューションエクスプローラーでプロジェクト(この記事ではTsReactCs)を右クリックして、[追加] - [新しいフォルダー] でフォルダーを追加し、名前を wwwroot にします。

wwwrootという名前に変更するとアイコンが通常のフォルダーアイコンから地球儀のアイコンに変化します。


手順1-5.wwwroot フォルダー に index.html を追加

追加した wwwroot フォルダー を右クリックして、[追加] - [新しい項目]で 「HTML ページ」を選択 し、名前に index.html と入力して「追加」ボタンをクリックします。

追加された index.html に次の通り記述します。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>React Sample</title>
  </head>
  <body>
    <h1>React Sample</h1>
    <div id="root"></div>
    <script type="module" src="js/app-bundle.js"></script>
  </body>
</html>

 

手順1-6.package.json を追加

ソリューションエクスプローラーでプロジェクトを右クリックして[追加] - [新しい項目] で 「npm 構成ファイル」を選択し、デフォルトの名前 package.json のまま「追加」ボタンをクリックします。

 

追加された package.json に以下のように記述して保存します。

{
  "version": "1.0.0",
  "name": "asp.net",
  "private": true,
  "devDependencies": {
    "@types/react": "17.0.0",
    "@types/react-dom": "17.0.0",
    "ts-loader": "~7.0.1",
    "typescript": "~3.8.3",
    "webpack": "~4.42.1",
    "webpack-cli": "~3.3.11"
  },
  "dependencies": {
    "react": "17.0.1",
    "react-dom": "17.0.1"
  }
}

 

メモ メモ  - 使用するパッケージ

@type/react と @type/react-dom は、TypeScript に react と react-dom というものが存在し、このようなクラスやメソッドなど存在するということを認識させるために必要です。react自身やreact-dom自身はJavaScriptで作成されているため、TypeScriptから認識させるために何かの仲介が必要で、その仲介の役割を担います。

ts-loader, typescript, webpack, webpack-cli はwebpackで使用します。つまり、作成したTypeScriptを1つのJavaScriptにまとめてブラウザーで実行できるようにします。

 

 

次に、 ソリューションエクスプローラーで package.json を右クリックして[パッケージの復元]をクリックします。

この操作でpackage.jsonに記述したreact, react-domなどのパッケージがダウンロードされます。この機能は Visual Studio が npm を呼び出すことで実現されています。

この処理が完了するまで数分かかります。

完了するとVisual Studioの左下に「パッケージのインストールが完了しました」と表示されます。

この処理ではプロジェクト配下に node_modules というフォルダーが追加され、ここに追加したパッケージが保存されます。node_modules フォルダーの中を見ると大量のサブフォルダーが作成されているのが確認できます。

 

手順1-7.tsconfig.json を追加

同様にプロジェクトを右クリックして[追加] - [新しい項目] で 「TypeScript JSON 構成ファイル」を選択し、デフォルトの名前 tsconfig.json のまま「追加」ボタンをクリックします。

 

追加された tsconfig.json に次のように記述して保存します。

{
  "compilerOptions": {
    "noImplicitAny": false,
    "noEmitOnError": true,
    "removeComments": false,
    "sourceMap": true,
    "target": "ES5",
    "lib": [ "ES2015", "DOM" ],
    "esModuleInterop": true,
    "jsx": "react",
    "outDir": ".tsoutput",
    "moduleResolution": "Node"
  },
  "exclude": [
    "node_modules",
    "wwwroot"
  ]
}

 

 

手順1-8.app.tsx を追加

ソリューションエクスプローラーでプロジェクトを右クリックして、[追加] - [新しい項目] で 「TypeScript JSX ファイル」を選択します。名前に app.tsx と入力して「追加」します。

メモ メモ  - TypeScriptファイルではなく、TypeScript JSX ファイル です。

JSXを使用するため、拡張子は tsx である必要があります。そのため通常のTypeScriptではなく、TypeScript JSXファイルを選択します。ReactではJSXをよく使います。

ファイル名は何でもよいのですが、後の手順でこの名前を使うことになりますので、ためしにやってみる場合は同じ名前にしておくのが無難です。

 

TypeScript JSXファイルを追加すると、Visual Studioの上側に Microsoft.TypeScript.MSBuild をインストールするようにメッセージがでるので、「今すぐインストール」をクリックします。

 

追加された app.tsx に次の通り記述して保存します。

import * as React from 'react'
import * as ReactDOM from 'react-dom'

ReactDOM.render(
    <h1>Hello, React!</h1>,
    document.getElementById('root')
);

 

手順1-9.webpack-config.js を追加

ソリューションエクスプローラーでプロジェクトを右クリックして[追加] - [新しい項目] で 「JavaScript ファイル」を選択し、名前に webpack-config.js と入力して「追加」ボタンをクリックします。

 

追加された webpack-config.js に次の通り記述します。

module.exports = {
    devtool: 'source-map',
    entry: './app.tsx',
    mode: 'development',
    output: {
        filename: '../wwwroot/js/app-bundle.js'
    },
    resolve: {
        extensions: ['.webpack.js', '.web.js', '.ts', '.js', '.jsx', '.tsx']
    },
    module: {
        rules: [
            {
                test: /\.ts|\.tsx$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'ts-loader'
                }
            }
        ]
    }
}

webpack-config.js は webpack がどのようにJavaScriptをまとめるかを定義します。この設定でwebpack を実行すると app.tsx とその依存しているパッケージが1つのJavaScriptにまとめられ wwwroot/jsフォルダー以下にapp-bundle.js というファイルになります。

 

 

手順1-10.ASP.NET Core の設定を編集

ソリューションエクスプローラーで Startup.cs を開き、次の4点を編集します。

1. app.UseRouting(); の下に app.UseStaticFiles(); を追加します。

2.その次にある app.UseEndpointsから始まる7行は削除します。(この削除は必須ではありませんが、不要なので削除しておくことにします。)

3.代わりにに、前の手順で追加した、app.UseStaticFiles の直後に 下記の4行を挿入します。

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

4.ConfigureServicesメソッド内で services.AddControllers(); を呼び出します。

 

最終的に Startup.cs は次のようになります

選択したテンプレートやVisual Studioのバージョンによって異なる場合があると思いますが、上記ポイントを抑えていれば大丈夫はなずです。

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace TsReactCs
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();
            app.UseStaticFiles();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });

        }
    }
}

 

手順1-11.ビルド時にwebpackコマンドを自動実行するよう設定

ソリューションエクスプローラーでプロジェクトを右クリックして[プロパティ]を選択し、ビルドイベント タブを選択します。

ビルド前イベントのコマンドラインに次の通り入力します。

node_modules/.bin/webpack-cli --config webpack-config.js

 

 

手順1-12.起動時に index.html を表示するように設定

次に、デバッグ タブを選択し、ブラウザーの起動欄に index.html を入力します。

ブラウザーの起動欄ついているチェックをはずさないように気をつけてください。

 

Visual Studio の保存ボタンをクリックします。

 

手順1-13.実行

Visual Studio の [デバッグ]メニューから[デバッグの開始]をクリックして、プログラムを実行します。

ブラウザーが起動して Hello, React! と表示されることを確認します。

ブラウザーがセキュリティの警告を表示する場合がありますが、ローカルの開発をしているだけなので問題ありません。

 

メモ メモ  - うまくいかない場合

「デバッグ アダプターを起動できませんでした。」というエラーメッセージの場合、ブラウザーをすべて閉じて再実行します。それでもダメなら、起動するブラウザーを変更します。たとえば、Chromeが起動する設定になっている場合はEdgeにします。起動するブラウザーはVisual Studioのデバッグ開始ボタンの右側の▼から変更できます。

ビルドエラーになる場合は、出力ウィンドウにエラーの原因が出力されている場合があります。たいていの場合、設定ファイルかプログラムに間違いがあります。カンマやカッコの余分/不足かもしれません。

ブラウザー自体は表示されるが Hello, React! と表示されない場合は、ブラウザーの開発者ツールのコンソールにエラーが出力されている場合があります。開発者ツールはブラウザーで F12 や Ctrl + Shift + I などで表示できます。

 

成功した場合、ソリューションエクスプローラーで、wwwrootフォルダーの下にjs\app-bundle.js が生成されていることを確認できます。

 

ここまでで、C# + TypeScript + React を Visual Studio で開発できる環境が整いましたが、まだ C# のプログラムは基本的な設定以外は登場していません。

次は C# で WebAPIを作成し、TypeScript + React から呼び出すサンプルを作成します。

 

手順2.WebAPI の実装と呼び出し

 

手順2-1.WebAPIの追加

ソリューションエクスプローラーでプロジェクト(この記事では TsReactCs)を右クリックして、[追加] - [新しい項目]で 「API コントローラー - 空」を選択 し、名前に EchoController.cs と入力して「追加」ボタンをクリックします。

ここでは名前の末尾が Controller.cs になっていることが重要です。この名前には特別な意味があり、この部分を変更すると動作しません。

追加された EchoController.cs に次の通り記述します。

using Microsoft.AspNetCore.Mvc;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace TsReactCs
{
    [Route("api/[controller]")]
    [ApiController]
    public class EchoController : ControllerBase
    {
        // GET api/<EchoController>/5
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return $"受け取った引数は{id}です。";
        }
    }
}

 

 

手順2-2.test.tsx を追加

ソリューションエクスプローラーでプロジェクトを右クリックして、[追加] - [新しい項目] 「TypeScript JSX ファイル」を選択します。名前に Test.tsx と入力して「追加」します。

 

C#で作ったWebAPI Echo を呼び出して受け取った値を表示するようにプログラムしてみます。

Test.tsx に次の通り記述して保存します。

import * as React from 'react'

type TestProps = { }
type TestState = {
    data: string;
    loading: boolean;
}

export class Test extends React.Component<TestProps, TestState> {

    constructor(props: TestProps) {
        super(props);
        this.state = { data: "", loading: true };
    }

    componentDidMount() {
        //このコンポーネントが画面に組み込まれたらWebAPIを呼び出します。
        this.loadData();
    }

    render() {
        if (this.state.loading) {
            return <p><em>Loading...</em></p>;
        } else {
            return <p>{this.state.data}</p>;
        }
    }

    async loadData() {
        const response = await fetch('api/Echo/627'); //WebAPI Echo を呼び出して結果を受け取ります。
        const data = await response.text();
        this.setState({ data: data, loading: false });
    }
}

 

手順2-3.app.tsx を編集

app.tsx を次のように変更し、Testコンポーネント(Test.tsx)が画面に描画されるようにします。

import * as React from 'react'
import * as ReactDOM from 'react-dom'
import {Test} from './Test'

ReactDOM.render(
    <Test />,
    document.getElementById('root')
);

 

手順2-4.実行

Visual Studio の [デバッグ]メニューから[デバッグの開始]をクリックして、プログラムを実行します。

C#で作ったWebAPI のレスポンス「受け取った引数は627です。」と表示されることを確認します。

セキュリティの警告が表示される場合がありますが問題ないのでサイトにアクセスしてください。

 

参考

ASP.NET Core で webpack を使う