こんにちは、としあきです。
2021年6月時点の私調べです。
React17でIE11に対応させようとして詰まってしまいました。
要件としてはaxiosを使って非同期読み込みを行うアプリケーションです。
Webpackの設定をいじって試していましたが、まるで動かない。
インターネットの情報を漁っても、古い情報と新しい情報が入り混じって何が正しいのかさっぱりわかりませんでした。
Webpack以外の方法でできないかを調べました。
- React-Create-Appのreact-scriptsを使用する
- Parcelを使用する
結論
Parcelが使いやすいです!
目次
react-scriptsを使用する
「React-Create-Appのreact-scriptsを使用する」はうまく動きます。ただ設定を変更することができず、いくつか生成したJavascriptが別れる状態を変更したかったのですが、変えられませんでした。
またHTML内にJSコードを直書きしてしまうのもいただけないです。
これで作成する場合、使用しているライブラリが固定されます。
webpackも内部で使用していますが、ver4と古いものを使用していました。
React-Create-Appで新規作成する
最初からReact-Create-Appで作成した場合は初期からreact-scriptsで実行できます。
後からreact-scriptsを追加する
後から追加する場合は以下でできます。
yarn add react-scripts
実行は以下のようにします。
react-scripts start
react-scripts build
Parcelを使用する
Parcelのインストール
yarnを実行できるものとします。
yarn global add parcel-bundler
これで完了。
Parcel上でReactを実行するためのインストール
yarn add react react-dom
yarn add --dev babel-preset-react-app
プロジェクト直下にbabel.config.jsを作成します。
module.exports = {
presets: [
"react-app",
],
}
これだけで実行できます。
Parcelの実行
実行コマンドは以下になります。
parcel src/index.html(エントリーポイント)
src/index.htmlは以下のように記述します。
<!DOCTYPE html>
<html xml:lang="ja" lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>テスト</title>
</head>
<body>
<div id="root"></div>
<script src="./index.js"></script>
</body>
</html>
デフォルトだとhttp://localhost:1234で実行できます。
ポートを変更したい場合-pオプションで指定します。
parcel src/index.html -p 8080
開発時ホットリロードの対応
hot module replacementに対応させます。これで簡易サーバーでの実行時、コード変更が即時反映されてテスト確認しやすくなります。
yarn add react-hot-loader
babel.config.jsにプラグインを追加します。
module.exports = {
presets: [
"react-app",
],
plugins: [
"react-hot-loader/babel"
]
}
index.jsで以下のように記述します。
import 'react-hot-loader/patch';
import React from 'react';
import ReactDOM from 'react-dom';
import { AppContainer } from 'react-hot-loader'
import App from './App';
ReactDOM.render(<AppContainer><App/></AppContainer>, document.getElementById("root"));
React17対応のpatchがないため、ChromeのDevToolsで警告が出ます。
開発環境で警告は出ますが、とりあえず動いているようです。
react-dom.development.js:26262 React-Hot-Loader: react-🔥-dom patch is not detected. React 16.6+ features may not work.
React17では以下のインポート文は不要なのですが、ないとエラーになります。
現在のParcelでのビルドに必要なようです。
import React from 'react';
Axiosを使用する
Axiosをインストールします。
yarn add axios
polyfillを入れてPromiseをes5環境でも動作するようにします。
core-jsを使用します。
yarn add --dev core-js
index.jsに下記を追加します。
import 'core-js/stable/promise';

ビルド
parcel build src/index.html
デフォルトではdistディレクトリ以下に作成されます。
sourcemap付きランダムなハッシュ名のjsファイルが作成されます。
$ tree dist
dist
├── index.html
├── src.a85de121.js
└── src.a85de121.js.map
jsファイル名をランダムではなく、固定にしたい場合は以下のコマンドでできます。
エントリーにjsファイルを指定すると、デフォルトでエントリー名のjsファイルを作成できます。
—out-fileオプションでファイル名を変更できます。
parcel build src/index.js [--out-file main.js]
$ tree dist
dist
├── index.html
├── index.js
└── index.js.map
build結果がシンプルでいいです。
運用するならhtmlを出力後、名称固定のjsを呼び出すように書き換えるのが良いかと思います。
後でhtml内から呼び出すjs名を変更すればOK。