'How to deploy React client and Node server (Both in a single git repository) in Heroku?

Am having a single Git repository where it contains both client and server. This is my Webpack.config.js

const path = require("path");

module.exports = {
    devServer: {
        contentBase: path.resolve(__dirname, "./src"),
        historyApiFallback: true
    },
    entry: path.resolve(__dirname, "./src/index.js"),
    module:{
        rules: [
            {
                test: /\.js$/,
                use:"babel-loader"
            },
            {
                test: /\.css$/,
                use:['style-loader', 'css-loader']
            }
        ]
    },
    output: {
        filename: "bundle.js"
    }

}

So when I run npm run Build Its creating a single file bundle.js. I placed bundle.js in the server static folder

app.get('/',(req,res)=>{
    res.sendFile(path.join(__dirname, 'public', 'index.html'))
    console.log('welcome')  
    res.send(req.sessionID)
})

in index.html

<html>
    <body>
        hello
        <script src='./bundle.js'></script>
    </body>
</html>

if i try to start the node server. i cant see my browser serving the bundle.js am getting the below error

 Uncaught Error: Minified React error #200; visit https://reactjs.org/docs/error-decoder.html?invariant=200 

If this is not the right approach, can anybody suggest a better so that i can deploy both my client and server code in heroku.



Solution 1:[1]

Considering your directory structure (DS) wasn't provided, the DS (in a MERN stack app) I find gives the least issues when deploying to Heroku is the following:

App (root)
|
|
+---client
|   |
|   +---src
|   +---...
|   +---package.json (react)
|
+---models
+---routes
+---package.json (node)
+---Procfile
+---server.js

Your package.json (node) scripts should look something like this (keeping other custom scripts):

"scripts": {
  "start": "nodemon server.js",
  "heroku-postbuild": "npm install --prefix client && npm run build --prefix client"
}

Procfile should be:

web: node server.js

The package.json (react) scripts should stay relatively unchanged:

"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"

}

I understand that you have customized a Webpack.config.js, bundle.js, and index.html, and that your app functionality has a particularly defined implementation - for purposes of providing insight and potentially helping you reach a resolve, here's what has worked and what continues to work for me...

In the server.js:

app.use("/", routes);

if (process.env.NODE_ENV === "production") {
  app.use(express.static(path.join(__dirname, "/client/build")));

  app.get("*", (req, res) => {
    res.sendFile(path.join(__dirname, "client", "build", "index.html"));
  });
}

Notice that I'm declaring the use of my routes above, which has worked for me.

Hope this guides you...

Solution 2:[2]

you can deploy them to separate Heroku dynos to deploy two apps.

More information regarding this is present in this Deploy two separate heroku apps from same git repo

Note: It is always a good option to serve JS files from your API server after building React files.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2