10
6

More than 5 years have passed since last update.

React + TypeScript + Webpack を既存プロジェクト(ASP.NET MVC5)に導入してみた

Last updated at Posted at 2019-06-21

はじめに

 「JQueryもいいけれど、そろそろReactを使ってみたいな」
 そう思って挑戦してみたところ、なかなかに難儀でしたので、それをまとめてみます。「React + TypeScript + Webpack 」をASP.NET MVC5に適用する内容になっています。

 次にような方に役立つのではないでしょうか。

  • JQueryは使ったことあるけれど、Reactを始めてみたい方
  • 1から作るのはサンプルやcreate-react-app をやってはみたものの、既存プロジェクトへの適用の仕方がよく分からない方

各パッケージの役割を整理

 正直なところフロントエンドがここまで複雑化しているのとは思いませんでした。
 たくさん登場人物がいて、さらに誰が何を担当しているのが分かりにくいです…。そもそもなんでフロントエンドの話に、サーバーサイドである、Node.js が出てくんねん!って感じですよ。過渡期なのでしょうけど、ちょっと魔境すぎません?

色々な登場人物が出てくる流れ

 大まかにこういう流れだと理解しています。

1. React を使いたい

  • やることは React.jsをインポートする。JQuery導入と同じ。怖くない。

2. JSXが登場

  • これまでのJavaScriptはHTMLに紐づくものだったけど、WEBサイト機能が複雑になってきたし機能単位でまとめた方がいいよね。JavaScript主体のJSXで書く方が便利。
  • JSXは Babel でコンパイルしないと使えない。Babel 登場。
  • Babelを使うのに Node.jsが必要。Node.jsも登場。

3. TypeScriptが登場

  • JavaScriptを直接書くより、最近のプログラミング言語っぽく書けるTypeScriptを使った方がいいよね。JSXじゃなくてTSXにしよう。
  • TSXの導入に伴い Babel は必要なくなった。でも TSXファイルをコンパイルするのに Node.js が必要なので、こいつは残ります。

4. webpackが登場

  • 機能の拡大と共にJavaScriptファイルが沢山増えてしまった。沢山あると読み込みが遅くなる。そこでwebpackです。こいつは一括で取り込めるようにまとめたJavaScriptを作成できます。ついでに圧縮(miniファイル作成)もできるよ。
  • TypeScriptのコンパイルを実行したり(コンパイルそのものは ts-loaderが行う)、どこにまとめたJavaScriptを置くかも担当します。
  • Webpackを使うのにもやっぱりNode.jsが必要です。

5. Reactを使う

  • 4で出力した JavaScriptを読み込めば使用できます。

 要はブラウザのスクリプト言語としてはJavaScriptがデファクトスタンダード。でもJavaScriptは使いづらいから、それを何とかしようと色々している結果、今現在のような複雑なことになっているのだと思います。

前提

 既存プロジェクトとして、ここでは、ASP.NET MVC5とします。.NET Coreじゃなく.NET Framework 4.7.2 の方にしてみます。(その方が既存プロジェクトっぽいし、.NET Coreの方はテンプレートあるしね……)
 IDEは Visual Studio 2019 Community で確認していますが、Visual Studio 2017でも大丈夫でしょう。

テンプレート通りに作成(既存プロジェクトのつもり)

ASPNet.PNG
MVC5.PNG
開始.png

npmを導入

npmとは

 各種パッケージを管理するものです。Visual Studioのデフォルトとしてある Nugetと同じような機能です。
 同じような機能を二つ使うのはややこしいですが、Nugetに無いので仕方がありません。フロントエンドのパッケージを管理するのが npm、サーバーサイドのパッケージを管理するのが、Nugetと分けるのがよさそうです。
(※デフォルトでは NugetでJQueryやBootstrapを管理しているので、後々削除する必要があります)

拡張機能のインストール

 Visual Studioではデフォルトでは npm を使えないので、拡張機能の管理を呼び出します。
拡張機能開始.png

 ここでは、NPM Task Runner と Package Installerを入れておきます。
NPM関連.png

 WebPack Task Runner もあとで使うので入れておきます。
webpackTaskRunner.png

 一度 Visual Studioを閉じてインストールを実行します。
拡張機能インストール確認png.png

npmでReactをインストール

 ソリューション エクスプローラー で右クリックをして、Quick Install Packagesを選択します。
QuickInstallPackage.png

 npm を選び、react のバージョンを16.8.6(現時点の最新版)を選択し、Installを実行します。同じように react-domもインストールします。
npmInstall.png

 すると、プロジェクトの直下に packeage.json が作られているのが確認できます。これがパッケージを管理するファイルになります。プロジェクト管理にはなっていませんが、package-lock.jsonファイルと node_modulesフォルダも作成されていることが確認できます。node_modulesにパッケージの実体が存在します。

NPMInstall後.PNG
(参考)
package-lock.jsonについて知りたくても聞けなかったこと

package.jsonの変更

 このまま必要なパッケージをnpmコマンドでインストールしていってもいいのですが、直接package.jsonを書き換えた方が早いのでそうします。

