React x TypeScript 学習 (2) - DevServer (webpack-dev-server)
概要
Reac x TypeScriptの1回目では開発環境を作ってみました。
npm start
を実行してTypeScriptファイルをJSへビルド出力しましたが、できるならブラウザで出力結果の画面を見ながらファイル更新を検知してビルドするといった流れにした方が効率的ですよね。
今回は、webpackのオプションでローカルサーバ立ち上げ・ライブリロード(ファイル変更を検知して自動リロードし)をしてくれるDevServer、 webpack-dev-server を導入していきます。
第1回の環境をベースに進めます。
実装
npm
webpack-dev-serverをnpmでインストールします。
npm install --save-dev webpack-dev-server
次に、npm scriptsにwebpack-dev-serverコマンドを追加します。第1回ではnpm start
に対しwebpackコマンドにしていましたが、今回webpack-dev-serverコマンドに対応づけをして、npm run build
を叩いたらwebpackコマンドを実行するようにしました(この辺りの対応づけや命名はプロジェクトに合わせて任意で設定してください)。
{ "name": "project", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "webpack-dev-server", "build": "webpack" }, "author": "", "license": "ISC", "devDependencies": { "@types/react": "^16.8.22", "@types/react-dom": "^16.8.4", "awesome-typescript-loader": "^5.2.1", "react": "^16.8.6", "react-dom": "^16.8.6", "source-map-loader": "^0.2.4", "ts-loader": "^6.0.4", "typescript": "^3.5.2", "webpack": "^4.35.0", "webpack-cli": "^3.3.4", "webpack-dev-server": "^3.7.2" } }
ターミナルでnpm start
を実行すると、以下のようなログが出てくるのでブラウザを立ち上げて http://localhost:8080/
にアクセスすると、index.htmlが表示されるようになります。
「wds」: Project is running at http://localhost:8080/ 「wds」: webpack output is served from /
DevServerオプション
ローカルサーバを立ち上げることはできたものの、npm run build
を実行してdist配下に出力しない限り、「Hello from TypeScript and React!」の文字列が表示されません。つまり、ローカルサーバを立ち上げた状態でビルド結果を読み込むようにしつつ、ファイル変更を監視し更新分を反映する必要があります。それにはDevServerにオプションとして設定を加える必要があります。
設定方法としては2通りあります。
- webpack.config.jsにdevServerオブジェクトを追加しその中にオプションを追加
- npm scriptsで実行する、webpack-dev-serverコマンドの後ろにオプションを追加
先ほどローカルサーバを立ち上げましたが、逐一ブラウザを立ち上げてURLにアクセスする必要がありました。例えば、コマンド実行したら自動的にブラウザを立ち上げるようにする場合、 1.ではwebpack.config.jsのdevServerオブジェクトにopen: true
を追加します。
module.exports = { mode: 'development', entry: './src/index.tsx', output: { filename: 'bundle.js', path: __dirname + '/dist' }, devServer: { open: true }, ... }
2.の場合、package.jsonのnpm start
に対し、webpack-dev-serverコマンドの後ろに--open
を追加します。
{ "name": "project", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "webpack-dev-server --open", "build": "webpack" }, ... }
ビルド結果の読み込み
実はローカルサーバを立ち上げた際、ビルド結果は以下のURLで確認することができます。
http://localhost:8080/bundle.js
実ファイルとして出力されてはいませんが、なぜこのURLになっているかというとデフォルト設定でpublicPathが /
になっているためです。
index.htmlでは ./dist/bundle.js
のファイルを参照するようにしているので、DevServerでもこのパスに合わせる必要が出てきます。
そこで、以下のようにpublicPathキーを追加し/dist/
にしておけば、ローカルサーバ立ち上げ後「Hello from TypeScript and React!」が表示されるようになります。
module.exports = { mode: 'development', entry: './src/index.tsx', output: { filename: 'bundle.js', path: __dirname + '/dist' }, devServer: { open: true, publicPath: '/dist/' }, ... }
Hot Module Replacement
モジュールの更新に合わせてその更新のみ画面に反映させたい場合、webpackのHot Module Replacement(HMR)を使用します。
HMRを使うには、webpack.config.jsのdevServerにhotキーを追加します。
module.exports = { mode: 'development', entry: './src/index.tsx', output: { filename: 'bundle.js', path: __dirname + '/dist' }, devServer: { open: true, publicPath: '/dist/', hot: true }, ... }
似たようなもので変更を受けてリロードを行うliveReloadもありますが、こちらを使う場合HMRはdisableにしておくのが良いそうです。
ファイル変更検知
DevServerで提供されるモジュール以外のhtmlファイル等の変更を検知するには、watchContentBaseキーを追加する必要があります。こちらをtrueにしておくと、変更を受けて画面のリロードを行ってくれます。
module.exports = { mode: 'development', entry: './src/index.tsx', output: { filename: 'bundle.js', path: __dirname + '/dist' }, devServer: { open: true, publicPath: '/dist/', hot: true, watchContentBase: true }, ... }
上述の設定まで行ったら、ビルド結果を読み込みファイル変更を検知して反映までをローカルサーバで行なえるでしょう。
その他オプションの詳細はこちらを参照すると良いと思います。
振り返り
前回に続いて、開発環境よりの話でしたがローカルサーバまで組み込んだので、ReactとTypeScriptについて次回から書いていこうと思います。とはいえ、webpack周りの設定はつまんだ程度のものなので、こちらも知見あれば追加で上げていこうと思います。