React+TypeScript+Webpackで環境構築
今回はReact+TypeScript+webpackの環境構築をしていきたいと思います。公式のドキュメントを参考になぞってみました。是非、一読してみてください。
前提としてnode
とnpm
はインストール済みで進めていきます。
作業ディレクトリを作成してください。
以下のディレクトリ構成で進めていきます。
proj/ ├─ dist/ └─ src/ └─ components/
ここでは、まだdist
フォルダを作成しなくても良いです。
後述しますが、webpackが自動で作ってくれます。
プロジェクトディレクトリ直下でnpm init -y
と実行してください。
そうするとpackage.jsonが生成されます。
webpackのインストール
まずグローバルにwebpackがインストールされているか確認してください。 まだインストールがされていなければ
npm i -g webpack
と実行してwebpackがインストールされていることを確認してください。
Reactのインストール
reactとreact-domをインストールしましょう。
npm i -D react react-dom @types/react @types/react-dom
ここで@typesという接頭辞が出てきて何ぞや?と思われた方もいると思います。この@typesというのはreact
とreact-dom
の型定義ファイルになります。
どんな型定義ファイルがあるかはこちらから確認ができます。
react単体で型定義をする場合は、PropTypesなどを作成すると思いますが、TypeScript 2から型定義ファイルの管理をnpmで行えるようになりました。
TypeScriptのインストール
npm install --save-dev typescript awesome-typescript-loader source-map-loader
この中のパッケージのawesome-typescript-loader
とsource-map-loader
はwebpackと一緒に使うときに必要になります。
awesome-typescript-loaderはwebpackがTypeScriptのスタンダードな設定ファイルであるtsconfig.jsonを使ってtypescriptのファイルをコンパイルしてくれます。
source-map-loaderはその名の通り、ソースマップを生成してくれます。
tsconfig.jsonの設定
tsconfig.jsonファイルをプロジェクトディレクトリ直下に作成し、以下のように設定してください。
{ "compilerOptions": { "outDir": "./dist/", "sourceMap": true, "noImplicitAny": true, "module": "commonjs", "target": "es5", "jsx": "react" }, "include": [ "./src/**/*" ] }
outDir
- 出力先のディレクトリの設定
sourceMap
- ソースマップの有無。
noImplicitAny
- 厳密に型を決めるときなど、暗黙のanyの型はエラーとすることができます。
module
- moduleコードの生成方法
target
- トランスパイルする先の、ECMAScript の ターゲット・バージョンになります.。
詳細を知りたい方はこちらで確認してください。
Let's Write Code
実際にReactを使ってTypeScriptを書いていきましょう。
まず、Hello.tsxというファイルをsrc/components
直下に配置してください。
import * as React from "react"; export interface HelloProps { compiler: string; framework: string; } export const Hello = (props: HelloProps) => <h1>Hello from {props.compiler} and {props.framework}!</h1>;
こちらはステートレスコンポーネントで記述しています。 文字通り、何か状態を保持ている状態ではなく、描画するためだけのコンポーネントになります。
クラス構文を使って記述すると以下のようになります。
import * as React from "react"; export interface HelloProps { compiler: string; framework: 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}!</h1>; } }
コードの中にこのような記述があります。
React.Component<HelloProps, {}>
ComponentはReact.Component<P, S>
を extends したクラスを作成します。
P
は props の型、 S
は state の型となります。
次にindex.tsxをsrc直下に追加します。
import * as React from "react"; import * as ReactDOM from "react-dom"; import { Hello } from "./components/Hello"; ReactDOM.render( <Hello compiler="TypeScript" framework="React" />, document.getElementById("example") );
ここでは単純にindex.tsxにHello.tsxをインポートしてReact.DOMのrederメソッドでレンダリングしています。
次にHello.tsxの内容を表示させるために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>
webpackの設定ファイルを作成
プロジェクトディレクトリの直下にwebpack.config.jsファイルを作成してください。
module.exports = { entry: "./src/index.tsx", output: { filename: "bundle.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" }, };
上記のexternals
とあると思いますが、React.jsのプロジェクトでは、webpackによるビルド時のデフォルト挙動がReact.jsライブラリ自体もビルドするため、時間がかかります。
そこでexternals指定してReact.jsをビルドから除外する手順が有効となります。
webapack
コマンドを実行してください。
このように表示されていればOKです!
今度はローカルサーバーを立てながら実際に簡単なTodoアプリを作成していきたいと思います。