eyecatch
Wed, Nov 7, 2018

React + Reduxアプリケーションプロジェクトのテンプレートを作る ― その10: Code Splitting、Flow、Jest、Enzyme

ReactとReduxを学ぶために、開発環境というかプロジェクトテンプレートをスクラッチから作っている。 (最終的な成果はGitHubに置いた。) 前回はReact Routerをセットアップした。 今回は残りの要素をまとめてかたづける。 (2018/11/21更新) (adsbygoogle = window.adsbygoogle || []).push({}); Code Splitting webpackでリソースをバンドルすると、一回の通信でアプリの要素全てをロードできるので効率いいような気がするけど、アプリの規模が大きくなってくるとバンドルサイズが大きくなって、初期ロード時間が長くなり、つまり初期画面の表示に時間がかかるようになってしまう。 そもそも、いつもアプリの全画面をみるとは限らないので、いつもアプリの全要素をロードするのは無駄。 そんな問題に対応する技術がCode Splitting。 バンドルを分割し、(理想的には)必要な時に必要な分だけロードする技術。 Code Splittingのやりかたはいくつかあるが、ダイナミックインポートとReact.lazyとReact Suspenseとwebpackのプリフェッチディレクティブを使ったやつを、フォントモジュールに適用してみる。 src/components/App.jsx: -import React from 'react'; +import React, { Suspense } from 'react'; import { Route, Redirect } from 'react-router-dom'; import Home from './Home'; -import Fonts from '../fonts'; +const Fonts = React.lazy(() => import(/* webpackPrefetch: true */ '../fonts')); const App = () => ( <div> <Route exact path="/" render={() => <Redirect to="/home" />} /> <Route exact path="/home" component={Home} /> - <Fonts /> + <Suspense fallback={<div />}> + <Fonts /> + </Suspense> </div> ); export default App; コード変更はこれだけ。 import()がダイナミックインポートで、ECMAScriptで現在策定中の機能。 これを使えるようにするためには、Babelのプラグインを追加する必要がある。 yarn add -D @babel/plugin-syntax-dynamic-import .babelrc: { "presets": [ [ "@babel/preset-env", { "useBuiltIns": "usage" } ], "@babel/preset-react" ], - "plugins": ["styled-components"] + "plugins": ["styled-components", "@babel/plugin-syntax-dynamic-import"] } ダイナミックインポートの設定も完了。 これでフォントモジュールはメインのバンドルとは別ファイルになり、初期画面の表示時にはロードされず、ブラウザの空き時間に非同期にロードされるようになる。 Flow Reactに限らない話だけど、JavaScriptは動的型付け言語なので、特に規模が大き目なアプリを開発するとなると保守性が悪くなりがちで辛い。 ので、できれば静的型付けでやりたい。 JavaScriptを静的型付けにするには、TypeScriptとFlowという二つの選択肢がある。 今回、FlowがReactと同じくFacebook製なので、Reactと相性がいいかと思ってFlowを選択したけど、人気やエコシステムの充実度から見るとTypeScriptのほうがよかった気がする。 ので、Flowについてはさらっと書く。 Flow導入 Flowは、ソースに型情報を付けて静的型チェック可能にしつつ、実行時には型情報を取り去って普通のJavaScriptとして実行できるようにする仕組み。 型チェックするツールはflow-binパッケージで配布されていて、型情報の除去は@babel/preset-flowを使ってBabelでできる。 yarn add -D flow-bin @babel/preset-flow .babelrc: { "presets": [ [ "@babel/preset-env", { "useBuiltIns": "usage" } ], + "@babel/preset-flow", "@babel/preset-react" ], "plugins": ["styled-components", "@babel/plugin-syntax-dynamic-import"] } これで、yarn flowでFlowを実行できるようになった。 $ yarn flow version yarn run v1.7.0 $ C:\Users\kaitoy\Desktop\bin\pleiades\workspace\react-redux-scaffold\node_modules\.bin\flow version Flow, a static type checker for JavaScript, version 0.77.0 Done in 0.38s.