From f09965633e5546cfe7be97a8a2f3a7994a9d83f4 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Fri, 27 Dec 2024 09:36:53 +0900 Subject: [PATCH] test: rewrite `playground/ssr-react` without `react-router` (#398) --- playground/ssr-react/package.json | 3 +- playground/ssr-react/public/favicon.ico | Bin 0 -> 4286 bytes playground/ssr-react/src/App.jsx | 59 +++++++++++++++++++--- playground/ssr-react/src/entry-client.jsx | 5 +- playground/ssr-react/src/entry-server.jsx | 5 +- pnpm-lock.yaml | 34 ------------- 6 files changed, 54 insertions(+), 52 deletions(-) create mode 100644 playground/ssr-react/public/favicon.ico diff --git a/playground/ssr-react/package.json b/playground/ssr-react/package.json index 0996e420..793737b4 100644 --- a/playground/ssr-react/package.json +++ b/playground/ssr-react/package.json @@ -13,8 +13,7 @@ }, "dependencies": { "react": "^18.3.1", - "react-dom": "^18.3.1", - "react-router-dom": "^6.28.0" + "react-dom": "^18.3.1" }, "devDependencies": { "@vitejs/plugin-react": "workspace:*", diff --git a/playground/ssr-react/public/favicon.ico b/playground/ssr-react/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..4aff076603f8f01fb3b7d8b5e38df77cc1efdd69 GIT binary patch literal 4286 zcmc(jeOQ&{9mmi9Y5(N4wKaEHmR6cpj%~hXo13+jb7bn2986aeCEr<~nOgZmpr$E` zf`o4brE!#(M1gZu646vl&`1pxMdw?|n=m>c+@F0P;mO>tlyk0ib#r~sdCqh0=e|Gp z@BY2q2Z!Sa`s>)yVZAyw{@CGY>u@-_O1kCfFIo4mH+}bzU$dHTI2`!e8Vx4;1ZKh^ zxKi)yD84^;xC-;kZcMM8u;Hxl=0 zrl(}R$D9P?+i+ezRaK9fv=7rK8`IkjJ!J!H{(<@MS+!R~`O?{>ox=Qa3-rsRXz(63 z2OX9VwCuy2qfp=E%do9`=6nq%BuDe7!jtKI6u6hZ(Up|S59#T~^xp-0ue5F~Z+jVS zZek&3&_;~E69#PN+~91w#MclR`Z@H~e)M!gs0@p&odJ103qFqWoKTLTHzP(@mAxzj(#e6hoycovD(ij}ivB{e#lRuP=cG5k$iaRo)dtx=G zM`-QOi1(><%*tYDlHdB;$}2ES5-{NlF)zQ3nIet}%c&n1$C&sM{8FwGkZ_g`sUGg! z3T>ptZyW}H`KjW=1Y|*Rxo@*u@#a=udF@Tij3~@2VhCG&oq>tVm=kl5JGI?yq#tEV znyQW7d%s`BnUNog;R7)^G4l^7CpCJ{a9%Yn`Yp_y*_byXFtZ{t(-+7Viy(9{&V^aD zbs2uD6#Nr0*t#nRmP8cFH{WZ{6~oeCpO^7?twAxY_*(EPM7@rgXEDr!SrITj3c}}8 zG&hNdv%li*9q=>hZiT(2yL8>xDH{YUC=?&&*$uMcN6JZFoDoXp$8j^YkZG`J2F#yD zT~q{{;?mf*+{vkkRh*ogz;80kX{(g`^V}P1yAv!$FZ=}TTrvCu$T`)zJ@6=Iw#2~7 zDX=^omRbzcx$<@-Pv=~u!|o<}xvTke<^?+EHqb5)?vdJw!(HPN#foO70Yl-k>>`W6NT?SD*WDt)y&<{AiS7Soz8*XK=RiTNo5?#oDKo7j&K*4as9+{Y$WBf^0FF zhPW_7T*Y)e2oGsl4=Su|Js>7q|IHS&LZG8pDR+w@NcCf#pc|Y1m!a|mxHMN<5IFx1 z8~>pkE;}TKz}oRNCQKpRUBH8fptD@dQYW$4vY4(*To35FgLJ?22Ui7UQ&lU1W0kw( zmA{hV*u|UYZ&JK{x(u?0L*`#0{co^Y3@IiNbQp!w zO~^{sk=0O8+H8YsRd7@>zI!0-dJcAo!6iFvdtPxEsQr*FoZ{FpidEZFc~oV-Tk*|$ zOiZ@A>Uvn-1u7yJ!OXeJSCKGPdDF_>p{gGfEe6%GMd?tjc)TqC{6ur_9{_tS27fUO z62lPLLUzcOFS-?jc~K-4?ZfXl{PI|{{KR7G7oUNpZc?8j4+TjnD#%v;R^FZ=O;ZgC zQw<4K9kXibq*$#{4s=ZGD|!+NHE*G=kG!mVVn4kRE-IKSOQ7zG>Zpg*Dnk!_{PpKI z^ege$`kG68tF7N7moCV*M=`td75h4u#3o_hR4h!F4JOMLvlF2rN59`Pl%M4|o^y(g zS}=__`)A81R}DOVN=Mz3(8JOR)qGpx>fXX;*=W+gG@L^E>t@wck4JM=z=<;1T8?r+ z2K1tp)T{Jd($Pnl{u<(`)5^1QqbH<3;_5B+5|_m^P~VlR|NpaD%c*J7PrU}Yugsfq z6=KWbwaXB4Ua4MOgTyu9jE-TFWv}nL35VJirUPP1tyZ~^yM!slY|{1Zn*D!(@9X_P D`VsgZ literal 0 HcmV?d00001 diff --git a/playground/ssr-react/src/App.jsx b/playground/ssr-react/src/App.jsx index 2fc9ece1..b660e5f2 100644 --- a/playground/ssr-react/src/App.jsx +++ b/playground/ssr-react/src/App.jsx @@ -1,4 +1,4 @@ -import { Link, Route, Routes } from 'react-router-dom' +import React from 'react' // Auto generates routes from files under ./pages // https://vitejs.dev/guide/features.html#glob-import @@ -13,7 +13,24 @@ const routes = Object.keys(pages).map((path) => { } }) -export function App() { +function NotFound() { + return

Not found

+} + +/** + * @param {{ url: URL }} props + */ +export function App(props) { + const [url, setUrl] = React.useState(props.url) + + React.useEffect(() => { + return listenNavigation(() => { + setUrl(new URL(window.location.href)) + }) + }, [setUrl]) + + const route = routes.find((route) => route.path === url.pathname) + const Component = route?.component ?? NotFound return ( <> - - {routes.map(({ path, component: RouteComp }) => { - return }> - })} - + ) } + +/** + * @param {() => void} onNavigation + */ +function listenNavigation(onNavigation) { + /** + * @param {MouseEvent} e + */ + function onClick(e) { + let link = e.target.closest('a') + if ( + link && + link instanceof HTMLAnchorElement && + link.href && + (!link.target || link.target === '_self') && + link.origin === location.origin && + !link.hasAttribute('download') && + e.button === 0 && + !(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) + ) { + e.preventDefault() + history.pushState(null, '', link.href) + onNavigation() + } + } + document.addEventListener('click', onClick) + return () => { + document.removeEventListener('click', onClick) + } +} diff --git a/playground/ssr-react/src/entry-client.jsx b/playground/ssr-react/src/entry-client.jsx index 83e04a0e..bb276971 100644 --- a/playground/ssr-react/src/entry-client.jsx +++ b/playground/ssr-react/src/entry-client.jsx @@ -1,11 +1,8 @@ import ReactDOM from 'react-dom/client' -import { BrowserRouter } from 'react-router-dom' import { App } from './App' ReactDOM.hydrateRoot( document.getElementById('app'), - - - , + , ) console.log('hydrated') diff --git a/playground/ssr-react/src/entry-server.jsx b/playground/ssr-react/src/entry-server.jsx index e2d34362..091b32a6 100644 --- a/playground/ssr-react/src/entry-server.jsx +++ b/playground/ssr-react/src/entry-server.jsx @@ -1,11 +1,8 @@ import ReactDOMServer from 'react-dom/server' -import { StaticRouter } from 'react-router-dom/server' import { App } from './App' export function render(url) { return ReactDOMServer.renderToString( - - - , + , ) } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index afd65d36..0e4e2067 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -302,9 +302,6 @@ importers: react-dom: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) - react-router-dom: - specifier: ^6.28.0 - version: 6.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) devDependencies: '@vitejs/plugin-react': specifier: workspace:* @@ -1172,10 +1169,6 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@remix-run/router@1.21.0': - resolution: {integrity: sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==} - engines: {node: '>=14.0.0'} - '@rollup/plugin-alias@5.1.0': resolution: {integrity: sha512-lpA3RZ9PdIG7qqhEfv79tBffNaoDuukFDrmhLqg9ifv99u/ehn+lOg30x2zmhf8AQqQUZaMk/B9fZraQ6/acDQ==} engines: {node: '>=14.0.0'} @@ -3414,19 +3407,6 @@ packages: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} - react-router-dom@6.28.0: - resolution: {integrity: sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg==} - engines: {node: '>=14.0.0'} - peerDependencies: - react: '>=16.8' - react-dom: '>=16.8' - - react-router@6.28.0: - resolution: {integrity: sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg==} - engines: {node: '>=14.0.0'} - peerDependencies: - react: '>=16.8' - react-switch@7.0.0: resolution: {integrity: sha512-KkDeW+cozZXI6knDPyUt3KBN1rmhoVYgAdCJqAh7st7tk8YE6N0iR89zjCWO8T8dUTeJGTR0KU+5CHCRMRffiA==} peerDependencies: @@ -4712,8 +4692,6 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.15.0 - '@remix-run/router@1.21.0': {} - '@rollup/plugin-alias@5.1.0(rollup@3.29.4)': dependencies: slash: 4.0.0 @@ -7369,18 +7347,6 @@ snapshots: react-refresh@0.14.2: {} - react-router-dom@6.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@remix-run/router': 1.21.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-router: 6.28.0(react@18.3.1) - - react-router@6.28.0(react@18.3.1): - dependencies: - '@remix-run/router': 1.21.0 - react: 18.3.1 - react-switch@7.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: prop-types: 15.8.1