packagejson書き換え.PNG

修正後のpackage.json
{
  "name": "myproject",
  "version": "1.0.0",
  "scripts": {
    "build": "webpack",
    "watch": "webpack -w"
  },
  "devDependencies": {
    "ts-loader": "^5.4.3",
    "typescript": "^3.4.4",
    "webpack": "^4.30.0",
    "webpack-cli": "^3.3.1"
  },
  "dependencies": {
    "@types/react": "^16.8.14",
    "@types/react-dom": "^16.8.4",
    "react": "^16.8.6",
    "react-dom": "^16.8.6"
  },
  "private": true
}

 package.jsonの中身の詳細については下記ページが勉強になります。

変更後のpackage.jsonのパッケージをインストール

 Visual Studio のメニューの 表示 -> その他のウィンドウ -> タスクランナー エクスプローラーを表示します。
taskRunner.png

 Defaultsでインストールを実行します。
taskRunner2.png
 インストール終了。
taskRunner3.png

 インストールが成功すると、node_modulesフォルダ内のパッケージが増えていることが確認できます。
npmのinstall後のnodemodule.PNG

(注釈)ここまで「あれ?」と思った方もいると思います。package.jsonを作成して、直接書き換えることが出来るならば「Package Installer」は必要なさそうと思うかもしれません。確かにそうなのですが、今後追加でインストールしたいものが出来た時に便利です。

TypeScriptの設定

 新しい項目の追加で、tsconfig.json を追加します。
typescriptの設定ファイル.png

 そして、tsconfig.json を次のように変更します。

{
  "compilerOptions": {
    "sourceMap": true,
    "target": "es5",
    "module": "es2015",

    "jsx": "react",
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "lib": [
      "es2019",
      "dom"
    ]
  }
}

 tsconfig.json の中身の詳細については package.json と同じく下記ページを参考にしています。

webpackの設定

 新しい項目の追加で、webpack.config.js を追加します。

webpackの設定ファイル.png

 そして、webpack.config.js を次のように変更します。
 ここでは「entry」に設定されている "./src/main.tsx"のファイルを ./dist/main.js として変換すると設定しています。


module.exports = {
    // モード値を production に設定すると最適化された状態で、
    // development に設定するとソースマップ有効でJSファイルが出力される
    mode: "development",

    entry: "./src/main.tsx",

    // ファイルの出力設定
    output: {
        //  出力ファイルのディレクトリ名
        path: `${__dirname}/dist`,
        // 出力ファイル名
        filename: "main.js"
    },

    module: {
        rules: [
            {
                // 拡張子 .ts もしくは .tsx の場合
                test: /\.tsx?$/,
                // TypeScript をコンパイルする
                use: "ts-loader"
            }
        ]
    },
    // import 文で .ts ファイルを解決するため
    resolve: {
        extensions: [".ts", ".tsx", ".js", ".json"]
    }
};

 webpack.config.js の中身についてもこちらを参考に(というかコピー)しています。

TSXファイルの追加と変更

 新しい項目の追加で、TypeScript JSXファイルを追加します。場所は上記 webpack.config.js で指定した./src/main.tsxです。

tsxの作成.png

 内容は create-react-app のHello Worldみたくしてみます。

main.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

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

 同じくTypeScript JSXファイルを./src/App.tsx に追加します。

App.tsx
import React from 'react';

const App: React.FC = () => {
    return (
        <div className="App">
            <header className="App-header">
                <p>
                    Hello, World!!
                </p>
                <a
                    className="App-link"
                    href="https://reactjs.org"
                    target="_blank"
                    rel="noopener noreferrer"
                >
                    Learn React
                </a>
            </header>
        </div>
    );
}

export default App;

WebPack Task Runnerでコンパイル

 WebPack Task Runnerを使って、TypeScriptのコンパイルを実行します。
webpackTaskRunner実行.PNG

実行結果
webpackTaskRunner実行結果.PNG

 コンパイルが無事に実行されると ./dist/main.js が作成されます。
distが出来る.PNG

 以後、TSX(TypeSciprt) が変更されるたびにコンパイルするのは面倒なので、ビルドする前にWebPack Task Runnerでコンパイルが走るようにバインドしておきます。
バインド設定.png

main.jsをHTML側で呼び出す

 main.jsを使うために、適当な index.cshtml を変更します。

index.cshtmlを変更

@{
    ViewBag.Title = "Home Page";
}

<div id="root"></div>
<script src="~/dist/main.js"></script>

ビルドして動作確認

 ビルドして、Hello World! が確認できれば無事に React が使えていることになります。

動いた.PNG

おわりに

 登場人物がたくさん出てきて混乱してしまいますが、一つ一つ誰が何をやっているかを理解していければ大丈夫だと思います。色々やってますけど、最終的にはJavaScriptになるというだけです。
 逆に理解しないまま「とりあえずサンプルあるし~」と進めていくと、上手く行っている時はいいのですが、トラブル発生時にどこに問題が発生しているのか分からないことになります。というか、なった。

参考資料

10
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
6