首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >与SSR一起反应HMR

与SSR一起反应HMR
EN

Stack Overflow用户
提问于 2019-04-03 16:45:07
回答 4查看 2.7K关注 0票数 6

我正在尝试为React-application设置SSR,当我第一次在development环境中启动服务器时,一切正常(服务器发送浏览器超文本标记语言和CSS),在更改我的应用程序的源代码后,我得到一个错误:

抛出这个错误是因为服务器上的源代码已经过时了,但是客户端有一个新的版本,React会通知我这个问题。我认为这个问题的解决方案是一种叫做HMR (热模块替换)的机制,但是设置这个对我来说很难。

我的服务器Webpack-config如下所示:

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
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);
});

对于热重新加载,我使用webpackDevMiddlewarewebpackHotMiddleware

代码语言:javascript
运行
复制
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));

用于将App呈现为NodeStreamrenderDocumentToStream函数

代码语言:javascript
运行
复制
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');
  });
}

当服务器在stdout中启动时记录了对console.log的第一次调用

即使在更改App.jsx之后,也未记录对console.log的第二次调用

我做错了什么?

EN

回答 4

Stack Overflow用户

发布于 2019-04-08 03:40:21

这似乎解决了我的react-ssr-kit在HMR更新期间客户端和服务器不匹配的问题

代码语言:javascript
运行
复制
 const renderMethod = module.hot ? ReactDOM.render : ReactDOM.hydrate;

我的设置略有不同,但它仍然适用于您的设置:

代码语言:javascript
运行
复制
import React from "react";
import ReactDOM from "react-dom";
import { createBrowserHistory } from "history";
import App from "root";
import routes from "routes";
import configureStore from "store/configureStore";

const history = createBrowserHistory(); // create browserhistory
const initialState = window.__INITIAL_PROPS__; // grabs redux state from server on load
const store = configureStore(history, initialState); // sets up redux store with history and initial state

const renderApp = props => {
  const renderMethod = module.hot ? ReactDOM.render : ReactDOM.hydrate; // if module is hot, use ReactDOM's render, else hydrate

  renderMethod(<App {...props} />, document.getElementById("root"));
};

renderApp({ routes, history, store }); // initial App render (ReactDOM.hydrate)

// enable webpack hot module replacement
if (module.hot) {
  module.hot.accept("./routes", () => {
    try {
      const nextRoutes = require("./routes").default;
      renderApp({ routes: nextRoutes, history, store }); // hot-module updates (ReactDOM.render)
    } catch (err) {
      console.error(`Routes hot reloading error: ${err}`);
    }
  });
}
票数 2
EN

Stack Overflow用户

发布于 2019-04-07 16:59:40

该警告清楚地表明,客户端和服务器端的内容不同。这不是一个错误,而是一个警告,这意味着将会有性能影响,因为React必须在客户端重新渲染,因此使用SSR的整个目的将会失败。请检查并确保客户端也获得与服务器相同的水合。这应该可以解决这个问题。

票数 1
EN

Stack Overflow用户

发布于 2019-04-07 17:06:56

我认为这是不可能解决的,因为服务器端不会使用HMR在更改时刷新。

在使用SSR进行React时,我会亲自设置nodemon来监听SSR输出文件上的文件更改并重新启动应用程序。不幸的是,这没有HMR快,并且您会丢失当前状态,但如果您将使用SSR (或忽略警告),我认为没有其他选择

使用Next.js时也是如此:https://github.com/zeit/next.js/issues/791

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55490802

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档