My FeedDiscussionsHeadless CMS
New
Sign in
Log inSign up
Learn more about Hashnode Headless CMSHashnode Headless CMS
Collaborate seamlessly with Hashnode Headless CMS for Enterprise.
Upgrade ✨Learn more

I need to know the flow of this MERN app.

Dave Rodriguez's photo
Dave Rodriguez
·Jun 12, 2020

I am looking to get to know the flow of a MERN application. I want to know how everything is taking place; who is serving whom. How React and Express are connected to each other? Can anyone explain me like five, what happens, say, a request is made from the client. I need to know the whole process in between. Why did we use an ejs template here? Is this app Server Side Rendered or Client Side Rendered? I am using React and Redux on the frontend and Express and MongoDB on the backend. But I'm confused how's everything connected. Please shed some light as I'm really confused. Thanks.

Folder structure:

Screenshot 2020-06-12 12:33:24.png

webpack.config.js

/* eslint-disable */
var webpack = require("webpack")
var path = require("path")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")

module.exports = {
  mode: "development",
  devtool: "inline-source-map",
  entry: ["./client/index.js"],
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: { loader: "babel-loader" },
      },
      {
        test: /\.(scss|css)$/,
        use: [
          { loader: MiniCssExtractPlugin.loader },
          {
            loader: "css-loader",
          },
          { loader: "sass-loader" },
        ],
      },
      {
        test: /\.(png|jpg|gif|jpeg)$/,
        use: [
          {
            loader: "file-loader",
            options: {},
          },
        ],
      },
    ],
  },
  resolve: {
    extensions: [".js", ".jsx"],
  },
  output: {
    filename: "bundle.js",
    path: __dirname + "/dist/bundle/",
    publicPath: "/static/",
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.DefinePlugin({
      "process.env": {
        NODE_ENV: JSON.stringify("development"),
      },
    }),
    new MiniCssExtractPlugin({
      filename: "bundle.css",
    }),
  ],
}

app.js

const createError = require("http-errors")
const express = require("express")
const bodyParser = require("body-parser")
const path = require("path")
const cookieParser = require("cookie-parser")
const logger = require("morgan")
const mongoose = require("mongoose")
const dotenv = require("dotenv")

const indexRouter = require("./routes/index")
const userRouter = require("./routes/users")

const app = express()

// view engine setup
app.set("views", path.join(__dirname, "views"))
app.set("view engine", "ejs")

app.use(logger("dev"))
app.use(express.json())
app.use(bodyParser.json())
app.use(express.urlencoded({ extended: false }))
app.use(cookieParser())
app.use(express.static(path.join(__dirname, "public")))

if (process.env.NODE_ENV === "development") {
  const webpack = require("webpack")
  const webpackConfig = require("./webpack.config")
  const compiler = webpack(webpackConfig)

  app.use(
    require("webpack-dev-middleware")(compiler, {
      noInfo: true,
      publicPath: webpackConfig.output.publicPath,
    })
  )

  app.use(require("webpack-hot-middleware")(compiler))
}

mongoose.connect(
  "mongodb://localhost:27017/myApp",
  { useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false },
  function (err) {
    if (err) {
      console.log("Not connected")
    } else {
      console.log("Connected successfully")
    }
  }
)

app.use("/api/v1/users", userRouter)
app.use("/*", indexRouter)

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  next(createError(404))
})

// error handler
app.use(function (err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message
  res.locals.error = req.app.get("env") === "development" ? err : {}

  // render the error page
  res.status(err.status || 500)
  res.render("error")
})

module.exports = app

client/index.js

import React from "react"
import ReactDOM from "react-dom"
import App from "./App"
import { Provider } from "react-redux"
import store from "./store"

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
)

routes/index.js

var express = require("express")
var router = express.Router()

/* GET home page. */
router.get("/*", function (req, res, next) {
  res.render("index", { title: "My App" })
})

module.exports = router

views/index.ejs

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel='stylesheet' href='/static/bundle.css' />
    <script src="https://kit.fontawesome.com/afb66cf461.js" crossorigin="anonymous"></script>
  </head>
  <body>
    <div id="root"></div>
    <script src="/static/bundle.js"></script>
  </body>
</html>