React & Webpack
このクイックスタートガイドでは、TypeScriptをReactとWebpackで繋ぐ方法を説明します。 npmで既にNode.jsを使用していることを前提としています。
プロジェクトの構築
新しいディレクトリを作成するところから始めていきましょう。
ここではproj
という名前にしましたが、好きな名前にしていただいて構いません。
mkdir proj
cd proj
始めるにあたり、ここでは次のようなプロジェクトの構成を想定しています。
proj/
├─ dist/
└─ src/
└─ components/
TypeScriptファイルは、TypeScriptコンパイラとwebpackを通してsrc
フォルダから実行され、
最終的にdist
内のbundle.jsファイルになります。
私たちが書くコンポーネントは、全てsrc/components
フォルダに入れます。
足場となるこの構成を作成しましょう。
mkdir src
cd src
mkdir components
cd ..
dist
ディレクトリは、最終的にWebpackが作成してくれます。
プロジェクトの初期化
このフォルダをnpmパッケージ化します。
npm init
一連のプロンプトが表示され、 予め用意されているデフォルト以外の値でも好きなように設定することができます。 また、生成されたpackage.jsonファイルで、いつでも自由に変更したり元に戻すことが可能です。
依存関係のあるライブラリをインストール
まず、Webpackがグローバル上にインストールされている状態にします。
npm install -g webpack
Webpackは、あなたのコードと任意の全ての依存関係のライブラリを、ひとつの.js
ファイルにまとめる事ができるツールです。
ReactとReact-DOMをそれらの宣言ファイルと一緒に、あなたのpackage.json
への依存関係があるものとして追加してみましょう。
npm install --save react react-dom @types/react @types/react-dom
@types/
が接頭辞として付いているものは、ReactとReact-DOMの宣言ファイルも取得することを意味します。
通常、"react"
のようなパスをインポートすると、reactパッケージ自身の内部が検索されますが、
パッケージ内部に宣言ファイルが含まれるとは限らないため、TypeScriptは@types/react
パッケージも同様に検索します。
次に開発時に必要となる依存性のあるツールawesome-typescript-loaderとsource-map-loaderを追加します。
npm install --save-dev typescript awesome-typescript-loader source-map-loader
これらはどちらも、TypeScriptとWebpackをうまく共存させてくれます。
awesome-typescript-loaderはtsconfig.json
という名前のTypeScript標準の設定ファイルを使用して、
WebpackがTypeScriptのコードをコンパイルするのを手助けしてくれます。
source-map-loaderは独自のソースマップを生成する際に、TypeScriptからのソースマップの出力を使用してwebpackに通知します。 これにより、元のTypeScriptソースコードをデバッグしているかのようにして、最終的に出力されるファイルをデバッグできます。
awesome-typescript-loaderだけがTypeScript用のローダーでは無いことに注意してください。 代わりにts-loaderを使用することもできます。 これらの違いについては、こちらを参照にしてください。
開発時に依存があるものとしてTypeScriptをインストールしていることに注意してください。
TypeScriptをnpm link typescript
を使用してグローバルのコピーにリンクすることもできますが、あまり一般的ではありません。
TypeScriptの設定ファイルを追加
あなたが書くTypeScriptのコードと必須となる宣言ファイルの両方を一緒にする必要があります。
これを行うには、コンパイル設定と入力ファイルのリストを含むtsconfig.json
を作成する必要があります。
プロジェクトのルートにtsconfig.json
という名前の新しいファイルを作成し、次の内容を入力してください。
{
"compilerOptions": {
"outDir": "./dist/",
"sourceMap": true,
"noImplicitAny": true,
"module": "commonjs",
"target": "es5",
"jsx": "react"
},
"include": [
"./src/**/*"
]
}
tsconfig.jsonの詳細については、こちらを参照してください。
コードを書く
Reactを使用した初めてのTypeScriptファイルを作成してみましょう。
まず、src/components
内にHello.tsx
という名前のファイルを作り、下記の内容を書いてください。
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>;
この例では、全体的にStateless functionalコンポーネントを使用していることに注意してください。 また、この例をこのまま改良していくことも可能です。
import * as React from "react";
export interface HelloProps { compiler: string; framework: string; }
// 'HelloProps'はpropsの形状(shape)を表すものです。
// Stateがセットされることは無いため、'undefined'型を使用します。
export class Hello extends React.Component<HelloProps, undefined> {
render() {
return <h1>Hello from {this.props.compiler} and {this.props.framework}!</h1>;
}
}
次は下記の内容でsrc
内にindex.tsx
を作成しましょう。
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
コンポーネントをインポートしています。
"react"
や"react-dom"
とは異なり、Hello.tsx
に相対パスを使用していることに注目してください。
これは重要なことです。
こうしなければ、TypeScriptはnode_modules
内を検索してしまいます。
また、Hello
コンポーネントを表示するページも必要です。
proj
のルートに、次の内容で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/dist/react.js"></script>
<script src="./node_modules/react-dom/dist/react-dom.js"></script>
<!-- Main -->
<script src="./dist/bundle.js"></script>
</body>
</html>
ここでnode_modules
からファイルを読み込んでいることに注目してください。
ReactとReact-DOMのnpmパッケージには、Webページに含めることができるスタンドアローンな.jsファイルが含まれていて、
てっとり早く動かすために直接参照しています。
これらのファイルを別のディレクトリにコピーするか、コンテンツ配信ネットワーク(CDN)でホストするようにしてください。 FacebookではReactのバージョンのCDNホストを利用可能にしており、 ここでをその詳細読むことができます。
webpackの設定ファイルを作成
プロジェクトディレクトリのルートにwebpack.config.js
ファイルを作成しましょう。
module.exports = {
entry: "./src/index.tsx",
output: {
filename: "bundle.js",
path: __dirname + "/dist"
},
// webpackの出力をデバッグするためのsourcemapsを有効化
devtool: "source-map",
resolve: {
// 解決可能な拡張子に'.ts'と'.tsx'を追加
extensions: ["", ".webpack.js", ".web.js", ".ts", ".tsx", ".js"]
},
module: {
loaders: [
// '.ts'または'.tsx'の全てのファイルを、'awesome-typescript-loader'で扱う
{ test: /\.tsx?$/, loader: "awesome-typescript-loader" }
],
preLoaders: [
// '.js'の全てのファイルに、'source-map-loader'によて予め処理されたsourcemapsを持たせる
{ test: /\.js$/, loader: "source-map-loader" }
]
},
// インポートしたモジュールのパスが下記のいずれかにマッチする場合、
// それに相当するグローバル変数が存在するものとしてそれを使用します。
// 依存性の全てを扱うことを避けることができるようになり、
// ビルド間でそれらのライブラリがキャッシュ可能になるため重要です。
externals: {
"react": "React",
"react-dom": "ReactDOM"
},
};
このexternals
について疑問に思うかもしれませんが、
Reactの全てが同一ファイルにバンドルされることを避けたいと考えてのことです。
こうすることで、コンパイル時間を減らし、変更が無ければライブラリをキャッシュするブラウザの一般的な機能を利用します。
理想的には、Reactモジュールをブラウザからインポートするだけになることですが、 ほとんどのブラウザが、まだモジュール機能を完全にサポートしていません。
代わりにライブラリは、伝統的に自身をjQuery
や_
のような1つのグローバル変数で扱えるようにしています。
これは"名前空間パターン"と呼ばれ、webpackではこのように書かれたライブラリを引き続き活用することができます。
"react": "React"
のエントリーにより、
webpackはReact
変数から"react"
読み込みをインポートする魔法を働かせます。
webpackの設定についての詳細は、こちらを参照してください。
まとめ
そして、このコマンドを実行します。
webpack
お気に入りのブラウザでindex.html
を開き、ここから全てが始まることを確認してください!
ページ上に、"Hello from TypeScript and React!"と表示されていることが確認できるはずです。
© https://github.com/Microsoft/TypeScript-Handbook
このページは、ページトップのリンク先のTypeScript-Handbook内のページを翻訳した内容を基に構成されています。 下記の項目を確認し、必要に応じて公式のドキュメントをご確認ください。 もし、誤訳などの間違いを見つけましたら、 @tomofまで教えていただければ幸いです。
- ドキュメントの情報が古い可能性があります。
- "訳注:"などの断わりを入れた上で、日本人向けの情報やより分かり易くするための追記を行っている事があります。