首页 文章

Webpack 4和react loadable似乎没有为服务器端渲染创建正确的块

提问于
浏览
13

我正在尝试使用延迟加载导入创建ssr react应用程序 . 一切正常,除了它 does not fetch all the the required chunks

我也想知道这是否与动态组件有关,它基于服务器响应

enter code here

Edit - It actually renders all the required chunks but it wipes out whole thing when client side takes over and render again

因为它重新渲染所有它减慢了很多 .

enter image description here
解析器发生在服务器端,当客户端接管它时,获取更多 server.js

const history = createHistory({
    initialEntries: [urlPath],
  })
  // const history = createHistory()
  const store = configureStore(history, {
    location: {
        ...
    },

  })

  const context = {}
  const htmlRoot = (
    <Provider store={store}>
      <StaticRouter location={urlPath} context={context}>
        <AppRoot />
      </StaticRouter>
    </Provider>
  )

  // pre fetching data from api
  store
    .runSaga(rootSaga)
    .done.then(() => {

        const RTS = renderToString(htmlRoot) + printDrainHydrateMarks()
        const head = Helmet.renderStatic() 
        console.log(printDrainHydrateMarks())

        res.status(code).send(renderDom(RTS, port, host, storeState, head))
      }
    })
    .catch(e => {
      console.log(e.message)
      res.status(500).send(e.message)
    })

  renderToString(htmlRoot)
  console.log(printDrainHydrateMarks())

  store.close()
} else {
  res.status(500).send(_err)
}

Prod Server

Loadable.preloadAll().then(() => {
  app.listen(PROD_PORT, (error) => {

  })
});

Client side

Loadable.preloadReady().then(() => {
    hydrate(
      <Provider store={store}>
        <ConnectedRouter history={history}>
          <AppRoot />
        </ConnectedRouter>
      </Provider>,
      domRoot,
    )
  })

Split Chunks setup

styles: {
      name: 'styles',
      test: /\.css$/,
      chunks: 'all',
      enforce: true
    },

欢迎任何意见或建议

有人建议尝试使用window.onload =()=> {但这种方法似乎也很慢 .

1 回答

  • 0

    您应该使用ReactLoadablePlugin来获取可加载导入的列表:

    new ReactLoadablePlugin({
      filename: './build/react-loadable.json',
    })
    

    使用“反应可加载捕获”,您可以找到渲染时需要哪些动态组件,并且可以将它们的包添加到头文件中:

    const content = ReactDOMServer.renderToString(
      <Loadable.Capture report={moduleName => modules.push(moduleName)}>
        <Provider store={configureStore()}>
          <StaticRouter location={req.url} context={context}>
            <App />
          </StaticRouter>
    
        </Provider>
      </Loadable.Capture>
    );
    
      let bundles = getBundles(stats, modules);
      bundles.map((item) => {
          //add js to header
          })
    

    这可以防止可加载的反应物擦除内容物并重新呈现它 .

    要根据动态加载的组件将Webpack配置为输出正确的块,请执行以下操作:

    optimization: {
        splitChunks: {
          cacheGroups: {
              default: false,
              vendors: false,
          }
      }
    }
    

    这个配置适用于Webpack v4 .

    您可以在此处找到可与React可加载服务器端呈现一起使用的完整文档:

    https://github.com/jamiebuilds/react-loadable

相关问题