Help us understand the problem. What is going on with this article?

公式ドキュメントに沿ってTypescript + Express + React + Webpack を検証

More than 1 year has passed since last update.

Reactを実装するドキュメントは見つけられたけど、、

Javascript + Express のものがほとんどで、 TypeScript + Express でやってるドキュメントや前例がこれがなかなか無くて(´Д⊂

TypeScript公式ドキュメントにReactについてあるやんけ

React & Webpack · TypeScript
公式ドキュメントにTypeScriptでReactコンポーネントを表示することが解説されていたので、この手順にExpressでのルーティングを付け加えました。
バカ正直な部分もありますが、スループットするためにここにやったことを1から書き起こします。

Node.jsのインストール

Node.jsをインストールする際には、下記を参考とさせていただきました。
nodebrewがあるとバージョン管理が楽ですので、入れることをオススメします。
node.jsのversionを管理するためにnodebrewを利用する - Qiita
nodebrewを使ってLTS版を知る術は無い(と思う)ので、Node.jsのGithubを確認してください。
GitHub - nodejs/Release: Node.js Foundation Release Working Group

ディレクトリ構成

公式ドキュメントに沿って進めたいので、合わせて下記のようなディレクトリ構成にしました。

test-dir/
├── dist/
└── src/
    └── components/

イニシャライズ

test-dirディレクトリ直下で、npmパッケージとするためのコマンドを実行します。

npm init

すると、いろいろ質問されますが、ひとまずエンターをただただ押していって、、

Is this OK? (yes)

と聞かれたらyと打ってエンターキーを押すとpackage.jsonが生成されます。

package.json
{
  "name": "test-dir",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

Node.jsの他に必要なパッケージのインストール

今回の検証に必要なパッケージをインストールします。

Webpack

npm install --save-dev webpack webpack-cli

TypeScript

npm install --save-dev typescript awesome-typescript-loader source-map-loader

Express

npm install --save express @types/express

React

npm install --save react react-dom @types/react @types/react-dom

tsconfig.jsonを作成

TypeScriptの設定ファイルであるtsconfig.jsontest-dir/直下に作成します。

tsconfig.json
{
    "compilerOptions": {
        "outDir": "./dist/",
        "sourceMap": true,
        "noImplicitAny": true,
        "module": "commonjs",
        "target": "es5",
        "jsx": "react"
    },
    "include": [
        "./src/**/*"
    ]
}

Reactコンポーネントを作成

公式ドキュメントを参考にHelloコンポーネントを書きます。

src/components/Hello.tsx
import * as React from "react";

export interface HelloProps { compiler: string; framework: string; library: string; }

// 'HelloProps' describes the shape of props.
// State is never set so we use the '{}' type.
export class Hello extends React.Component<HelloProps, {}> {
    render() {
        return <h1>Hello from {this.props.compiler} and {this.props.framework} and {this.props.library}!</h1>;
    }
}

Helloコンポーネントをインポートするindex.tsxも作ります。
公式にはHelloコンポーネントのインポート方法と"React""react-dom"と異なることに注目と書いてありますね。

src/index.tsx
import * as React from "react";
import * as ReactDOM from "react-dom";

import { Hello } from "./components/Hello";

ReactDOM.hydrate(
    <Hello compiler="TypeScript" framework="Express" library="React" />,
    document.getElementById("example")
);

ReactコンポーネントをビルドしてレンダリングするHTMLを作成

Reactコンポーネントを表示するindex.htmlを作成します。

index.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Hello React!</title>
    </head>
    <body>
        <div id="example"></div>

        <!-- Dependencies -->
        <script src="./node_modules/react/umd/react.development.js"></script>
        <script src="./node_modules/react-dom/umd/react-dom.development.js"></script>

        <!-- Main -->
        <script src="./dist/bundle.js"></script>
    </body>
</html>

Expressのルーターを作成

これはTypeScriptの公式ドキュメントに書いてないのですが、Expressでルーティングする機能を盛り込みたいのでsrc/ディレクトリ以下にserver.tsを作成しました。

src/server.ts
var express = require('express');
var app = express();

app.use(express.static('./'));

app.listen(process.env.PORT || 3000, function () {
  console.log('express app is started.');
});

Webpackの設定ファイルを作成

これも公式ドキュメントに書いてあるのですが、server.tsを追加したのでこちらを少し改修しています。

webpack.config.js
module.exports = {
  target: "node",
  mode: "development",
  entry: {
    bundle: "./src/index.tsx",
    server: "./src/server.ts"
  },
  output: {
    filename: "[name].js",
    path: __dirname + "/dist"
  },

  // Enable sourcemaps for debugging webpack's output.
  devtool: "source-map",

  resolve: {
    // Add '.ts' and '.tsx' as resolvable extensions.
    extensions: [".ts", ".tsx", ".js", ".json"]
  },

  module: {
    rules: [
      // All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
      { test: /\.tsx?$/, loader: "awesome-typescript-loader" },

      // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
      { enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
    ]
  },

  // When importing a module whose path matches one of the following, just
  // assume a corresponding global variable exists and use that instead.
  // This is important because it allows us to avoid bundling all of our
  // dependencies, which allows browsers to cache those libraries between builds.
  externals: {
    react: "React",
    "react-dom": "ReactDOM"
  }
};

実行

webpackコマンドでビルドします。

webpack

するとdist/以下にビルドされたjavascriptファイルが生成されるので、それをnodeコマンドで実行します。
localhost:3000にアクセスすると、Reactコンポーネントが描画されます。

node dist/server.js

こういうコマンドは個人的に好きくないので、package.jsonにコマンドを登録しました。

package.json
{
  "name": "test-dir",
  ...
  "scripts": {
    "build": "webpack",
    "start": "node dist/server.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  ...
}

すると下記コマンドで同様なことができます。

npm run build
npm run start

最終的なディレクトリ構成

test-dir/
├── dist
│   ├── bundle.js
│   ├── bundle.js.map
│   ├── server.js
│   └── server.js.map
├── index.html
├── node_modules
│   ├── ...
├── package.json
├── src
│   ├── components
│   │   └── Hello.tsx
│   ├── index.tsx
│   └── server.ts
├── tsconfig.json
└── webpack.config.js

参考文献

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away