ひとりでのアプリ開発 - fineの備忘録 -

ひとりでアプリ開発をするなかで起こったことや学んだことを書き溜めていきます

Node.js・React:Visual Studioでのアプリの開発環境を整える②

初めに

 本記事では、Visual Studio でNode.js と React を用いたアプリの開発をするための開発環境を整える方法をまとめます。本記事は、「Node.js・React:Visual Studioでのアプリの開発環境を整える①」の続きとなります。

前提

 本記事は、「Node.js・React:Visual Studioでのアプリの開発環境を整える①」の続きとなります。先にそちらをご覧いただくことを推奨いたします。

fineworks-fine.hatenablog.com

プロジェクトの構造の確認

最上位 ソリューション(.sln)
上位 プロジェクト(.njsproj)
プロジェクト内 npm ノード
package.json
プロジェクトファイル(server.js)

最上位:ソリューション(.sln)

 最上位レベルにあるのは "ソリューション" です。既定では、名前はプロジェクトと同じです。 ディスク上の .sln ファイルで表されるものがソリューションになります。

 .sln ファイルは、Visual Studio でプロジェクトを整理するための構造ファイルで、ソリューションファイルといいます。詳細は下のドキュメントをご覧ください。

learn.microsoft.com

プロジェクト(.njsproj)

 次にプロジェクトがあります。ディスク上では、.njsproj ファイルで表されます。

 プロジェクト内は、次の3つで構成されています。

  • npm ノード
  • package.json
  • プロジェクトファイル
npm ノード

 npm ノードには、インストールされているすべての npm パッケージが表示されます。

 npm とは、Node Package Manager のことで Node.jsのパッケージ(Package )を管理する(Manager)ツールです。パッケージをインストールすることで、さまざまな便利な機能を追加することができます。

 npm パッケージのインストールの仕方は後述します。

package.json

 ローカルにインストールされたパッケージの依存関係とバージョンを管理するために、npm には package.json ファイルを使用します。

プロジェクトファイル

 プロジェクトファイルです。デフォルトでは、server.js という名前で次のように Hello World と表示するコードになっています。

'use strict';
var http = require('http');
var port = process.env.PORT || 1337;

http.createServer(function (req, res) {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('Hello World\n');
}).listen(port);

 プロジェクトのスタートアップ ファイル server.js は太字で表示されています。

 プロジェクトでファイルを右クリックし、 [Node.js スタートアップ スクリプトとして設定] を選択することで、スタートアップ ファイルを設定できます。

npm パッケージの追加

 React や Web フレームワークを使うために npm パッケージを追加していきます。今回は、公式ドキュメントにあるようにパッケージを追加していきます。

npm パッケージ 説明
react UI を作ることに特化した JavaScriptフレームワーク
react-dom React 要素とブラウザ上のDOMを接続
React 要素の画面への出力するなど
express Web アプリケーションとモバイル・アプリケーション向けの一連の機能を提供する最小限で柔軟なWeb アプリケーション・フレームワーク
path ファイルおよびディレクトリのパスを操作するためのユーティリティを提供
ts-loader webpackにTypeScriptの変換処理を組み込むloader
typescript TypeScript サポートを追加
webpack モジュールバンドラー
JavaScript等の複数のファイルを1つにまとめる
webpack-cli webpackのcli
cli は Command Line Interface のことでコマンドプロンプトのようなもの

 次の手順で npm パッケージをインストールします。

  1. ソリューション エクスプローラーで npm ノードを右クリックし、「新しい npm パッケージのインストール」をクリック
  2. 「新しい npm パッケージのインストール」ダイアログ ボックスで、react パッケージを探し、「パッケージのインストール」を選択してインストール

 インストールされると、ソリューション エクスプローラーの npm ノードの下に react パッケージが表示されます。

 また、package.json ファイルが、パッケージのバージョンなど、新しいパッケージの情報で更新されます。

 ※UI を使って残りのパッケージを 1 つずつ検索して追加するのではなく、package.json の dependencies セクションに追加したいパッケージとそのバージョンを記述し、npm ノードを右クリック、「npm パッケージのインストール」をクリックする方法もあります。この方法では、一気にすべてのパッケージをインストールすることができます。詳細はドキュメントをご覧ください。

プロジェクトファイルの追加

 次の 4 つのファイルをプロジェクトに追加します。

  • app.tsx(TypeScript JSX ファイル)
  • webpack-config.js(JavaScript ファイル)
  • index.html(HTML ファイル)
  • tsconfig.json(TypeScript JSON 構成ファイル)

 ファイル追加の手順は次の通りです。

  1. ソリューションエクスプローラーで右クリックし、追加 > 新しい項目をクリックする
  2. 「新しい項目の追加」ダイアログ ボックスで追加したいファイルの形式を選択し、ファイル名を入力後、追加ボタンをクリックする


アプリのコードを追加

 server.js、app.tsx、index.html にコードを追加します。

server.js
/*  もとのコードをコメントアウト
'use strict';
var http = require('http');
var port = process.env.PORT || 1337;

http.createServer(function (req, res) {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('Hello World\n');
}).listen(port);
*/

// 以下のコードを追加
'use strict';
var path = require('path');
var express = require('express');

var app = express();

var staticPath = path.join(__dirname, '/');
app.use(express.static(staticPath));

// Allows you to set port in the project properties.
app.set('port', process.env.PORT || 3000);

var server = app.listen(app.get('port'), function () {
    console.log('listening');
});

 Express を使用し、Web アプリケーション サーバーとして Node.js を起動します。 このコードにより、ポートはプロジェクトのプロパティに構成されているポート番号(既定値は 1337)に設定されます。

