在我的应用程序的第一次展示中,我的样式组件未应用,仅看到纯HTML标签。
我该如何处理?我想从服务器端渲染中应用基本样式。
我检查了样式化组件的官方文档,但是 ServerStyleSheet 不起作用。
我在这里获取我的应用预览和代码
server.tsx
import express from 'express';
import path from 'path';
import React from 'react';
import { renderToString } from 'react-dom/server';
import { StaticRouter } from 'react-router-dom';
import { Helmet } from 'react-helmet';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import { ChunkExtractor } from '@loadable/server';
import { ServerStyleSheet, StyleSheetManager } from 'styled-components';
const app = express();
if (process.env.NODE_ENV !== 'production') {
const webpack = require('webpack');
const webpackConfig = require('../webpack.client.js').map((config: any) => {
config.output.path = config.output.path.replace('dist/dist/', 'dist/');
return config;
});
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');
const compiler = webpack(webpackConfig);
app.use(
webpackDevMiddleware(compiler, {
logLevel: 'silent',
publicPath: webpackConfig[0].output.publicPath,
writeToDisk: true,
}),
);
app.use(webpackHotMiddleware(compiler));
}
app.use(express.static(path.resolve(__dirname)));
app.get('*', (req, res) => {
const sheet = new ServerStyleSheet();
const styleTags = sheet.getStyleTags();
const nodeStats = path.resolve(__dirname, './node/loadable-stats.json');
const webStats = path.resolve(__dirname, './web/loadable-stats.json');
const nodeExtractor = new ChunkExtractor({ statsFile: nodeStats });
const { default: App } = nodeExtractor.requireEntrypoint();
const webExtractor = new ChunkExtractor({ statsFile: webStats });
const context = {};
try {
const styledHtml = sheet.collectStyles(
<StaticRouter location={req.url} context={context}>
<App />
</StaticRouter>
)
const jsx = webExtractor.collectChunks(styledHtml);
const html = renderToString(jsx);
const helmet = Helmet.renderStatic();
res.set('content-type', 'text/html');
res.send(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, user-scalable=no">
<meta name="google" content="notranslate">
${helmet.title.toString()}
${webExtractor.getLinkTags()}
${webExtractor.getStyleTags()}
</head>
<body>
<div id="root">${html}</div>
${webExtractor.getScriptTags()}
</body>
</html>
`);
} catch(error){
console.log(error);
} finally{
sheet.seal();
}
});
app.listen(5000, () => console.log('Server started http://localhost:5000'));
答案 0 :(得分:1)
我通过使用 ServerStyleSheet
注入适当的样式来解决此问题请参见下面的代码
/// server.tsx using express
import { ServerStyleSheet } from 'styled-components';
import { ChunkExtractor } from '@loadable/server';
...
const sheet = new ServerStyleSheet();
const webStats = path.resolve(__dirname, './loadable-stats.json');
const webExtractor = new ChunkExtractor({statsFile: webStats});
const jsx = webExtractor.collectChunks(<App/>);
const html = renderToString(sheet.collectStyles(jsx));
const styles = sheet.getStyleTags();
res.send(`
...
<head>
${webExtractor.getStyleTags() + styles }
</head>
... `)
我缺少的关键点放在 webExtractor.getStyleTags()之后的样式。
完成这些操作后,我发现一切正常