No load / service stylesheets - respond

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 :

enter image description here

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:

enter image description here

enter image description here

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

enter image description here

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)

+8
javascript reactjs webpack
source share
2 answers

I think you have an error in your webpack.config json hierarchy for you css / sass downloaders. Replace the "loaders" array in the module with this "rules" array:

 module: { rules: [ { test: /\.scss$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: ['css-loader', 'sass-loader'] }), }, { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: "css-loader" }) }, ], }, 

Here you can see more examples of using ExtractTextPlugin: https://github.com/webpack-contrib/extract-text-webpack-plugin#usage

+2
source share

You have problems because you are using css-loader/locals but not using ExtractTextPlugin (at least in the Development section). https://github.com/webpack-contrib/css-loader/issues/59

Note. To preload using extract-text-webpack-plugin, you should use css-loader / locals instead of style-loader! css-loader in prerendering package. It does not embed CSS, but only exports identifier mappings.

This also explains why you cannot access the .theHeader style .theHeader .

In addition, the error Resource interpreted as Stylesheet but transferred with MIME type text/html: "http://localhost:3000/app.css". - This is a red herring. This is just an error message that you get if you try to load a stylesheet that does not even exist. Which in this case, it seems, is not in the directory that, in your opinion, is, or is not actually created in the file there.

Since ExtractTextPlugin disabled in development, its likelihood that your CSS is processed only by css-loader/locals . This may not be a production issue, as it connects to ExtractTextPlugin , but may explain your problems with running it in development.


Update:

Studying this a bit more, I came across a blog post that I think will help you understand how to set up your CSS to work the way you want. https://medium.com/@mattvagni/server-side-rendering-with-css-modules-6b02f1238eb1

I think the main reason for the complication is that you are sending the HTML code as a rendering string through ReactDOMServer. So there is no place where webpack enters the <link> . You might want to consider having a <link> in your header to link to the desired CSS file, since webpack is still going to create one CSS file.

Finally, I highly recommend working on webpack a bit, especially since the SSR is a newer process and requires a bit of a different kind of action than many initially thought when webpack was first created.

+2
source share

All Articles