2017-12-01 4 views
0

NodeJSの上に同形のreact-reduxアプリケーションを構築しています。ホームページをサーバーからレンダリングしています。しかし、私のスタイルはレンダリングされたビューに反映されません。私はクライアント側でスタイルシートをインポートするだけです。私はthis articlethisも試しましたが、どちらも実際に私が達成したいと思っていません。サーバでスタイルシートをインポートすると反応ビューが表示される - TypeError:style._getCssは関数ではありません

ここにプロジェクトの詳細があります。

.babelrc

{ 
"presets": [ "es2015", "react", "stage-0"], 
"plugins": ["transform-decorators-legacy", ["transform-assets", { 
      "extensions": ["scss"], 
      "name": "[name].[ext]?[sha512:hash:base64:7]", 
      }]] 
} 

webpack.config.js

const path = require('path'); 
module.exports = [ 
    { 
     name: 'client', 
     target: 'web', 
     entry: './routes/client.jsx', 
     output: { 
     path: path.join(__dirname, 'assets'), 
     filename: 'client.js', 
     publicPath: '/assets/', 
     }, 
     resolve: { 
     extensions: ['.js', '.jsx'] 
     }, 
     devtool: 'source-map', 
     module: { 
     rules: [ 
      { 
       test: /\.(js|jsx)$/, 
       exclude: /(node_modules\/)/, 
       use: [{ loader: 'babel-loader'}] 
      }, 
      { 
       test: /\.scss$/, 
       use: [ 
        { loader: 'isomorphic-style-loader' }, 
        { 
         loader: 'css-loader', 
         options: { 
          modules: true, 
          importLoaders: 1, 
          localIdentName: '[name]__[local]___[hash:base64:5]', 
          sourceMap: true 
         } 
        }, 
        { loader: 'sass-loader'} 
       ] 
      } 
     ], 
    }, 
}]; 

server.js

import express from 'express' 
import React from 'react' 
import { createStore } from 'redux' 
import { Provider } from 'react-redux' 
import MainStore from './views/store/MainStore' 
import { StaticRouter } from 'react-router-dom'; 
import Routes from './routes/routes'; 
import Template from './views/templates/template'; 
import { Helmet } from 'react-helmet'; 
import { renderToString } from 'react-dom/server' 
import ReactDOMServer from 'react-dom/server'; 
import ContextProvider from './routes/contextProvider' 

const webpackDevMiddleware = require('webpack-dev-middleware') 
const config = require('./webpack/webpack.development.config.js') 
const webpack = require('webpack') 
const app = express() 
const port = 3000 
const compiler = webpack(config); 

let preloadedState = { shipper: {view: "from_server"} } 

app.use('/assets', express.static('./assets')) 
app.use(webpackDevMiddleware(compiler, { 
    publicPath: "/assets/", 
})); 

app.use(handleRender); 

function handleRender(req, res) { 
    // Create a new Redux store instance 
    const store = createStore(MainStore, preloadedState) 
    const css = new Set(); // CSS for all rendered React components 
    const context = { insertCss: (...styles) => styles.forEach(style => 
    css.add(style._getCss())) } 

    const html = renderToString(
    <Provider store={store}> 
     <StaticRouter context={context}> 
      <ContextProvider context={context}> 
      <Routes /> 
     </ContextProvider> 
     </StaticRouter> 
    </Provider> 
) 
    const finalState = store.getState() 
    const helmet = Helmet.renderStatic(); 
    const preloadedState = store.getState() 
    res.send(renderFullPage(html, preloadedState)); 
} 

function renderFullPage(html, finalState) { 
    return ` 
     <!doctype html> 
     <html> 
     <head> 
      <title>Redux Universal Example</title> 
      <style type="text/css">${[...css].join('')}</style> 
     </head> 
     <body> 
      <div id="root">${html}</div> 
      <script> 
       window.__PRELOADED_STATE__ = ${JSON.stringify(preloadedState).replace(/</g, '\\u003c')} 
      </script> 
      <script src="./assets/client.js"></script> 
     </body> 
    </html> 
    ` 
    } 

app.listen(port) 

contextProvider.js

import React, { Component } from 'react'; 
import PropTypes from 'prop-types'; 
import Routes from './routes.jsx'; 

export default class ContextProvider extends Component { 
    static childContextTypes = { 
    insertCss: PropTypes.func, 
} 

getChildContext() { 
    return { ...this.props.context } 
    } 

render() { 
    const { children, ...props } = this.props 
    return React.cloneElement(children, props) 
    } 
} 
私は

<div className={homePageStyle.component}> 

にこれを変更する場合は210

私は

import homePageStyle from './home.scss'; 

として私homePresenterでそれをインポートし、

<div className="component"> 

と同じ構成要素には、私のdivの中でそれを使用しています私が取得しますブラウザのエラー

TypeError: style._getCss is not a function at server.js:52:84 

ブラウザでは、divにクラス名が「コンポーネント」であることがわかりました。それはちょうどスタイルを継承していません。

私がここで紛失していることに関する提案はありますか?

+1

反応コンポーネントのisomorphic-style-loader/lib/withStyles '; 'から' import withStyles'を使用しましたか? – Umesh

+0

@Umeshリードしていただきありがとうございます。私は挿入しましたが、今は別の問題に遭遇しています。私はここのプロセスを、https://github.com/kriasoft/isomorphic-style-loader/issues/110とhttps://github.com/kriasoft/react-starter-kit/issues/378に従って、 isomorphic-style-loader、isomorphic-style-loaderはスタイルオブジェクトに2つのヘルパーメソッドを提供します。 - .insinsCss()(CSSをDOMに挿入)と._getCss()(CSS文字列を返します)。私はしかし、エラーを取得しています "TypeError:style._getCssはserver.jsの関数ではありません:52:84" – Mona

答えて

0

TypeError: style._getCss is not a function at server.js:52:84

ほとんどの場合、サーバー側のレンダリングが正しく構成されていない可能性があります。サーバ側バンドルのコンパイルにwebpackを使用していない場合、isomorphic-style-loaderはサーバ側でファイルを処理していないため、適切なスタイルはロードされません。アプリケーションはwebpackはサーバーバンドルと構成に適用されていたことを、開始し、確保された方法
チェックはこのようなものだった:https://webpack.js.org/configuration/node/
また、あなたは、フロントエンド+バックエンドバンドルと準備同型のソリューションを試してみて、resolve-appのように、CSSのサポートが含まれてすることができます。

関連する問題