0
반응 서버 쪽 렌더링에 FOUC 문제가 있습니다. 자산을 처리하기위한 별도의 CSS 파일 React Server Side Rendering (CSS Module) FOUC 문제
css-modules-require-hook
& asset-require-hook
를 생성하기위한 구성 요소 스타일extract-text-webpack-plugin
와
CSS Module
거래 : 나는 + ReactRouter + 돌아 오는 여기 주요 기술 스택 내가 필요한 목록에 생각이다 반작용 사용 서버 측
내 웹팩 설정 :
module.exports = {
entry: [
APP_PATH,
],
output: {
path: BUILD_PATH,
filename: 'client.bundle.js',
publicPath: '/JdBus/',
},
resolve: {
extensions: ['.js', '.jsx'],
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [
'babel-loader',
],
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
modules: true, // 开启CSS Module
localIdentName: '[name]__[local]-[hash:base64:5]',
},
},
{
loader: 'postcss-loader',
options: {
plugins() { // 这里配置postcss的插件
return [autoprefixer];
},
},
},
],
}),
},
{ // 处理图片
test: /\.(png|jpg|gif|webp')$/,
// include:path.resolve(__dirname,'/client/assets'),
use: [{
loader: 'url-loader',
options: {
limit: 10000,
// 这个是输出的图片文件,跟output一致,生成的是bundleImg目录下的图片文件
name: 'bundleImg/[hash:8].[name].[ext]',
},
}],
},
{ // 处理文字
test: /\.(woff|ttf|svg|eot|woff2)$/,
// include:path.resolve(__dirname,'/client/assets'),
use: [{
loader: 'url-loader',
options: {
limit: 10000,
name: 'bundleFonts/[hash:8]-[name].[ext]',
},
}],
},
],
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
WEBPACK: true,
},
}),
new webpack.optimize.UglifyJsPlugin({
compressor: {
warnings: false,
},
}),
new ExtractTextPlugin('bundle.css'),
new webpack.optimize.CommonsChunkPlugin({
name: 'commons',
filename: 'commons.js',
minChunks: 2,
}),
};
ExtractTextPlugin
은 bundle.css에서 모든 CSS 스타일을 생성합니다. 익스프레스 바이
내 서버 사이드 핸들 :
function renderFullPage (html, initiaState, env) {
// 根据生产和开发环境配置不同的页面
if (env === 'development') {
return `
<!DOCTYPE html>
<html lang="en">
<head>
<title>开发测试页面</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-
scale=1.0, user-scalable=no"/>
<style>
body{
margin:0px;
}
</style>
</head>
<body>
<div id="root"></div>
<script>
window.__INITIAL_STATE__ = ${JSON.stringify(initiaState)};
</script>
<script src='/devClient.bundle.js'></script>
</body>
</html>
`;
} else if (env === 'production') {
return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>十二棵橡树</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0,
user-scalable=no"/>
<link rel="stylesheet" type="text/css" href="/JdBus/bundle.css">
<style>
body{
margin:0px;
scroll:no
}
</style>
</head>
<body>
<div id="root">
${html}
</div>
<script>
window.__INITIAL_STATE__ = ${JSON.stringify(initiaState)};
</script>
</body>
</html>
`;
}
}
module.exports = renderFullPage;
내 server.js 어디 프로그램 시작이다 :
match({ routes: AppRoutes, location: `/jdbus${req.url}` }, (err, redirectLocation, renderProps) => {
if (err) {
res.status(500).send(err.message);
} else if (redirectLocation) {
res.redirect(302, redirectLocation.pathname + redirectLocation.search);
} else if (renderProps) {
const store = configureStore({ user: {
name: 'ddd',
avatar: 'ddd',
} });
// console.log(renderProps);
const marked = renderToStaticMarkup(
<Provider store={store}>
<RouterContext {...renderProps} />
</Provider>
);
const initHtml = renderFullPage(marked, store.getState(), process.env.NODE_ENV);
res.status(200).end(initHtml);
} else {
res.status(404).end('404 not');
}
});
renderFullPage()
는 veiw.js에서 HTML을 생성하는 기능입니다 :
// 各种钩子
require('babel-polyfill');
require('css-modules-require-hook')({
extensions: ['.css'],
generateScopedName: '[name]__[local]-[hash:base64:8]',
});
require('asset-require-hook')({
extensions: ['jpg', 'png', 'gif', 'webp'],
limit: 10000,
});
// 处理字体
require('asset-require-hook')({
extensions: ['ttf', 'woff', 'svg', 'eot', 'woff2'],
limit: 10000,
});
const app = require('./app');
app.listen(PORT,() => {
console.log('Node app is running on port:', PORT);
// 注册全局未捕获异常处理器
process.on('uncaughtException', (e) => {
console.error(`Caught exception:, ${e.stack}`);
});
process.on('unhandledRejection', (reason, p) => {
console.error(`Unhandled Rejection at: Promise , ${p}, reason: , ${reason.stack}`);
});
});
asset-require-hook
및 css-modules-require-hook
은 서버 측에서 처리 할 수없는 자산을 처리합니다.
FOUC를 제외한 모든 것이 정상입니다. 내 서버 측은 정상적으로 HTML을 생성하지만, 시도 할 때마다 잠시 CSS를 생성하지 않습니다. 다음 enter image description here
확인해 보겠습니다. Thks – Betamee