具有样式组件的SSR-当app.js加载网站时缺少几种样式

时间:2018-09-30 18:00:48

标签: reactjs serverside-rendering styled-components isomorphic-javascript

我已使用styled-components实现了SSR。

使用SSR加载页面时,一切看起来都很好。但是,将app.js与SSR版本一起加载和合并后,页面缺少某些样式,并且元素中断很少。

更多-当我在本地使用npm start打开应用程序或基本上只是删除我的SSR时,一切正常,并且样式正确使用。

重要:当我进入页面并且app.js的负载和样式被破坏时,如果我更改路线-新路线会正确显示应用的样式,问题就消失了... 。

  • SSR加载-样式很好
  • 然后几秒钟加载app.js(水化过程)-样式被破坏

在本地运行应用-样式没有问题

运行没有SSR的应用-样式没有问题


因此,简要介绍一下-如果我使用SSR时缺少某些样式,则SSR本身会返回正确的样式,但是在与app.js混合后,很少有组件损坏。

我敢打赌,styled-components可能是一个问题。 SSR可以正常工作,并且其他所有功能都可以正常工作,只是缺少一种样式的组件。


我知道这是关于我的案情的相当不完整的信息,但是要显示可能导致此错误的每个部分,我应该发布整个项目,但是也许您遇到过类似的案情,并且可以以某种方式帮助我。谢谢。

编辑:我的babel-styled-component-plugin配置:

['babel-plugin-styled-components', {
    ssr: true,
    displayName: false,
    fileName: false,
    transpileTemplateLiterals: false,
    minify: false,
}],

2 个答案:

答案 0 :(得分:1)

两件事...

1)确保您使用的是babel plugin;没有它,就不能保证服务器和客户端之间生成的类名是相同的。

2)在捆绑设置中,确保客户端和服务器都使用相同的babel配置。如果存在重大差异,并且文件转换的方式非常不同,则可能会影响生成的类名输出。

答案 1 :(得分:0)

我分四步解决

Server.js

app.get('*', handleRender);


function handleRender (req, res) {
  const activeRoute = routes.find((route) => matchPath(req.url, route)) || {};

  const promise = activeRoute.fetchInitialData ?
    activeRoute.fetchInitialData(req.path) :

    Promise.resolve();

promise.then((data) => {
    const context = { data };
    
    const store = configureStore({});
    const sheet = new ServerStyleSheet(); // ==== STEP -1
    


    const preloadedState = store.getState();

    const html = renderToString(
        sheet.collectStyles(    // === STEP --2
            <Provider store={store}>
                <StaticRouter location={req.url} context={context}>
                    <App/>
                </StaticRouter>
            </Provider>

        )
    );
    const styles = sheet.getStyleTags(); /// === STEP 3
   
    res.send(renderFullPage(html, styles, preloadedState));
});



function renderFullPage (html, styles, preloadedState) {
return `
<!DOCTYPE html>
<html>
  <head>
  <link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600&display=swap" rel="stylesheet">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>body,html,div,ul,p{margin:0;padding:0;}</style>
    <title>Characters of Rick And Morty Show</title>
    <style>
      ${globalStyles}
    </style>
    ${styles} // === STEP 4
  </head>
  <body>
    <div id="root">${html}</div>
    <script>
      // WARNING: See the following for security issues around embedding JSON in HTML:
      // https://redux.js.org/recipes/server-rendering/#security-considerations
      window.__PRELOADED_STATE__ = ${JSON.stringify(preloadedState).replace(
    /</g,
    '\\u003c'
)}
    </script>
    <script src="client_bundle.js"></script>
  </body>
</html>
`;

}

客户

hydrate(<BrowserRouter>
     <Provider store={store}>
       <App/>
    </Provider>
  </BrowserRouter>, document.getElementById('root'));