I am trying to use SSR with React router StaticRouter .
express.js (server)
const html = ReactDOMServer.renderToString( <StaticRouter location={req.url} context={context}> <App /> </StaticRouter> ); res.status(200).send(` <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="/app.css" type="text/css"/> </head> <body> <div id="app">${html}</div> </body> </html> `);
Static File Maintenance:
app.use(express.static(path.resolve(__dirname, "../dist/client")));
App.js (general)
import React from "react"; import { Switch, Route } from "react-router"; export default () => { return ( <Switch> ... </Switch> ); };
index.jsx (client)
import React from "react"; import { BrowserRouter } from "react-router-dom"; import ReactDOM from "react-dom"; import App from "./App"; ReactDOM.render( <BrowserRouter> <App/> </BrowserRouter>, document.getElementById("app") );
./styles/Main.scss
.header { background-color: #002933; }
I have 2 webpack configurations, 1 for the client and 1 for the server:
webpack.config.dev.js
const nodeExternals = require("webpack-node-externals"); const webpack = require("webpack"); const ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { devtool: "cheap-module-eval-source-map", entry: { app: [ "eventsource-polyfill", "webpack-hot-middleware/client", "webpack/hot/only-dev-server", "react-hot-loader/patch", "./client/index.jsx", ], vendor: [ "react", "react-dom", ], }, output: { path: `${__dirname}/dist/client`, ... }, ... module: { loaders: [ ... }, { test: /\.scss$/, exclude: /node_modules/, loader: ExtractTextPlugin.extract({ fallback: "style-loader", use: [ { loader: "css-loader", query: { localIdentName: "[hash:8]", modules: true } }, { loader: "postcss-loader" }, { loader: "sass-loader" } ] }), }, ], }, plugins: [ new ExtractTextPlugin({ filename: "[name].css", allChunks: true }), ] };
webpack.config.server.js
const ExternalsPlugin = require("webpack-externals-plugin"); module.exports = { ... output: { path: `${__dirname}/dist/`, filename: "server.bundle.js", }, ... resolve: { ... modules: [ "client", ], }, module: { loaders: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, loader: "babel-loader", }, { test: /\.scss$/, loader: 'style-loader!css-loader/locals?module&localIdentName=[name]__[local]___[hash:base64:5]!sass-loader', }, ], }, plugins: [ new ExternalsPlugin({ type: "commonjs", include: `${__dirname}/node_modules/`, }), ], };
I have a jsx file where .header should be applied to:
import React from "react"; import Links from "./Links.jsx"; import profilePic from "../../img/brand/profilePic.jpg"; import styles from "../../styles/Main.scss"; export default class Header extends React.Component { constructor() { super(); } render() { return ( <header className={styles.header}> <img src={profilePic} alt="Professional Picture"/> <h5>{this.props.pageName}</h5> <Links/> </header> ); } }
This causes an error:
TypeError: Cannot read property 'header' of undefined at Header.render (E:/Documents/Projects/website/client/js/components/Header.jsx:22:30) at resolve (E:\Documents\Projects\website\node_modules\react-dom\cjs\react-dom-server.node.development.js:2149:18) at ReactDOMServerRenderer.render (E:\Documents\Projects\website\node_modules\react-dom\cjs\react-dom-server.node.development.js:2260:22) at ReactDOMServerRenderer.read (E:\Documents\Projects\website\node_modules\react-dom\cjs\react-dom-server.node.development.js:2234:19) at Object.renderToString (E:\Documents\Projects\website\node_modules\react-dom\cjs\react-dom-server.node.development.js:2501:25) at E:/Documents/Projects/website/server/config/lib/express.js:204:31 at Layer.handle [as handle_request] (E:\Documents\Projects\website\node_modules\express\lib\router\layer.js:95:5) at trim_prefix (E:\Documents\Projects\website\node_modules\express\lib\router\index.js:317:13) at E:\Documents\Projects\website\node_modules\express\lib\router\index.js:284:7 at Function.process_params (E:\Documents\Projects\website\node_modules\express\lib\router\index.js:335:12) at next (E:\Documents\Projects\website\node_modules\express\lib\router\index.js:275:10) at p3p (E:\Documents\Projects\website\node_modules\lusca\lib\p3p.js:15:9) at E:\Documents\Projects\website\node_modules\lusca\index.js:59:28 at xframe (E:\Documents\Projects\website\node_modules\lusca\lib\xframes.js:12:9) at E:\Documents\Projects\website\node_modules\lusca\index.js:59:28 at xssProtection (E:\Documents\Projects\website\node_modules\lusca\lib\xssprotection.js:16:9)
When the application starts, Webpack reports that a stylesheet has been loaded :

EDIT
Besides importing ES6, I tried using CommonJS ' require() as in MERN , but still not looking ..
When I create the webpack configuration for the server, I get an error:
ERROR in (webpack)-dev-middleware/node_modules/mime/index.js Module not found: Error: Can't resolve './types/standard' in 'E:\Documents\Projects\website\node_modules\webpack-dev middleware\node_modules\mime' @ (webpack)-dev-middleware/node_modules/mime/index.js 4:26-53 @ (webpack)-dev-middleware/index.js @ ./server/config/lib/express.js @ ./server/config/lib/app.js @ ./server/server.js
Iβm not sure if itβs red-herring or not in this situation or not, but I thought it was worth mentioning here, since I'm completely lost. Feel as though I am clutching a straw at that moment.
This is my .babelrc :
{ "presets": [ "react", "es2015", "stage-0" ], "plugins": [ "react-hot-loader/babel", "transform-decorators-legacy" ], "env": { "server": { "plugins": [ [ "css-modules-transform", { "preprocessCss": "./loaders/sass-loader.js", "generateScopedName": "[hash:8]", "extensions": [".scss"] } ] ] }, "production": { "presets": [ "es2015", "react", "react-optimize", "es2015-native-modules", "stage-0" ] } } }
I tried to get back to basics and attached to the server on the buffer side instead of webpack. This was built from a tutorial for SSR with CSS modules. I was kindly associated with @mootrichard
EDIT 2
Some observations that might help ... when using es6 import for style sheets:
import styles from "../../styles/Main.scss";
and log styles in the console, it returns undefined (proof that it cannot find the file for any reason).
When placing the <link> in the head for the start page, the <link> present in the markup, but not on the network:


However, when switching to localhost:8000/app.css , a positive response is returned with the style:

If the browser can find the standalone version in the kit, then why doesn't it load on my start page? (The path is true)