1

私は同型を書いているが、に基づいてアプリに反応反応します。何らかの理由で私は彼らに仕事をさせるのに本当に苦労しています。私の最初のステップは、サーバとクライアントconfigspostcssを同様に削除)scss固有のローダーに置き換えるの両方からcss WebPACKのローダーを削除することでした:SCSSのコンパイルは、アプリ

loaders: [ 
    'style-loader', 
    'css-loader?modules&localIdentName=[name]_[local]_[hash:base64:3]', 
    'sass-loader?sourceMap', 
    ] 

しかし、スタイル・ローダーとして構築するときに、これはReferenceError: window is not definedをスローします明らかにサーバー側のレンダリングには適していません。だから私の次のアイデアはisomorphic-style-loaderです。

import React, { PropTypes } from 'react'; 
import classNames from 'classnames'; 
import withStyles from 'isomorphic-style-loader/lib/withStyles'; 
import s from '../assets/scss/common/index.scss'; 

const App = (props, context) => (
    <div className={classNames('app')}> 
    <h1 className="home_header">Welcome!</h1> 
    {props.children} 
    </div> 
); 

export default withStyles(s)(App); 

をして、サーバー上のコードのレンダリングページでいくつかの策略を実行します。私の知る限り、それは作業を取得するために理解し、私は彼らの高次成分をwithStylesと私のコンポーネントを装飾する必要があります。しかし、問題は、エクスプローラー(https://libraries.io/npm/isomorphic-style-loader#webpack-configuration)内で発生したフラックスアクションを示すパッケージのドキュメントの例です。私が使用しているボイラープレートは、react-routerを使用しています。だから私はちょうど文脈にinsertCssとこのオブジェクトを注入する必要がありますようにちょっと失われています。私はこの試みた:

import React from 'react'; 
import { renderToString } from 'react-dom/server'; 
import { RouterContext, match, createMemoryHistory } from 'react-router'; 
import axios from 'axios'; 
import { Provider } from 'react-redux'; 
import createRoutes from 'routes.jsx'; 
import configureStore from 'store/configureStore'; 
import headconfig from 'components/Meta'; 
import { fetchComponentDataBeforeRender } from 'api/fetchComponentDataBeforeRender'; 

const clientConfig = { 
    host: process.env.HOSTNAME || 'localhost', 
    port: process.env.PORT || '3001' 
}; 

// configure baseURL for axios requests (for serverside API calls) 
axios.defaults.baseURL = `http://${clientConfig.host}:${clientConfig.port}`; 

function renderFullPage(renderedContent, initialState, head = { 
    title: 'cs3', 
    css: '' 
}) { 
    return ` 
    <!DOCTYPE html> 
    <html lang="en"> 
    <head> 
    ${head.title} 
    ${head.link} 
    <style type="text/css">${head.css.join('')}</style> 
    </head> 
    <body> 
    <div id="app">${renderedContent}</div> 
    <script type="text/javascript">window.__INITIAL_STATE__ = ${JSON.stringify(initialState)};</script> 
    <script type="text/javascript" charset="utf-8" src="/assets/app.js"></script> 
    </body> 
    </html> 
    `; 
} 

export default function render(req, res) { 
    const history = createMemoryHistory(); 
    const store = configureStore({ 
    project: {} 
    }, history); 

    const routes = createRoutes(store); 

    match({ routes, location: req.url }, (error, redirectLocation, renderProps) => { 
    const css = []; 

    if (error) { 
     res.status(500).send(error.message); 
    } else if (redirectLocation) { 
     res.redirect(302, redirectLocation.pathname + redirectLocation.search); 
    } else if (renderProps) { 
     const context = { insertCss: (styles) => css.push(styles._getCss()) }; 

     const InitialView = (
     <Provider context={context} store={store}> 
      <RouterContext {...renderProps} /> 
     </Provider> 
    ); 

     fetchComponentDataBeforeRender(store.dispatch, renderProps.components, renderProps.params) 
     .then(() => { 
     const componentHTML = renderToString(InitialView); 
     const initialState = store.getState(); 
     res.status(200).end(renderFullPage(componentHTML, initialState, { 
      title: 'foo', 
      css 
     })); 
     }) 
     .catch(() => { 
     res.end(renderFullPage('', {})); 
     }); 
    } else { 
     res.status(404).send('Not Found'); 
    } 
    }); 
} 

を私はまだこれに取り組むためにどのようにWarning: Failed context type: Required context 'insertCss' was not specified in 'WithStyles(App)'.任意のアイデアを取得していますか?さらに重要なことは、それをやるための簡単な方法はないのか?これは多くの追加作業のようです。

答えて

1

サーバサイドレンダリングを実行するときにwebpackでscssコンパイルを処理するには、いくつかの部分があります。まず、ノードが.scssファイルをコンポーネントにインポートしようとしないようにします。

plugins: [ 
    new webpack.DefinePlugin({ 
     'process.env': { 
      WEBPACK: JSON.stringify(true), 
     } 
    }) 
], 

そしてコンポーネントはWebPACKのによって処理されている場合、あなたのコンポーネントには、唯一の(のいずれかのビルドまたは開発中).scssファイルをインポートしようとすると::

だから、グローバル変数あなたのWebPACKの設定で WEBPACK: trueを設定

if (process.env.WEBPACK) require('../assets/scss/common/index.scss'); 

コンポーネントごとに1つのSassファイルしかない場合は、これは常に1ライナーです。必要に応じて、追加のSassファイルをindex.scssにインポートすることができます。

は、その後、あなたの設定には、おそらくまだCSSローダーをしたいので、それはあなたのdevのサーバーに対して次のようになります。

{ 
    test: /\.s?css$/, 
    loader: ExtractTextPlugin.extract('style', 'css!sass') 
}, 
+0

クール:あなたが設定を構築するために、このような

{ test: /\.s?css$/, loaders: ['style', 'css', 'sass'] }, 

そして何か、これは動作します。しかし、私はちょうど必要最小限のCSSをロードすることになっていたので、私はこのisomorphicローダーの利点のいくつかを失っているように感じる。私のコンポーネントの中でこのwebpackプラグイン変数を使って作業することも、これまでにない最もクリーンな解決策ではありませんが、今のところ私はそれで生きなければなりません。 – owca

関連する問題