Пытаюсь настроить SSR для React приложения, в процессе возникла проблема. Когда я в первый раз запускаю сервер (в development
среде), все работает так как и должно (сервер отсылает отрендереный HTML и СSS), после того как я меняю код своего приложения возникает ошибка:
Она возникает потому что код на сервере остался прежний, а на клиенте уже обновился, и react сообщает мне об этой проблеме. Я думаю, что в решении этой проблемы мне поможет технология горячей замены модулей (hot module replacement), но мне не удается ее настроить.
Мой серверный webpack-конфиг выглядит примерно так:
const serverConfig = merge(commonConfig, {
name: 'server',
target: 'node',
externals: [
nodeExternals({
whitelist: ['webpack/hot/poll?1000'],
}),
],
entry: ['webpack/hot/poll?1000', appServerEntry],
output: {
path: path.resolve(appDist, 'server'),
filename: 'index.js',
},
plugins: [new webpack.HotModuleReplacementPlugin()],
resolve: {
extensions: ['.js', '.jsx', '.json'],
},
});
На сервере на каждый запрос рендерится ui
app.get('*', (request, response) => {
const staticAssets = getStaticAssets();
const routerContext = {};
const renderStream = renderDocumentToStream({
staticAssets,
request,
routerContext,
});
const cacheStream = createCacheStream(request.path);
response.writeHead(200, { 'Content-Type': 'text/html' });
response.write('<!DOCTYPE html>');
cacheStream.pipe(response);
renderStream.pipe(cacheStream);
});
Для hot-релоада на сервере использую webpackDevMiddleware
и webpackHotMiddleware
const webpackInstance = webpack(webpackConfig);
const clientCompiler = webpackInstance.compilers.find(cmpl => cmpl.name === 'client');
app.use(
webpackDevMiddleware(clientCompiler, {
hot: true,
stats: 'errors-only',
}),
);
app.use(webpackHotMiddleware(clientCompiler));
Функция renderDocumentToStream
занимается тем что преобразует react-компоненты в NodeStram
и выглядит примерно так:
import App from './App';
renderDocumentToStream: ({ request, staticAssets, routerContext }) => {
const rootMarkup = renderToString(
<StaticRouter location={request.url} context={routerContext}>
<App />
</StaticRouter>
);
return renderToNodeStream(
<Document
rootMarkup={rootMarkup}
staticAssets={staticAssets}
/>,
);
},
if (module.hot) {
console.log('HERE-0');
module.hot.accept('./App', () => {
console.log('HERE-1');
});
}
Когда запускается сервер в консоле можно увидеть что первый console.log
выполнился:
а второй нет, даже после того как я изменил App.jsx
Что я делают не так?
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Имеется код для отправки файла на сервер
Требуется найти готовый сервисРеализация может быть как для Angular (TypeScript), так и обычный JS модуль
В настоящее время, куда не глянь, любая полезная библиотека подключается к проекту npm install