LaravelをReact化+SSRした際のつまった所
個人開発のサイトReact化してみました
前回記事で書いたけど個人で開発のサイトReact化してみました。
誰にも望まれてないけど勝手にリニューアル。
目指せ不労所得。がんばるんだ俺。
寝てるだけでお金入って来ないかなって思ってる自分がいる #ひなまつり #大武政夫 #詩子 https://t.co/gLf4GcyjLT
— wordstacks (@wordstacks_bot) January 28, 2020
SSR(server side rendering)
SEOの事は詳しくは良くわかりませんがが
多分Reactそのままだとよくないかと思われる。ので今回server side renderingしました。
React自体今回始めてじっくりと触った感じなので
わからんけど普通はnext.jsとかでやるのかな?
良くは知りません。
SSRは不要?
最近のクローラーはイケてるので
SSRは不要なのでは?って情報とか見て
じゃいいや。
って思ってたんだけども
元々あんまり無かったアクセスが
結構あからさまにさらに下がった気がするので
致し方なくやる事に。
誰にも望まれてないけど
laravel server side rendering
https://github.com/spatie/laravel-server-side-rendering
多分Lalavelでやるならこれでやると良いらしいという情報みてやってみた。
想定してたよりは簡単にできた。
でも面倒は面倒だけど、
あんま情報少ないと思うので
自分がつまったポイント書いてみます。
node pathの設定
Laladock
nodeのパスを設定しましょうって書いてあるので
普通はwhich nodeで出てきたやつ.envに入れればいいはず、です。
でも自分の場合はローカルでLaladock使ってたからか
nodeがありまへんえ的なエラーがでて結構困った。
結論言うとlaradock_workspaceの方じゃなくて
laradock_php-fpm
のphp-fpmコンテナにnodeインストールしてからの
node pathを指定しないと駄目っぽい。
僕の場合は
laradock/php-fpm/Dockerfile
の適当な所に
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - \
&& apt-get update \
&& apt-get install -y nodejs
追記してから
dockerのphp-fpmリビルドしてーの
docker-compose build --no-cache php-fpm
which node
docker exec -it laradock_php-fpm_1 which node
のパス入れれば無事動きました。
リモートで
最初sshで入ってwhich nodeで出たpathを
特に気にせずそのまま入れてて
僕の場合~/(チルダ)から始まってるパスだったので
laravelからだとnginxのホームディレクトリ指しちゃってるの気づかず少し詰まった。
なのでルートディレクトリから指定した方が確実かと思う。多分。
あとはjsの話
初期表示
htmlかえってくるので
一瞬、生のhtmlがでちゃう。
生ででちゃう。ので
<style>body{display: none;}</style>
と
document.getElementsByTagName("body")[0].style.display = "block";
でひとまず対応した。
ローテクな感じになってしまったけど、これで良いのだろうか?
多分なんかありそうではある。けど、
困ってはないので一旦このまま
server.js
contextとdispatchは
laravel-serverside-renderingのパッケージからの関数なので
特に宣言とかは必要ないらしい。
がなんで使ってしまったのかtypescriptで初めてしまったので
そのままだとエラーがでます。
また面倒な事になってしまったなーと思ってたけど
declareを使えばいいっぽい。
declare var context;
declare var dispatch;
const html = ReactDOMServer.renderToString(
<div id="root">
<Provider store={store}>
<StaticRouter location={context.url} context={context}>
<Container />
</StaticRouter>
</Provider>
</div>
);
こんな感じ。
ガッツリtypescript使って人からしたら当然?なのかな?
アンビエント宣言っていうらしい。
とりあえずは動いたので何でもいい。
ブライアンイーノ宣言。
createMemoryHistory
documentとかwindow使ってちゃ駄目ってのはサーバーサイドレンダリングだと割と有名な話らしい。
まぁnodeなんだからwindowは無いよね。って事かな?
ソレ先に言っといてよー。
とも思ったが仕方ない。誰にも望まれてないので。
話逸れたけど、
createBrowserHistoryでもエラーになっちゃいます。
かわりにcreateMemoryHistory使えばよいっぽい。
import { createBrowserHistory, createMemoryHistory, History } from "history";
const history: History =
typeof document !== "undefined"
? createBrowserHistory()
: createMemoryHistory();
export default history;
こんな感じ。
CSS
あとjQueryおじさんなので
カルーセルっていえばslickです。
react-slick使ってたのだけども、
server側ではcssをimportするとエラーになったので
こんな感じにしました。
if (typeof window !== "undefined") {
require("slick-carousel/slick/slick.css");
}
ちなみにimport()だとなぜかエラー出たのでここだけ
requireで、理由はしらない。動いたからいいや。
import "slick-carousel/slick/slick.css";
//これはerror
if (typeof window !== "undefined") {
import("slick-carousel/slick/slick.css");
}
//これもerror
webpackの設定が悪いのかも、ですが。
おわり
今の所lalavel側からとってきた。
eloquentのデータはserver側にしか反映しておらず
二度手間みたいなリクエストになっちゃってるので
そのうちちゃんとする予定。
忘れないうちに記事にしてみました。
ディスカッション
コメント一覧
まだ、コメントがありません