2017-12-01 1 views
0

Ich baue eine isomorphe react-redux App auf NodeJS. Ich rende meine homePage vom Server. Meine Stile werden jedoch nicht in meiner gerenderten Ansicht wiedergegeben. Ich würde gerne Stylesheets importieren, wie ich es auf der Client-Seite mache. Ich habe auch versucht, this article und this, aber keiner von ihnen hat mich tatsächlich, was ich erreichen will.Stylesheet in einen Server importieren gerendert react view - TypeError: style._getCss ist keine Funktion

Hier sind weitere Details zum Projekt.

.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) 
    } 
} 

ich es in meinem homePresenter als

import homePageStyle from './home.scss'; 

und deren Verwendung in meinem div in der gleichen Komponente wie

<div className="component"> 

Wenn ich dies den Import

<div className={homePageStyle.component}> 

zu ändern bekomme ich eine Fehler im Browser

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

Im Browser konnte ich sehen, dass das Div den Klassennamen als 'Komponente' hat; es; es erbt nur nicht die Stile.

Irgendwelche Vorschläge, was mir hier fehlt?

+1

hast du 'import withStyles 'von' isomorphic-style-loader/lib/withStyles '; in deiner react-Komponente verwendet? – Umesh

+0

@Umesh Danke für die Führung. Ich habe eingefügt, aber ich stoße jetzt auf ein anderes Problem. Ich folgte dem Prozess hier https://github.com/kriasoft/isomorphic-style-loader/issues/110 und https://github.com/kriasoft/react-starter-kit/issues/378 und laut der Dokumentation von Isomorphic-style-loader, isomorphic-style-loader bietet zwei Hilfsmethoden für das Styles-Objekt - ._insertCss() (fügt CSS in das DOM ein) und ._getCss() (gibt eine CSS-Zeichenkette zurück). Ich bekomme jedoch den Fehler "TypeError: style._getCss ist keine Funktion bei server.js: 52: 84" – Mona

Antwort

0

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

Höchstwahrscheinlich ist das serverseitige Rendering nicht ordnungsgemäß konfiguriert. Wenn Sie webpack nicht zum Kompilieren des serverseitigen Pakets verwenden, werden die entsprechenden Formate natürlich nicht geladen, da isomorphic-style-loader keine Dateien auf der Serverseite verarbeitet hat.
prüfen, wie Anwendung gestartet wird und sicherstellen, dass webpack für Server-Bundle und Konfiguration angewendet worden war, wie es war: https://webpack.js.org/configuration/node/
Sie können auch bereit isomorph Lösung mit Frontend + Backend Bündelung versuchen und enthält CSS-Unterstützung, wie resolve-app.

Verwandte Themen