Javascript 网页包SCSS“;闪烁“;页面加载前

Javascript 网页包SCSS“;闪烁“;页面加载前,javascript,css,express,reactjs,webpack,Javascript,Css,Express,Reactjs,Webpack,我正在开发一个同构的React+Flux+express应用程序,并为我的sass(带有sass加载器)和jsx文件使用网页包加载器。我不知道如何将样式表注入服务器端模板。为此,我查看了Extract Text插件,但我真的希望能够使用热模块替换。 现在,我正在将我的main.scss文件加载到React组件中,如下所示: if (typeof window !== 'undefined') { require("!style!css!sass!../../../styles/main.sc

我正在开发一个同构的React+Flux+express应用程序,并为我的sass(带有sass加载器)和jsx文件使用网页包加载器。我不知道如何将样式表注入服务器端模板。为此,我查看了Extract Text插件,但我真的希望能够使用热模块替换。 现在,我正在将我的
main.scss
文件加载到React组件中,如下所示:

if (typeof window !== 'undefined') {
  require("!style!css!sass!../../../styles/main.scss");
}
这对于在组件中加载单个样式表非常有效,但是在安装React部件之前会出现闪烁。我理解这是因为这是在我的客户端应用程序加载后注入样式表,所以样式表不能立即可用。
这就引出了一个实际的问题:在仍然使用webpack loader的情况下,有没有办法将这个样式表注入到我的服务器端模板中,或者这需要一个单独的gulpfile或express中间件?我以前使用gulpfile来构建我的样式表,但我最终会有很多样式表,不希望它们都被塞进一个文件。

因此,这里的想法是让webpack使用两个单独的配置进行编译,一个用于
web
(浏览器),另一个用于
节点
(服务器端)。在其他node/express代码中可能需要服务器端捆绑包来使用css构建预呈现的HTML

这里有一个完整的示例,我将引导您了解其中的相关部分。

app
中的
prerender.html
是作者正在使用的服务器端模板。请注意以下两行代码:

<link rel="stylesheet" href="STYLE_URL">
<script src="SCRIPT_URL"></script>
在捆绑包旁边创建一个单独的css文件。在第二次编译(用于预渲染)期间,它使用
null loader
加载样式(因为我们已经在css文件中拥有了所需的样式,我们可以直接使用它)

现在,我们将css的路径注入到您的服务器模板中。 请看一个简化的
server.js

假设捆绑包的输出路径与server.js相同(否则,您可以使用
require(../build/stats.json)获取publicPath)。publicPath
并将其添加到上面的
STYLE\u URL
SCRIPT\u URL

然后在
prerender.jsx
中: 抓取服务器端模板
prerender.html
并替换URL:

var html = require("../app/prerender.html");
module.exports = function(scriptUrl, styleUrl, commonsUrl) {
    var application = React.renderComponentToString(<Application />);
    return html.replace("STYLE_URL", styleUrl).replace("SCRIPT_URL", scriptUrl).replace("COMMONS_URL", commonsUrl).replace("CONTENT", application);
};
var html=require(“../app/prerender.html”);
module.exports=函数(scriptUrl、styleUrl、commonURL){
var application=React.renderComponentToString(),我相信那里的一位开发人员可能会给你一个比我更好的解释


希望这有点(?)帮助!

您将需要两个webpack版本:一个用于web,一个用于节点

如果删除样式,则可以在服务器和客户端上加载样式表

  var css = require("!css!sass!../../../styles/main.scss");
由于您不再使用样式加载器,因此需要将生成的css手动注入到视图中

在你看来,你需要包括这一点

<style>{css.toString()}</style>
{css.toString()}

这应该可以在服务器和客户端上使用。当您执行React.renderToString()时,css将按照html中的任何顺序进行解析。如果它位于顶部/在
中,则不会闪烁。

初始闪烁会出现,因为“样式加载程序”尚未下载您的css样式

要解决这个问题,需要同构(通用)呈现(在服务器上生成标记,而不仅仅是在生产模式下—在开发模式下)

您可以通过遵循“react starter”项目路径(在上面的评论中提到)或使用
webpack同构工具来实现同构渲染


感谢您提供了详细而翔实的答案。很抱歉,我花了这么长时间写了一篇评论。我最终选择了node sass中间件,因为它更容易启动和运行。node sass中间件是我能找到的最接近Rails清单文件的东西(帮助一组开发人员从Rails过渡到节点生态系统。我确实完成了这一步,它起到了作用,我很可能会回到这种方法上来,但这不是我现在需要的。再次感谢!太复杂了…但没有更简单的解决方案。另外,请看一个更简单的使用示例…当然不会有任何风格的热重新加载。)用这种方法
  var css = require("!css!sass!../../../styles/main.scss");
<style>{css.toString()}</style>