-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dev-ssr #41
dev-ssr #41
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
По логике работы пока особо не могу сказать - не изучал эту тему на достаточном уровне.
То, что смог прокомментировать, прокомментировал.
packages/client/index.html
Outdated
</head> | ||
<script>window.initialState = <!--store-data-->;</script> | ||
<body> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Давай назовем, переменную window.__PRELOADED_STATE__
как в репозитории - примере.
Так понятно, что она приватная, ну и в коде выделяется.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
window.initialState изменил на window.__PRELOADED_STATE__
packages/client/package.json
Outdated
"build:client": "rm -rf dist/client && vite build --outDir dist/client", | ||
"build:server": "rm -rf dist/server && vite build --outDir dist/server --ssr src/entry-server.tsx", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Не во всех системах команда rf
работает. Думаю, стоит заменить ее на rimraf
или del
из одноименных пакетов. Так получится 100% универсальное решение.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rm -rf изменил на rimraf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Нужно в дев зависимости добавить этот пакет
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Установил пакет rimraf.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
нужно в devDependencies
его, он же только для сборки используется.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Переместил в devDependencies.
"dev": "vite", | ||
"build": "tsc && vite build", | ||
"preview": "vite preview", | ||
"dev": "node server", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Есть иллюзия, что запуск сервера в клиентском пакете странно выглядит. У нас же есть папка server
для разработки и запуска сервера.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Думаю лучше отделить frontend от backend, backend должен отвечать только за данные.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ну я тут рассуждаю как. Забываем про js, представим кейс с роботами. Робот шлет get запрос на сервер (в данном случае к express), получает в ответ готовую html страницу. Разве это не данные? Про клиента он знать не знает. Ровно так же работает классический веб без SPA. Шлем запрос, получаем от сервера готовую HTML страницу.
Сейчас мы не можем пользователя получать из-за кук и текстовые данные в страницы захардкожены. Возможно по этой причине не выглядит, как сервер. Но замени текстовые данные на условно данные из БД (которые предварительно получишь в express же), добавь авторизацию пользователя, загрузи его данные и вот уже полностью готовая страница. А на клиенте она просто за счет js на события реагировать начнет.
Я считаю, это сервер. Давай посмотрим, что Олег скажет. Клиент, дак клиент ))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Вы себе очень сильно облегчили работу, сделав SSR в одном "пакете" с клиентом. Одобряю.
Если дальше вы в server будете делать API-сервер, который например будет проксировать в Яндекс или будет раздавать API форума - будет шикарно.
Я за вариант, когда SSR живет вместе в client.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Но тут есть нюанс - вам всегда придется ходить "по сети", даже в свои APIшки.
import express from "express"; | ||
import fs from "node:fs"; | ||
import path from "node:path"; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А почему такие импорты? Не встречал раньше. Можно же просто
import fs from "fs";
import path from "path";
Ну и, как писал выше, думаю это должно в папке server
быть написано и на ts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
С 18 версии node рекомендует писать так "node:..."
https://nodejs.org/docs/latest-v19.x/api/fs.html
const isProd = process.env.NODE_ENV === "production"; | ||
const indexProd = isProd ? fs.readFileSync(path.resolve("dist/client/index.html"), "utf-8") : ""; | ||
const root = process.cwd(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Есть предложение заинлайненные пути вынести в переменные в начало файла. По крайней мере какие-то общие части типа dist/client
, dist/server
, ну и дальше уже их использовать для получения итоговых путей.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Пока оставлю так, при переносе ничего не изменится.
.replace(`<!--emotionCss-->`, emotionCss) | ||
.replace(`<!--store-data-->`, JSON.stringify(initialState).replace(/</g, "\\u003c")); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Как пишет redux, можно и такой способ оставить.
https://redux.js.org/usage/server-rendering#security-considerations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Да, такой replace вполне безопасен
const ThemeProvider: React.FC<React.PropsWithChildren> = ({ children }) => { | ||
const [theme, setTheme] = useState<Theme>(defaultTheme); | ||
const [theme, setTheme] = useState<Theme>(Theme.LIGHT); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А почему дефолтную тему решил сменить на светлую? Мне кажется темная симпатичнее ))
Ну и в любом случае, это изменение не должно наверное в текущем PR быть.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Пришлось так сделать, т.к. в node нет localStorage
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Дак я по поводу рефактора не спорю, вопрос, почему не Theme.DARK
? ))
const [theme, setTheme] = useState<Theme>(Theme.DARK);
Получается, ты не рефактор компонента сделал, а сменил его поведение по умолчанию.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Вернул тему Theme.DARK
Добавление SSR