🙄

PreactへのVike導入手法メモ

2023/11/20に公開

はじめに

Preactの勉強を行っている際にどこまで拡張できるかをみておりSSRもできるようにするプラグインVike
(旧vite-plugin-ssr)を知ったので実験的に導入してみた際につまった部分とその解決方法をメモしておきます。

つまずいた点

既存アプリケーションへの導入

問題点

既存アプリに導入したかったのですが、npm init vike@latestを促されており、新規導入になってしまう?

解決策

特に問題なく下記でいけました!

npm i vike@latest

Preactでの描画ライブラリ

今回Preactではありましたが公式のReact導入手順に沿ってやっていきました。(Preactの方には詳細があまり書いていなかったので...)
その際にサーバー側、クライアント側共有のrenderファイルを作成しました。

問題点

その際にimportするライブラリに差異があったため、少し調査し解決しました。

解決策

下記でいけました!
ただその後の問題で少し修正します。

サーバー側

Vike公式
import ReactDOMServer from "react-dom/server";
import React from "react";
import { escapeInject, dangerouslySkipEscape } from "vike/server";
解決案
import ReactDOMServer from "preact-render-to-string";
import React from "preact/compat";
import { escapeInject, dangerouslySkipEscape } from "vike/server";

クライアント側

Vike公式
import ReactDOM from "react-dom/client";
import React from "react";
解決案
import ReactDOM from "preact/compat";
import React from "preact/compat";

ReactDOMServerでのエラー

問題点

ReactDOMServerを使用した際に下記エラーが発生しました。
おそらくは「ReactDOMServerrenderToStringがないよ」って言われますね。

Following error was thrown by the render() hook defined at /renderer/_default.page.server.tsx
TypeError: __vite_ssr_import_0__.default.renderToString is not a function

解決策

preact-render-to-stringの中身を見てみたところrenderToStringがそのままexportされていました。なので下記修正を行いました。

https
- import ReactDOMServer from "preact-render-to-string";
+ import { renderToString } from "preact-render-to-string";

〜省略〜

- const viewHtml = ReactDOMServer.renderToString(
+ const viewHtml = renderToString(

pageContextをクライアント側で取得できていないエラー

現状で描画自体はできるのですが、コンソールにエラーがでていました。

問題点

以下エラーが出てしました。
おそらくはpageContextがクライアント側で上手く取得できていないとのことでした。

pageContext["pageProps"] isn't available on the client-side because "pageProps" is missing in passToClien

解決策

公式に記載ある以下を使い下記変更で解決しました。
passToClient

_default.page.server.tsx
- export { render };
+ export { render, passToClient };

+ const passToClient = [
+     'pageProps',
+ ]

クライアント側でhydrateRootでのエラー

問題点

以下エラーが出てしました。
ReactDOMを使用した際に下記エラーが発生しました。
先ほどの「ReactDOMServerでのエラー」と同時事象でしょう。

Uncaught (in promise) TypeError: ReactDOM.hydrateRoot is not a function

解決策

これもpreact/compatの中を見てみて以下解決。

_default.page.client.tsx
- import ReactDOM from "preact/compat";
+ import { hydrateRoot }from "preact/compat/client";

〜省略〜

- ReactDOM.hydrateRoot(
+ hydrateRoot(

最後に

やはり新しいものの導入は詰まるところが多いですね...
Viteの可能性がどのくらい広まるかによってVikeの発展可能性に直結すると思うので、頑張って欲しいものです。

Discussion