我正在开发同构的React + Flux + express应用,并为我的sass(使用sass-loader)和jsx文件使用webpack加载器。我不确定如何将样式表注入服务器端模板。我为此目的查看了“提取文本插件”,但我确实希望能够使用热模块替换。现在,我正在main.scss
像这样在React组件中加载文件:
if (typeof window !== 'undefined') {
require("!style!css!sass!../../../styles/main.scss");
}
这对于在组件中加载单个样式表效果很好,但是在安装React部件之前会出现闪烁。我了解这是因为这是在加载客户端应用程序后注入样式表,因此样式表不会立即可用。这就引出了一个实际的问题:是否有办法在仍然使用webpack加载器的情况下将此样式表注入我的服务器端模板,还是这需要单独的gulpfile或表达中间件?我以前使用的是gulpfile来构建样式表,但最终我会拥有很多样式表,并且不希望它们全部卡在一个文件中。
因此,这里的想法是让webpack编译两种不同的配置,一种针对web
(浏览器),另一种针对node
(服务器端)。在其他节点/表达代码中可能需要服务器端捆绑软件,以使用CSS构建预渲染的HTML。
这里有一个完整的示例,我将带您逐步了解它的相关部分。https://github.com/webpack/react-starter
该prerender.html
中app
是笔者使用的是服务器端的模板。请注意以下两行代码:
<link rel="stylesheet" href="STYLE_URL">
<script src="SCRIPT_URL"></script>
请参阅https://github.com/webpack/react-starter/blob/master/make-webpack-config.js上的webpack配置。传递给此处的选项取决于您是在进行生产构建还是开发构建。因为我们要构建客户端捆绑包和预渲染服务器捆绑包,所以让我们看一下https://github.com/webpack/react-starter/blob/master/webpack-production.config.js。它正在创建两个捆绑包,特别是第一个捆绑包,其中的样式表针对浏览器,而第二个配置用于预渲染。
对于第一次编译,它使用以下代码:
plugins.push(new ExtractTextPlugin("[name].css" + (options.longTermCaching ? "?[contenthash]" : "")));
在您的包旁边创建一个单独的css文件。在第二次编译(用于预渲染)期间,它用于null-loader
加载样式(因为我们已经在css文件中有了所需的样式,因此可以使用它)。
现在,在这里我们将css的路径注入到您的服务器模板中。在这里看一个简化的server.js
:https : //github.com/webpack/react-starter/blob/8e6971d8fc9d18eeef7818bd6e9be45f6b8643e6/lib/server.js
var STYLE_URL = "main.css?" + stats.hash;
var SCRIPT_URL = [].concat(stats.assetsByChunkName.main)[0];
app.get("/*", function(req, res) {
res.contentType = "text/html; charset=utf8";
res.end(prerenderApplication(SCRIPT_URL, STYLE_URL, COMMONS_URL));
});
假设您包的输出路径与server.js相同(否则,您可以使用publicPathrequire("../build/stats.json").publicPath
并将其添加到您的STYLE_URL
及SCRIPT_URL
以上版本。
然后在您的prerender.jsx
:https : //github.com/webpack/react-starter/blob/8e6971d8fc9d18eeef7818bd6e9be45f6b8643e6/config/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);
};
我承认这可能很复杂且令人困惑,如果使用单独的gulpfile更容易,那就去做吧。但是一定要玩这个。如果您需要更多说明和帮助,可以发表评论,我会尽快处理,或者您可以在此处使用webpack聊天室(https://gitter.im/webpack/webpack),我是确保那里的一名开发人员可能会给您比我更好的解释。
希望这对您有所帮助!
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句