2017-04-17 74 views
0

我HAVA得到了FOUC問題反應與服務器端渲染。我用的陣營+ ReactRouter +終極版 這裏是主要的技術堆棧我認爲有必要列表:陣營服務器端渲染(CSS模塊)FOUC問題

  • CSS Module處理組件樣式
  • extract-text-webpack-plugin生成單獨的css文件
  • css-modules-require-hook & asset-require-hook在處理資產服務器端

和我的WebPack配置:

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樣式。

我的服務器端處理由快遞:

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功能:

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是程序的開始:

// 各種鉤子 
    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-hookcss-modules-require-hook手柄資產服務器端無法處理。

一切正常,除了... FOUC!我的服務器端通常會生成html,而每次嘗試時都沒有任何css。

這是我的截圖: enter image description here

回答

0

下面是我的webpack.config文件的一個片段。我在我的React Server-side Rendering Example中修復了FOUC問題。我認爲這是使用HtmlWebpackHarddiskPlugin在HtmlWebpackPlugin的alwaysWriteToDisk設置爲true。

new ExtractTextPlugin({ 
    filename: isDevelopment 
     ? 'assets/styles/main.css' 
     : 'assets/styles/[name].[chunkhash].css', 
}), 

new HtmlWebpackPlugin({ 
    template: path.resolve(__dirname, 'src/index.html'), 
    minify: isProduction ? {collapseWhitespace: true, collapseInlineTagWhitespace: true} : false, 
    alwaysWriteToDisk: true, 
}), 
new HtmlWebpackHarddiskPlugin(), 
+0

好的我會試一下,Thks – Betamee