2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

React + TypeScript + webpackで作るWebアプリケーション

Posted at

概要

以下の技術を用いた簡単な静的Webアプリケーションを作る環境を学習がてら構築したので備忘録として残します。

使用技術
React
TypeScript
Sass
webpack

リポジトリ

https://github.com/enuswi/react-app

本投稿時点のcommit

https://github.com/enuswi/react-app/commit/a74409890292c4e96140361d682a4ec869510a89

*cloud9(EC2)環境上であれば上記リポジトリのREADME「開発セットアップ(Cloud9)」の通りで動作確認できると思います(2020.01.06)

構成

・
├── dist ...ビルドされたファイルが出力されるフォルダ。
│   ├── index.html
│   ├── main.bundle.js
│   └── style.css
├── node_modules
├── src ...実際に作業するフォルダ。
│   ├── index.html
│   ├── main.tsx
│   └── style.scss
├── package-lock.json
├── package.json
├── tsconfig.json ... typescriptの設定ファイル
└── webpack.config.js ...webpackの設定ファイル

srcフォルダ

実際に作業するフォルダ。
ここのファイルを編集していきます。

distフォルダ

ビルドされたファイルが出力されるフォルダ。
ここに出力されたファイルをS3におけば簡単に公開もできます。

tsconfig.json

TypeScriptファイルをコンパイルするのに必要な設定を指定します。
今回は使用していませんが、filesプロパティやincludeプロパティを用いることでコンパイルするファイルを指定することもできるみたいです。

tsconfig.json
{
    "compilerOptions": {
        "sourceMap": true,
        "target": "es5",        // TSはECMAScript 5に変換
        "module": "es2015",     // TSのモジュールはES Modulesとして出力
        "jsx": "react",         // JSXの書式を有効に設定
        "moduleResolution": "node",
        "lib": [
            "es2019",
            "dom"
        ]
    }
}

compilerOptions

...その名の通り、コンパイルする際のオプション設定です。
各オプションにはデフォルトが設定されている為、省略も可能です。
以下、使用オプションのみ簡単に説明します。

sourceMap

boolean型 (default: false)
...対応する.mapファイルを生成します。

↓今回で言えば以下の表の形で生成することができます。

コンパイルしたファイル(.js .css) ソースマップファイル(.map)
main.bundle.js  main.bundle.js.map
style.css style.css.mapp

ソースマップファイルを一緒に配置すると

ブラウザが元のソースを再構築し、それを開発者ツールから確認できるようになります。圧縮されたファイルやトランスパイルされた今回のTypeScriptのファイルのようなファイルをデバッグするのには役立ちそうです。

*あくまで開発時に使うもの(の認識)なので、ファイルの取り扱いには注意が必要かなと思いました。
*画像はChromeの開発者ツール表示

  1. ソースマップファイルなし
screenshot 2020-01-05 18.35.07.png 2. ソースマップファイルあり screenshot 2020-01-05 19.06.19.png

target

string型 (default: ES3)
...対象とするECMAScriptのバージョンを指定します。

module

string型 (default: targetプロパティの値により変化)
...モジュールの方式を指定します。

jsx

string型 (default: Preserve)
...(.tsx)ファイルのJSXをサポートします。
モードはPreserveかreactの2種類あり今回はreactを選択します。

ReactにおけるJSXはReact.createElement()の糖衣構文です。
jsxの設定をすることでReact.createElement()の形にコンパイルしてくれます。

main.tsx
class Game extends React.Component {...}

// ↓これを
ReactDOM.render(
    React.createElement(
        Game, {}, null
    ),
    document.getElementById('root')
);

//↓このように書き換えることが出来ます。ちょっとスッキリ。
ReactDOM.render(
    <Game />,
    document.getElementById('root')
);

moduleResolution

string型 (default: Classic)
... モジュールをどのように解決するのかを決定します。
モードはnodeとClassicの2種類があり今回はnodeを選択しています。
nodeモードではnode.jsのモジュール解決アルゴリズムを真似たアルゴリズムが用いられます。
*細かいアルゴリズムについては今度調べてみようと思います。

lib

string[]型 (default: targetプロパティの値により変化)
...コンパイルに含めるライブラリのファイルの一覧を指定します。

*各オプションについては以下で詳しくまとめられております
http://js.studio-kingdom.com/typescript/project_configuration/compiler_options

webpack.config.js

webpackを用いてビルドを行うのでその為の設定を行います。

webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
    //mode: "development",
    mode: "production",
    devtool: "source-map",

    entry: {
        main: "./src/main.tsx",
    },
    output: {
        path: path.join(__dirname, "/dist"),
        filename: "[name].bundle.js"
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: "ts-loader"
            },
            {
                test: /\.scss$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'sass-loader'
                ]
            }
        ]
    },
    resolve: {
        extensions: [".ts", ".tsx", ".js", ".json"]
    },
    plugins: [
        // index.htmlファイルをdist以下に配置
        new HtmlWebpackPlugin({
            inject: true,
            template: "src/index.html"
        }),
        new MiniCssExtractPlugin({
            filename: "style.css"
        })
    ],

    // cloud9用の設定
    devServer: {
        contentBase: path.resolve(__dirname, "dist"), // dist以下のファイルを監視
        port: 8080,
        host: "0.0.0.0",
        disableHostCheck: true
    }
};

devTool

...デベロッパーツールの設定です。ここに「source-map」を指定しないと先ほどのtsconfig.jsonにてsourceMapを有効にしていてもビルドされません。

entry

...ビルド時の起点となるファイルです。エントリポイントと呼びます。
このファイルからモジュール等の依存関係を整理して後述のoutputで指定した形式でファイルに出力します。

output

...ビルドしたファイルの形式を指定します。
今回の設定では、「dist」というフォルダに「(元ファイル名).bundle.js」という名前で保存するようにしています。

resolve.extensions

...モジュールの解決に使用される拡張子の配列を指定します。

plugins

...拡張プラグインを追加します。

html-webpack-plugin

...コンパイル時にdist以下にindex.htmlも生成させる為に使用しました。
dist以下をgit管理したくなかったのでsrc以下にindex.htmlを配置しビルド時に一緒に生成するようにしています。

mini-css-extract-plugin

...コンパイル時にscssファイルをcssとして生成する為に使用しました。

devServer

...cloud9動作確認用の設定です。
dist以下に変更が加わった際にリロードがかかる(はず)

動作確認

上記必要な設定ファイルが用意できたら動作確認を進めていきます。
cloud9上であれば以下のコマンドとコンソール画面に対するアクションで確認することができます。

$ cd react-app
$ npm start

コンソール画面におけるアクション

「Preview」 => 「Preview Running Application」
screenshot 2020-01-05 11.35.16.png ↑Reactのチュートリアルで作成したアプリです。(○×ゲーム)

ビルドを実行すればdistフォルダとビルドの成果物が作成されます。

$ npm run build

さいごに

今までLaravel等のフレームワーク(以下、FW)を利用していて、FWがよしなにやってくれていることがたくさんあることは理解していました。
2020年は、基本的にはFWが頑張ってくれている部分を勉強する年にしたいと思っての備忘録をアップしていければと思っております。
間違い等ございましたらご指摘くださいますと幸いです。

次回は、先ほど作ったアプリケーションをS3に配置して公開してみようと思います。

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?