0

I have react-ssr project (webpack, express) with two react components. First one is app component which handles a lot of api calls and stuff. This is worker component the other one is just to list something.

While my first components imported css files bundles and correctly sent to client side. The other component's imported css file does not reach to client.

Here is my webpack.config.js first. As you can see I have app, business entry points. While app entry point bundles everything with imported css. Business does not.

const path = require("path");

const config = {
  entry: {
    vendor: ["@babel/polyfill", "react"],
    app: "./src/components/index.js",
    business: "./src/components/OneBusinessComponent/index.js"
  },
  output: {
    path: path.resolve(__dirname, "public"),
    filename: "[name].js",
    publicPath: '/public'
  },
  module: {
    rules: [
      {
        test: /\.js$|jsx/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env", "@babel/preset-react"]
          }
        },
        exclude: /node_modules/
      },
      {
        test: /\.css$/,
        use: ['style-loader','css-loader'],
      }
    ]
  },
  resolve: {
    extensions: [".js", ".jsx", ".json", ".wasm", ".mjs", "*"]
  }
};

module.exports = config;

Here is my routes which I serve these two components

import express from "express";
import App from '../components/app';
import OneBusiness from '../components/OneBusinessComponent/oneBusiness'
import React from 'react';
import { renderToString } from 'react-dom/server';
import hbs from 'handlebars';
import { Provider } from 'react-redux'
import store from '../redux/store'
import con from '../config/mysqlConfig'
import mysql from 'mysql';
con.connect(function (err) {
    if (err) throw err;
    console.log("Connected")
})

const router = express.Router();
router.get("/", async (req, res) => {
    // <script src="/public/app.js" charset="utf-8"></script>
    // <script src="/public/vendor.js" charset="utf-8"></script>

    const theHtml = `
    <html>
     <head><title>Local Data</title></head>
    
    
    
    <body>
    
    <div id="reactele">{{{reactele}}}</div>
    <script src="app.js" charset="utf-8"></script>
    <script src="vendor.js" charset="utf-8"></script>
    
    </body>
    </html>
    `;
    const hbsTemplate = hbs.compile(theHtml)
    const reactComp = renderToString(<Provider store={store}>
        <App />
    </Provider>)
    const htmlToSend = hbsTemplate({ reactele: reactComp })


    res.send(htmlToSend);

});

router.get("/biz/:name/:city/:state/:id", async (req, res) => {

    console.log(req.params)
    
    let query = "SELECT * FROM final_businesses WHERE id= " + req.params.id.toString()
    console.log(query)
    con.query(query, (err, data) => {
        if (err) {

        }
        
        const theHtml = `
        <html>
            <head><title>My First SSR</title></head>
        <body>
        
        <div id="reactele">{{{reactele}}}</div>
        <script src="business.js" charset="utf-8"></script>
        <script src="vendor.js" charset="utf-8"></script>
        
        
        </body>
        </html>
        `;
        const hbsTemplate = hbs.compile(theHtml)
        console.log(hbsTemplate)
        const reactComp = renderToString(<OneBusiness params={data[0]}></OneBusiness>)
        console.log(reactComp)
        const htmlToSend = hbsTemplate({ reactele: reactComp })


        res.send(htmlToSend);
    })

});
export default router;

As I checked my business.js bundled file now it actually bundles css but may be because of routing it does not add css file as source to client side. Below is start of bundled business.js.

(()=>{"use strict";var e={3138:(e,t,n)=>{n.d(t,{Z:()=>a});
var r=n(3645),l=n.n(r)()((function(e){return e[1]}));l.push([e.id,'.info-label {\n    
color:white;\n    
font-family: "Segoe UI\', Tahoma, Geneva, Verdana, sans-serif";\n    
width: 100%;\n    
border:1px solid red;\n    \n}\n.
info-key {\n    
color:orange;\n    
font-family: "Segoe UI\', Tahoma, Geneva, Verdana, sans-serif";\n}\n.  
.nothing{\n    
background-color: blue;\n    
margin: 40px\n}\n.different {\n    
width: 500px;\n    
height: 500px;\n    
background-color: aqua;\n    \n}',""]);

This looks like I am accomplishing bundling. But my second route includes a lot of params. When I check google chrome source section. It shows my routes like file directories. I am using hbs template engine to embed my react component inside.

I am stuck with this for three days, any help will be appreciated.

  • are you importing css files into your components? – Yilmaz Dec 30 '20 at 16:04
  • @Yilmaz Yes Sir, In app.js there is inner component which is MainPageContainer and I imported mainPage.css there, It returns that css to client side. While in second root css not loaded which is business.js. I guess since I am rooting the app js as default route '/' and I am routing second component as /biz/bus_name/bus_city/bus_state this may be a problem. – Selim Mıdıkoğlu Dec 30 '20 at 17:29
  • If you jhave github repo, i ll look into. in webpack loaders does one thing. so style-loader does not care about the structure of your app, all it does, it sees css code and injects it. – Yilmaz Dec 30 '20 at 17:40
  • @yilmaz https://github.com/selimmidikoglu/ssr-localdata Here it is, I made it public now. – Selim Mıdıkoğlu Dec 30 '20 at 17:49
  • Since u have struggling for 3 days, I am working on it. I know how it feels – Yilmaz Dec 30 '20 at 17:51
  • @If you are Turkish, Abi çok sağol, If you are not Thank you so much Sir. If you want to include more details I am in this channel https://discord.gg/pSRXwMCg. – Selim Mıdıkoğlu Dec 30 '20 at 17:57
  • Selim, yes I am turkish but we are not allowed to chat in turkish. It will be considered scam. Since you are really trying to do ssr, you need to have 2 webpack config files. one for server, and one for client. server bundle should never ever been sent to the client, it cannot be public because you will be sending all server side secrets to the client and in server bundle, you dont use style loader because there is no DOM in ssr. server bundle is different than client bundle. Sorry but your app structure is not set up for ssr – Yilmaz Dec 30 '20 at 18:16
  • @Thank you so much. Is there any sample structure you would share with me? Additionally a sample would be better which has two different confs for webpack. – Selim Mıdıkoğlu Dec 30 '20 at 18:28
  • https://github.com/yilmazbingo/typrescript-reactSSR this is written in typescript i m still working on it. but can get an idea about the structure of ssr. I m looking for another one – Yilmaz Dec 30 '20 at 18:33
  • https://github.com/yilmazbingo/webpack-server-side-rendering this is without js but more complex. good luck – Yilmaz Dec 30 '20 at 18:35

0 Answers0