TypeScriptを書いたこともないのにReactのプロジェクトに導入しようとした話です。
PropTypesはレガシー?TypeScriptへ置き換える?
発端は、「第65回 HTML5とか勉強会 ー React最新情報」レポの中で出てきたPropTypesの件。
2016年5月19日のreactjs/core-notes(GitHub)の中で、これまでPropsTypesを使ってきたけど、今後は型付けとかしたかったらFlowかTypeScriptを使う方針でいこう、ってな話になっています。
React本家がそういう方針になっている、しかも今後業務などでReactを使うとしたら、それも大規模開発なら、きっとTypeScriptは避けて通れないだろう…ということで、先日React使ってSPAを作るよ(22)番外編でせっかくReactのバージョンもv15.0.0にあげたことですし(現在は15.2.1。さらに更新していくかも)、ブランチきってTypeScriptを導入してみることにしました。
React+TypeScript環境の構築
そもそもTypeScript自体使ったことがないのに、何をどうしたらいいかわかりません。
とにかくいろいろ記事を漁りました。
- TypeScriptを使ってreactのチュートリアルを進めると捗るかなと思った。
- TypeScriptでReactを書く(1):JSX
- TypeScript 1.6.0-beta 変更点
- TypeScript 1.8.0-beta 変更点
- TypeScript1.6 + React 書いてみてハマったポイントとか
- TypeScript + React JSX + CSS Modules で実現するタイプセーフなWeb開発
- TypeScriptの型定義管理ツールTypingsについて
- TypeScript で React
- Typescript + React + gulp環境構築してみた
- JSX と TypeScript の混合 Flux または悪魔合体
- Visual Studio上のTypeScript JSXを使ってReact.js「ReactのチュートリアルをTypeScriptでリライト」
- 全然よくわからないけどReact + TypeScript + webpackをとりあえずつかってみた
- DefinitelyTyped/DefinitelyTyped(GitHub)
- kimamula/ts-react(GitHub)
見た。もうこれでもかというほどの記事を見た。
最終的にどれのどこを見て解決したのか思い出せません。
もともとのプロジェクトではgulpを使ってbundle.jsを作ったり、編集をwatchして自動コンパイルとかやっていたのですが、そこにさらにTypeScriptのタスクを増やしていくのはもう無理でした。
途中までがんばったんですができず…
いったん、まっさらなところにReact + TypeScript + Webpackの最小構成を参考に環境を作ってみました。
ちょっとつまずきながらでしたが、これは記事のとおりにできました!
TypeScriptと型定義ファイルをインストール
記事中のpackage.jsonをまるごと拝借。
プロジェクトのディレクトリで、
npm i
はい簡単!
型定義ファイルのインストールですが、私は試行錯誤する段階でTypeScriptをグローバルにインストールしていたので、難しいこと考えず
tsd install react
みたいな感じでやりました。
あと、react-domとjqueryもインストール。
そうすると/typingsディレクトリに型定義ファイルが落っこちてきます。
–saveをつけて叩いたらtsd.jsonに書かれるって感じですかね?
そんなことすらいまだによくわかっていません黒い画面こわいヒィー(((゚Д゚)))ガタガタ
tsxファイルのコンパイル設定
もともと/viewディレクトリにjsxファイルを入れていたのですが、Laravelのblade.php群が入っている/resources/viewsディレクトリもあって紛らわしいので、これを機に/srcディレクトリに変えちゃうことにしました。
それから、エントリーポイントがapp.jsxだったのも、最初にほかのサイトを参考に構築したときの名残だったので、個人的にもわかりやすいと思うIndex.tsxにしちゃいます。
//webpack.config.js module.exports = { entry: "./src/Index.tsx", output: { filename: "./public/js/bundle.js" }, devtool: "source-map", resolve: { extensions: ["", ".ts", ".tsx", ".js"] }, module: { loaders: [ { test: /\.tsx?$/, loader: "ts-loader" } ], preLoaders: [ { test: /\.js$/, loader: "source-map-loader" } ] } };
それと、私の環境ではドキュメントルートが/public配下にあり、index.htmlで呼び出すjsファイルは/public/jsディレクトリなので、bundle.jsを吐き出す先のパスを変えてあります。
あとtsconfig.jsonのそれらしい箇所も直さないといけませんね。
いろんな記事見ていると、だいたい/tmpとか/distとかのディレクトリにコンパイルしたjsを置いているようなのですが、どこになにがあるのかわかんなくなっちゃうので/public/jsにしておきました。
//tsconfig.json { "compilerOptions": { "outDir": "./public/js", "sourceMap": true, "noImplicitAny": true, "module": "commonjs", "target": "es5", "jsx": "react" }, "files": [ "./typings/tsd.d.ts", "./src/common.ts", "./src/Index.tsx", "./src/Account.tsx", "./src/ArticleArea.tsx", "./src/Comment.tsx", "./src/Login.tsx", "./src/Signup.tsx", "./src/SiteFooter.tsx", "./src/SiteHeader.tsx", "./src/Tag.tsx", "./src/URLForm.tsx" ] }
ここにcommon.tsというファイルが書いてあります。
Reactとは別にindex.htmlで読み込んでいたcommon.jsもTypeScriptに変えて入れておかないと、先頭に書いてあった変数定義がtsx側で認識できなくてコンパイルできないんです…
ガ━━(;゚Д゚)━━ン!!
common.tsをどうやってimportするのかわからず、これだけバンドルされないので、/public/jsの中にファイルをコピーする必要があって、開発中いちいちやるのがめんどくさいんです。
たぶん設定を書き換えればcommon.jsだけ分けて置けると思うのですがそこまで調べる元気がなかったのでひとまずこれでいっちゃいます!
実際にリリースするときは必要ないファイルが溜まってしまうので、あとで変えないと。
とにかくまずは動かすことを優先( ´Д`)=3
ここまでできたら自分のプロジェクトのHTMLを持ってきて、最終的にrender()する対象のdivのidを変えたり、コンポーネントclassの名前を変えたりして、小さいコンポーネントで試して、別ファイルにもういっこ小さいコンポーネント作って、それをexportとimportして…みたいな感じで、ちょこっとずつ書き換えていきました。
中身のソースはまた次回以降!