app.tsx
declare var require: any

var React = require('react');
var ReactDOM = require('react-dom');

export class Hello extends React.Component {
    render() {
        return (
            <h1>Welcome to React!!</h1>
        );
    }
}

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

 メッセージを表示するために JSX 構文と React が使用されています。

index.html
<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <div id="root"></div>
    <!-- scripts -->
    <script src="./dist/app-bundle.js"></script>
</body>
</html>

 この HTML ページは app-bundle.js を読み込みます。app-bundle.js ファイルは、現在、空ですが、プレーンな JavaScript にトランスパイル(変換)された JSX と React のコードが含まれるようにしていきます。

webpack と TypeScript のコンパイラオプションを構成する

 webpack-config.js に webpack 構成コードを追加します。JSX をバンドルしてプレーンな JavaScript にトランスパイル(変換)するための入力ファイル (app.tsx) と出力ファイル (app-bundle.js) を指定する、webpack の簡単な構成を追加します。

webpack-config.js

 webpack-config.js を開き、コードを追加します。

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

 entry の部分に "./app.tsx"、output の部分に "./app-bundle.js" と入力されており、JavaScript にトランスパイルするための入力ファイルと出力ファイルを指定していることが分かります。

tsconfig.json

 tsconfig.json を開き、次のように追記していきます。

{
  "compilerOptions": {
    "noImplicitAny": false,
    "module": "commonjs",
    "noEmitOnError": true,
    "removeComments": false,
    "sourceMap": true,
    "target": "es5",
    "jsx": "react"
  },
  "exclude": [
    "node_modules"
  ],
  "files": [
    "app.tsx"
  ]
}

 "jsx": "react" の部分と "files:["app.tsx"] の部分が追記された箇所になります。

JSX をトランスパイルする

 この状態で実行をすると、次のようにエラーが発生します。

 エラーの原因は、まだ JSX をトランスパイル(変換)していないことにあります。

 JSX は JavaScript XML のことで、JavaScript を拡張して、UI 要素を記述するのに HTML のようなタグ構文が使えるようにしたものです。

 トランスパイルとは、トランスコンパイルのことであるプログラミング言語を別の言語に変換することを指します。

 そのため、app.tsx(TypeScript JSX ファイル)を JavaScript に変換し、app-bundle.js に出力するという作業をする必要があります。

 次の手順で、JSX をトランスパイルします。

  1. プロジェクト名を右クリックし、「ここでコマンドプロンプトを開く」を選択する
  2. コマンドプロンプトが開き、現在のプロジェクトにいることが確認できる
  3. コマンド プロンプトで、次の webpack コマンドを入力する

    node_modules\.bin\webpack --config webpack-config.js


  4. 下のように successfully と表示されたら ok です。

    エラーが起きた場合は、npm パッケージのバージョンによるものだと考えられますので、最新のバージョンをインストールして、再度、試してみてください。

  5. プロジェクトノードを右クリックし、 [追加]>[既存のフォルダー] を選択する

  6. dist フォルダーを選択し、「フォルダーの選択」をクリックする

  7. dist フォルダがプロジェクトに追加され、app-bundle.js と app-bundle.js.map が含まれていることが確認できる

  8. app-bundle.js を開き、トランスパイルされた JavaScript コードを表示する

 これで、app.tsx(TypeScript JSX ファイル)が JavaScript に変換され、app-bundle.js に出力されました。外部で変更されたファイルを再度読み込むかどうかを確認される場合があるようです。そのときは、"Yes to All(すべてはい)" を選択してください。

 この変換作業は、app.tsx を変更する度に行う必要があります。つまり、app.tsx を修正するたびに、上記の流れをする必要があるということ。これは流石に面倒なので、この手順を自動化しておきます。

JSX をトランスパイルするビルドスクリプトを追加する

 Visual Studio 2019 以降の Visual Studio バージョンにはビルドスクリプトが必要なようです。

 ここで、先ほどインストールした webpack-cli を使用します。JSX をトランスパイルするビルドスクリプトを追加することで、上記のようにトランスパイルするのではなく、Visual Studio からビルドするときに自動で JSX をトランスパイルすることができるようになります。

 JSX をトランスパイルするビルドスクリプトを追加する手順は次の通りです。

  1. package.json を次のように追記する

    {
      "name": "nodejs-web-app1",
      "version": "0.0.0",
      "description": "NodejsWebApp1",
      "main": "server.js",
      "author": {
        "name": ""
      },
      "devDependencies": {
        "eslint": "^8.21.0"
      },
      "eslintConfig": {},
      "dependencies": {
        "express": "^4.18.2",
        "path": "^0.12.7",
        "react": "^18.2.0",
        "react-dom": "^18.2.0",
        "ts-loader": "^9.4.4",
        "typescript": "^5.2.2",
        "webpack": "^5.88.2",
        "webpack-cli": "^5.1.4"
      },
      "scripts": {
        "build": "webpack-cli --config webpack-config.js"
      }
    }
    


 追記されたのは次の部分だけです。

"scripts": {
 "build": "webpack-cli --config webpack-config.js"
}

(実行結果)

ブレークポイント、デバッガについて

 ひとまず、これで React を使用した Node.js アプリの開発環境を Visual Studio を使って整えることがほぼできました。

 Microsoft のドキュメントには、サーバー側のブレークポイントの設定とクライアント側の React コードにブレークポイントを設定についても記載されています。興味がある方は参考のリンク先からご覧ください。