クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

【React】React + TypeScriptの開発環境を作る(デプロイまで)

Reactの続きです。前回までReactのいろいろなCSS環境を試しました。今回からはReactとTypeScriptの開発環境を作ります。Create React AppでのTypeScript導入方法があったのでトライ。GitHub Pagesのデプロイまでできました。それではいきましょう!

【目次】

※参考:前回記事
【React】UIフレームワークMaterial UIでマテリアルデザインを事始める - クモのようにコツコツと

※参考:Reactを習得するためにやったことまとめ qiita.com

前回までのおさらい

ReactのいろいろなCSS設定方法について調べた

※参考:ReactのCSS設定方法について調べたこと(className属性、style属性、CSS Modules、CSS in JS、UIフレームワーク) - クモのようにコツコツと

CSS ModulesでCSSとSass(SCSS)のローカルスコープを作る

※参考:【React】CSS ModulesでCSSとSass(SCSS)のローカルスコープを作る - クモのようにコツコツと

styled-componentsでCSS in JSを事始め

※参考:【React】styled-componentsでCSS in JSを事始める - クモのようにコツコツと

Material UIでマテリアルデザイン事始め

※参考:【React】UIフレームワークMaterial UIでマテリアルデザインを事始める - クモのようにコツコツと

CSSについてはここで一区切りにして、今回からはTypeScriptをReact環境で使う方法を調べる。

Reactでも型を付けたい!

以前、TypeScriptを含むメタ言語開発環境を作った。

※参考:【メタ言語】フロントエンド開発スターターキットを作った(EJS、Sass(SCSS)、TypeScript) - クモのようにコツコツと

※参考:【メタ言語】HTMLテンプレートエンジン、AltCSS、AltJSのまとめ(随時更新) - Qiita

Reactの場合はTypeScriptと同様にモジュールを分割した構造で開発はできる。しかし型チェックはできない。


Reactドキュメントでは型チェックの方法としてFlowとTypeScriptの事例を紹介している。

※参考:静的型チェック – React

FlowはReactと同じFacebookが開発している型チェッカー

※参考:Getting Started | Flow

しかしフロントエンド界隈ではTypeScriptの方が多く採用されているようなのでこれを使ってみる。(使い方、書き方はどちらも似ているようだった)

Create React AppをTypeScript付きでインストール

Create React AppのドキュメントにTypeScriptの導入方法があった

※参考:Adding TypeScript | Create React App


Create React Appインストール時にオプション--template typescriptを追加

$ npx create-react-app (アプリ名) --template typescript

