10
6

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 1 year has passed since last update.

React+TypeScriptの環境構築(create-react-appなし)

Last updated at Posted at 2022-01-03

create-react-appを使用せずにReact+TypeScriptの環境構築について解説します。(個人開発の備忘録も兼ねているので、何か気づいたことがあれば教えていただけると嬉しいです。)

create-react-appを使用しない理由

create-react-appを使用すると、簡単にReactのプロジェクトを作成することができるが、webpack(JSやCSSなどのリソースファイルを1つにまとめたり、JSXのような特殊な記法で書かれたファイルを変換するツール)の設定が隠蔽されているため、プロジェクトに応じてloaderやpluginを新たに読み込むことが難しくなります。

build周りの設定がブラックボックス化してしまうため、今回はcreate-react-appを使用せずに環境構築を行なっていきます。

##構成
最終的なフォルダとファイル構成は以下のとおり。

react_app/
  ├ node_modules/
  ├ dist/
       └ bundle.js
  ├ public/
       └ index.html
  ├ src/
       ├ App.tsx
       └ index.tsx
  ├ package-lock.json
  ├ package.json
  ├ tsconfig.json
  └ webpack.config.json

1. 準備

適当なディレクトリを作成し、必要なモジュールをインストール。

#プロジェクトのフォルダを作成
$ mkdir react_app
$ cd react_app

#package.jsonを作成
$ npm init -y

#typescriptをインストール
$ npm i -D typescript

#webpackをインストール
$ npm i -D webpack webpack-cli webpack-dev-server

#loaderをインストール
$ npm i -D ts-loader

#pluginをインストール
$ npm i -D html-webpack-plugin

#React、ReactDOMをインストール
$ npm i react react-dom

#型定義ファイルをインストール
$ npm i -D @types/react @types/react-dom
  • typescript(typescript本体)
  • webpack
    • webpack(webpack本体)
    • webpack-cli(webpackコマンドを使うために必要なパッケージ)
    • webpack-dev-server(開発環境用のローカルサーバー)
  • loader
    • ts-loader(webpackからtypescriptを読み込むために必要なローダー)
  • plugin
    • html-webpack-plugin(webpackが生成したバンドルファイルを指定したhtmlに埋め込む)
  • react
    • react(React本体)
    • react-dom(ReactのDOMライブラリ)
    • @types/react(reactの型定義)
    • @types/react-dom(react-domの型定義)

######補足
パッケージインストール時にオブション -D をつけると、package.jsonのdevDependenciesに記録される。
webpackやtypescriptなど開発専用のパッケージはdevDependenciesインストールする。

2. package.jsonの編集

ルートディレクトリのpackage.jsonを以下のように編集。
script.testを削除して、script.start(開発環境用のローカルサーバー起動コマンド)とscirpt.build(webpack.config.jsonで設定した自前のbuildコマンド)を追加。

package.json
{
  "name": "portfolio",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
-   "test": "echo \"Error: no test specified\" && exit 1",
+   "build": "webpack",
+   "start": "webpack-dev-server"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/react": "^17.0.38",
    "@types/react-dom": "^17.0.11",
    "html-webpack-plugin": "^5.5.0",
    "ts-loader": "^9.2.6",
    "typescript": "^4.5.4",
    "webpack": "^5.65.0",
    "webpack-cli": "^4.9.1",
    "webpack-dev-server": "^4.7.2"
  },
  "dependencies": {
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  }
}

3. webpack.config.jsの作成

ルートディレクトリにwebpack.config.jsを作成。

webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    //モードをdevelopment、production、noneから設定(必須)
    //development: 開発時のファイル出力モード(最適化より時間短縮、エラー表示を優先)
    //production: 本番時のファイル出力モード(最適化されて出力)
    mode: 'development',
    //メインとなるjsファイル(エントリーポイント)
    entry: './src/index.tsx',
    //ファイルの出力設定
    output: {
        path: path.join(__dirname, '/dist'), //出力先のディレクトリ(絶対パスで指定)
        filename: 'bundle.js' //出力ファイル名
    },
    //デバッグのためのSourceMap(ビルド前後の対応関係を記述したファイル)の出力設定
    devtool: 'inline-source-map',
    //対象のファイルを変換するためのloaderを設定
    module: {
        rules: [
            {
                test: /\.tsx?$/, //build対象(loaderを適用するファイル)を指定
                loader: 'ts-loader', //適用するloaderを指定
            }
        ]
    },
    //importの際に省略する対象の拡張子を配列で指定
    resolve: {
        extensions: ['.ts', '.tsx', '.js', '.json'] //指定されている拡張子のファイルはimportの際に拡張子を省略できる
    },
    //webpack-dev-serverの設定
    devServer: {
        static: path.join(__dirname, '/dist'), //表示する静的ファイル(HTML)の場所を指定
        open: true, //ブラウザを自動的に起動
        port: 3000 //ポート番号を指定(デフォルトのポート:8080)
    },
    //pluginの設定
    plugins: [
        new HtmlWebpackPlugin({ //webpackでbuildされたJSやCSSを表示するHTMLを自動的に生成するplugin
            template: './public/index.html', //テンプレートとして使用するHTMLファイルを指定
            filename: 'index.html' //生成するHTMLファイル名
        })
    ]
}

4. tsconfig.jsonの作成

以下のコマンドを実行して、TypeScriptの設定ファイルを作成します。

$ tsc --init

作成されたtsconfig.jsonの内容を一部修正します。
(コメント文は省略)

tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
+   "jsx": "react",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  }
}

5. HTML

ルートディレクトリにpublicフォルダを作成して、その中にindex.htmlを作成

public/index.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>react_app</title>
    </head>
    <body>
        <div id="app"></div>
    </body>
</html>

6. React App

ルートディレクトリにsrcフォルダを作成して、その中にindex.tsxとApp.tsxを作成

src/index.tsx
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'

ReactDOM.render(
    <App />,
    document.getElementById('app')
)
src/App.tsx
import React from 'react'

const App = () => {
    return (
        <div>
            <h1>Hello React!</h1>
        </div>
    )
}

export default App

7. webpackの実行

package.jsonで設定したscriptを実行。
npm run build を実行し、webpackがdist/bundle.jsを生成。
npm run start を実行し、http://localhost:3000にアクセスすると'Hello React!'と表示される。

$ npm run build #webpackの実行
$ npm run start #webpack-dev-serverの起動
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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?