やり方を聞かれて調べたのでメモ。
react-router-domでルーティングされているページをbuildしてexpressにホストしたい。
Reactでの作業
とりあえず何でもいいのですが、react-router-domで最低限のルーティングを設定します。
簡易仕様
- / → Home.js
- /about → About.js
- それ以外だと、Page not found.を表示。
プロジェクトの作成
とりあえずcreate-react-appでプロジェクトを作成。
npx create-react-app react-test
cd react-test
最低限のルーティングを設定したいのでreact-router-domのインストール。
npm install react-router-dom
Home.jsとAbout.jsを生成。
touch src/Home.s src/About.js
Home.js
Home.jsの実装。Homeと表示し、About.jsへのリンクがあるだけ。
import { Link } from "react-router-dom";
const Home = () => {
return (
<div>
Home<br/>
<Link to="/about">Aboutへ</Link>
</div>
);
}
export default Home;
About.js
Aboutと表示しHome.jsへのリンクがあるだけ。
import { Link } from "react-router-dom";
const About = () => {
return (
<div>
About<br/>
<Link to="/">Homeへ</Link>
</div>
);
}
export default About;
App.js
ルーティングの設定。/でも/aboutでもなければPage not foundを表示。
import { BrowserRouter, Switch, Route } from "react-router-dom";
import Home from "./Home";
import About from "./About";
const App = () => {
return (
<BrowserRouter>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/about" exact component={About} />
<Route render={()=><p>Page not found.</p>}/>
</Switch>
</BrowserRouter>
);
}
export default App;
動作確認
npm startで動作確認。 http://localhost:3000。
npm start
build(本番用ファイル生成)
今回の肝はbuildしたファイルがexpressで動くかなのでbuild。
npm run build
buildファイルが作成され、中にbuild結果が出力される。index.htmlを始めとする各種ファイルが生成される。
Express側での作業
上記で生成されたファイル群をexpressの静的ファイルホスティングで正常に動作させるのがゴール。
expressのインストールと作業場の作成
expressをインストールし、reactのプロジェクトフォルダ中にnodeフォルダを作る(わけてもいい。めんどいのでそうしているだけ)。そして、index.jsを生成。
npm install express
mkdir node
touch node/index.js
cd node
実装
index.jsを実装していく。
const path = require("path");
const express = require("express");
const app = express();
//ミドルウエアでstaticパスを追加(ただ、これだけだと直アクセスや無いpathだと動かない)
app.use(express.static(path.join(__dirname, "..", "build")));
//これを追加(全てをindex.htmlにリダイレクト。いわゆるrewrite設定)
app.use((req, res, next) => {
res.sendFile(path.join(__dirname, "..", "build", "index.html"));
});
app.listen(3001, () => {
console.log("server started on port 3001");
});
ポイント
動作のポイントは2つ。
静的ファイルの場所
まず、静的フォルダを設定する。
これだけで実は http://localhsot:3001にアクセスすると動きます。が、これだけでは不十分。
app.use(express.static(path.join(__dirname, "..", "build")));
/を経由せず、ダイレクトに/aboutや/xxxとかにアクセスするとエラーとなる(表示されない or Not foundとならない)。
全てのリクエストをbuild/index.htmlへ
これらを処理するには全てのリクエストをindex.htmlに処理させる必要がある。
一般的なWebサーバではRewirte処理などを行うがExpressでは以下のようにする。
app.use((req, res, next) => {
res.sendFile(path.join(__dirname, "..", "build", "index.html"));
});
実行
では動作確認してみる。
node index.js
確認