自分の場合こうなる(プロジェクト名react-typescript-test

$ npx create-react-app react-typescript-test --template typescript

この時点でTypeScriptの設定ファイル「tsconfig.json」も自動で作られていた!

※参考:react-typescript-test/tsconfig.json at main · ryo-i/react-typescript-test · GitHub

ローカルでアプリを起動

「react-typescript-test」というフォルダができるので移動する

cd react-typescript-test

ローカル環境でアプリを起動!

npm start

localhost(3000)でブラウザが開く f:id:idr_zz:20210126064328j:plain 表示された!Reactロゴクルクル…

ファイルの中身の中身を確認

ファイルの中身を見てみる。

なお、前回(TypeScriptなし)のファイル構成はこちらを参照

※参考:【React】ReactプロジェクトのAppコンポーネントを書き換えてみる - クモのようにコツコツと

index.html

「public」フォルダに静的なファイルがある f:id:idr_zz:20210126064522j:plain


「index.html」を見てみる

<body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!-- 中略 -->
  </body>

noscript#rootのみがある。これは前回と変わらない。

index.tsx

「srs」フォルダがReactのファイル。拡張子がtsxになっている! f:id:idr_zz:20210126064624j:plain


「index.tsx」を開いてみる。冒頭でパッケージなどをインポート

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

ここは前回と変わらない。


HTMLレンダリング部分

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

Appコンポーネントを読み込んでいる。ここも前回と変わらない。

StrictModeについてはこちら

※参考:strict モード – React


最後にreportWebVitals()を実行

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

アプリのパフォーマンスの測定を開始する場合は、関数を渡します
結果をログに記録します(例:reportWebVitals(console.log))
または分析エンドポイントに送信します。 詳細:https://bit.ly/CRA-vitals

パフォーマンスの測定に使う関数のようだ。

※参考:Measuring Performance | Create React App

App.tsx

index.tsxで読み込まれている「App.tsx」を見てみる。

冒頭でパッケージなどをインポート

import React from 'react';
import logo from './logo.svg';
import './App.css';

ここも前回と変化なし。


App()コンポーネント部分

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

ここも前回と特に違いはないように見える。型の設定などは書かれていない。


最後にAppをエクスポート

export default App;

全体的に拡張子が「.tsx」になっただけで特に違いはないようだ。

これだけでもTypeScriptが型推論でチェックしてくれるはずなので問題ないということかな。

※参考:型推論 - TypeScript Deep Dive 日本語版

内容を打ち替えてみる

「App.tsx」のpタグ部分を打ち替えてみる

        <p>
          りあくと & たいぷ・すくりぷと、はじめました。
        </p>

ブラウザ確認。おお、打ち変わった! f:id:idr_zz:20210126065417j:plain

ファイルをビルド

ファイルをビルドしてみる。こちらのコマンド

npm run build

「build」フォルダが作られた!
f:id:idr_zz:20210126065459j:plain


「index.html」を見ると中身は圧縮されている。

<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>React App</title><link href="/static/css/main.8c8b27cf.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script><!-- 中略 --></script></body></html>

整形するとHTMLは#rootのみがある

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8"/>
        <link rel="icon" href="/favicon.ico"/>
        <meta name="viewport" content="width=device-width,initial-scale=1"/>
        <meta name="theme-color" content="#000000"/>
        <meta name="description" content="Web site created using create-react-app"/>
        <link rel="apple-touch-icon" href="/logo192.png"/>
        <link rel="manifest" href="/manifest.json"/>
        <title>React App</title>
        <link href="/static/css/main.8c8b27cf.chunk.css" rel="stylesheet">
    </head>
    <body>
        <noscript>You need to enable JavaScript to run this app.</noscript>
        <div id="root"></div>
        <script><!-- 中略 --></script>
    </body>
</html>

「index.html」をローカルで開くとブラウザ上は真っ白な画面。。 f:id:idr_zz:20210126065605j:plain

ビルドファイルを画面に表示するにはサーバ上にデプロイする必要がありそう。

GitHub Pagesにデプロイ

Create React AppをGitHub Pagesにデプロイする方法があった。

※参考:Deployment | Create React App

package.jsonにhomepageを追加

package.jsonにhomepageコマンドを追加。

"homepage": "https://(ユーザ名).github.io/(アプリ名)"

自分の場合こうなる

"homepage": "https://ryo-i.github.io/react-typescript-test"

gh-pagesインストール

gh-pagesというパッケージをインストール

npm install --save gh-pages

GitHubに「gh-pages」というブランチ を追加してくれうようだ。

Publish files to a gh-pages branch on GitHub (or any other branch anywhere else).

GitHubのgh-pagesブランチ(または他のブランチ)にファイルを公開します。 

※参考:gh-pages - npm

predeploy、deployコマンドを追加

package.jsonにpredeploydeployのコマンドを追加

"scripts": {
   "predeploy": "npm run build",
 "deploy": "gh-pages main -d build",
 // 中略
}

ドキュメントでは「masterを追加」とあったが

Tweak your package.json scripts to push deployments to master:

package.jsonスクリプトを微調整して、デプロイメントをマスターにプッシュします。 

自分のデフォルトブランチ名はmainなのでそうしてみた。

※参考:GitHub、これから作成するリポジトリのデフォルトブランチ名が「main」に。「master」から「main」へ変更 - Publickey

GitHub Pagesにデプロイ

GitHub Pagesにデプロイしてみる。下記のコマンド

npm run deploy

GitHubを開くと「gh-pages」ブランチが増えている! f:id:idr_zz:20210126070753j:plain

「gh-pages」開くとindex.htmlなど「build」フォルダの中身がデプロイされている f:id:idr_zz:20210126070816j:plain

※参考:GitHub - ryo-i/react-typescript-test at gh-pages

ブラウザで表示

GitHub Pages のURLを開いてみると…

※参考:React App

おお、今度は画面が表示された! f:id:idr_zz:20210126065417j:plain


Dev-toolsでファイルを見ると「.tsx」ファイルのまま動いている! f:id:idr_zz:20210126071614j:plain

GitHubで見るとこのファイルはないんだけどなー

※参考:react-typescript-test/static/js at gh-pages · ryo-i/react-typescript-test · GitHub


GitHubの設定画面では何も設定してないんだが、もう設定済みになっている♪ f:id:idr_zz:20210126071113j:plain


ソースコード(GitHub)

※参考:GitHub - ryo-i/react-typescript-test

プレビュー(GitHub Pages)

※参考:React App

最後に

ということで、Create React AppとTypeScriptの開発環境を作ることができました。拡張子が「.tsx」になるだけでコードの中身はほとんど違いがありませんでした。(型推論チェックが行われるはずなのでこれだけでも違うはず)

次は、以前作った「メタ言語スタートキット」の内容をReact + TypeScript環境に置き換えてみようと思います。HTMLはJSX、CSSはCSS in JSでやってみようかと。

※参考:【メタ言語】HTMLテンプレートエンジン、AltCSS、AltJSのまとめ(随時更新) - Qiita

構造がどう変わるのか比較してみたく。それではまた!


※参考:Reactを習得するためにやったことまとめ qiita.com