简体   繁体   English

使用Sass反应服务器端渲染

[英]React Server Side Rendering with Sass

As i have searched through the previous but could not find any relevant / solved issues on this so I ask... 由于我已经搜索过以前但未找到任何相关/已解决的问题所以我问...

Current stack: React, express/node, Sass, Webpack, Sass. 当前堆栈:React,express / node,Sass,Webpack,Sass。

I have a question specific to the Styling of pages before server sends them to the browser. 在服务器将页面发送到浏览器之前,我有一个特定于页面样式的问题。

Styling is working perfectly in the browser and by I mean when the pages are being navigated via browser router, all the styling works. 样式在浏览器中完美运行,我的意思是当页面通过浏览器路由器导航时,所有样式都有效。 However, I need to figure out a way to inject custom Sass styles to the page before the Server sends the page to the browser. 但是,我需要找到一种方法,在服务器将页面发送到浏览器之前将自定义Sass样式注入页面。

Current behavior: I access any page from the browser, I get serve the page with correct styling BUT there is a minor delay to get the correct styling in place to appear on the page. 当前行为:我从浏览器访问任何页面,我得到正确样式的页面服务但是有一个小的延迟,以便在页面上显示正确的样式。 If view in slow motion, page appears without styling (because the server sent the page with no styling) and then browser takes over with correct styling. 如果以慢动作查看,页面将显示没有样式(因为服务器发送的页面没有样式),然后浏览器接管正确的样式。

I have tried webpack to generate all styles in a separate file but I can't seem to link this file to page before server sends it to the browser. 我已尝试使用webpack在单独的文件中生成所有样式,但在服务器将其发送到浏览器之前,我似乎无法将此文件链接到页面。

Any help / feedback will be appreciated? 任何帮助/反馈将不胜感激?

server.js(route handler) server.js(路由处理程序)

app.get('*', (req, res) => {
  const store = createStore();

  const promises = matchRoutes(Routes, req.path).map(({ route }) => {
    return route.loadData ? route.loadData(store) : null;
});

Promise.all(promises)
.then(() => {
  const context = {};
  const content = renderer(req, store, context);

  if (context.notFound) res.status(404);

  res.send(content);
 });
});

const PORT = process.env.PORT || 3000;

renderer.js renderer.js

import React from 'react';
import { renderToString } from 'react-dom/server';
import { StaticRouter, matchPath } from 'react-router-dom';
import { Provider } from 'react-redux';
import { renderRoutes } from 'react-router-config';
import serialize from 'serialize-javascript';
import Routes from '../client/Routes';

export default (req, store, context) => {

  // req.path is the url that the user is trying to access
  const content = renderToString(
  <Provider store={store}>
   <StaticRouter location={req.path} context={context}>
    <div>
      { renderRoutes(Routes) }
    </div>
   </StaticRouter>
 </Provider>
);

return `
  <html>
    <head>
      <link rel="stylesheet" href="../../public/styles.css">
    </head>
    <body>
      <div id='app'>${content}</div>
      <script>
        window.INITIAL_STATE = ${serialize(store.getState())}
      </script>
      <script src="bundle.js"></script>
    </body>
  </html>
`;
};

webpack.config.js (I omitted the rest of config since its not relevant) webpack.config.js (我省略了配置的其余部分,因为它不相关)

const extractSass = new ExtractTextPlugin({
  filename: "styles.css",
  disable: process.env.NODE_ENV === "development"
});

module: {
rules: [{
    test: /\.scss$/,
    use: extractSass.extract({
        use: [{
            loader: "css-loader"
        }, {
            loader: "sass-loader"
        }],
        // use style-loader in development
        fallback: "style-loader"
    })
  }]
},
plugins: [ extractSass ],

This gives me a styles.css file in my /build folder. 这给了我/build文件夹中的styles.css文件。 How can i link this to my html. 我怎么能把它链接到我的HTML。 If i try to throw a <link> tag the browser does not recognize the file. 如果我尝试抛出<link>标记,则浏览器无法识别该文件。

I finally solved this issue by creating another route handler. 我终于通过创建另一个路由处理程序解决了这个问

app.get('/styles.css', (req, res) => {
  res.sendFile(__dirname + "/" + "styles.css");
});

My webpack compiles a styles.css file which gets put in the /public folder. 我的webpack编译一个styles.css文件,该文件放在/public文件夹中。 Please note i changed the path of my styles file in webpack to this: ../public/styles.css 请注意,我改变我的风格路径的WebPack文件到这一点: ../public/styles.css

app.use(express.static('public'));

Above statement ^^^ makes the styles.css file accessible and finally styles are applied by supplying the below <link> tag in the response of server to the browser. 上面的语句^^^使styles.css文件可访问,最后通过在服务器响应中向浏览器提供以下<link>标记来应用样式。

<link rel="stylesheet" href="../../public/styles.css">

If anyone else have a better solution, I would love to get feedback. 如果其他人有更好的解决方案,我很乐意得到反馈。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM