使用 Sass 反应服务器端渲染
Posted
技术标签:
【中文标题】使用 Sass 反应服务器端渲染【英文标题】:React Server Side Rendering with Sass 【发布时间】:2018-10-02 05:33:54 【问题描述】:正如我已经搜索过以前但找不到任何相关/已解决的问题,所以我问...
当前堆栈:React、express/node、Sass、Webpack、Sass。
在服务器将页面发送到浏览器之前,我有一个特定于页面样式的问题。
样式在浏览器中运行良好,我的意思是当通过浏览器路由器导航页面时,所有样式都可以正常工作。但是,我需要想办法在服务器将页面发送到浏览器之前将自定义 Sass 样式注入页面。
当前行为:我从浏览器访问任何页面,我会以正确的样式为页面提供服务,但是在页面上显示正确的样式有一点延迟。如果以慢动作查看,页面出现时没有样式(因为服务器发送的页面没有样式),然后浏览器以正确的样式接管。
我尝试过 webpack 在单独的文件中生成所有样式,但在服务器将其发送到浏览器之前,我似乎无法将此文件链接到页面。
任何帮助/反馈将不胜感激?
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
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(我省略了其余的配置,因为它不相关)
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 ],
这在我的/build
文件夹中为我提供了一个styles.css
文件。我怎样才能将它链接到我的html。如果我尝试抛出 <link>
标签,浏览器将无法识别该文件。
【问题讨论】:
【参考方案1】:我终于通过创建另一个路由处理程序解决了这个问题。
app.get('/styles.css', (req, res) =>
res.sendFile(__dirname + "/" + "styles.css");
);
我的 webpack 编译了一个 styles.css
文件,该文件被放入 /public
文件夹中。请注意,我将 webpack 中样式文件的路径更改为:../public/styles.css
app.use(express.static('public'));
上述语句 ^^^ 使styles.css
文件可访问,最后通过在服务器对浏览器的响应中提供以下<link>
标记来应用样式。
<link rel="stylesheet" href="../../public/styles.css">
如果其他人有更好的解决方案,我很乐意得到反馈。
【讨论】:
感谢@Ash,这也是我最终解决它的方法。我正在研究使用 github.com/zeit/styled-jsx 的其他解决方案,但您的解决方案要简单得多。 很高兴你能弄明白。还有另一种方法似乎更简单一些。通过 webpack 将你的 css 编译成它自己的文件。并在你的反应根目录中要求该文件index.js
您也可以使用styled components
,这将产生一个内联css,因此用户将保存css文件所需的请求以上是关于使用 Sass 反应服务器端渲染的主要内容,如果未能解决你的问题,请参考以下文章