reactjs – How to deploy react application on heroku using .gitlab-ci.yml

I have created a React app and used webpack to bundle it. Now I am trying to deploy the app on Heroku. The build is successful but when I try to open the link I get “Application Error”.

This is my webpack file

import * as webpack from 'webpack';
import * as webpackDevServer from 'webpack-dev-server';
import path from "path";
import { Configuration, DefinePlugin } from "webpack";
import HtmlWebpackPlugin from "html-webpack-plugin";
import ForkTsCheckerWebpackPlugin from "fork-ts-checker-webpack-plugin";
import TsconfigPathsPlugin from "tsconfig-paths-webpack-plugin";
import MiniCssExtractPlugin from "mini-css-extract-plugin";


const webpackConfig = (): webpack.Configuration => ({
    entry: [
        './src/index.tsx',
        './src/styles/base.scss',
    ],
    resolve: {
        extensions: [".ts", ".tsx", ".js"],
        plugins: [new TsconfigPathsPlugin({ configFile: "./tsconfig.json" })],
        mainFields: ["module", "browser", "main"],
        alias: {
            "@styles": path.resolve(__dirname, "./src/styles"),
            "@views": path.resolve(__dirname, "./src/views"),
        }
    },
    output: {
        path: path.join(__dirname, "/dist"),
        filename: "bundle.js",
    },
    module: {
        rules: [
            {
                test: /.tsx?$/,
                loader: "ts-loader",
                options: {
                    transpileOnly: true,
                },
                exclude: /dist/,
            },
            {
                test: /.s?css$/,
                use: ["style-loader", "css-loader", "sass-loader"],
            },
            {
                test: /.(?:ico|gif|png|jpg|jpeg)$/i,
                type: 'asset/resource',
            },
            {
                test: /.(woff(2)?|eot|ttf|otf|svg|)$/,
                type: 'asset/inline',
            },
        ],
    },
    devServer: {
        port: process.env.PORT || 3000,
        open: true,
        historyApiFallback: true,
    },
    plugins: [
        // HtmlWebpackPlugin simplifies creation of HTML files to serve your webpack bundles
        new HtmlWebpackPlugin({
            template: "./public/index.html",
            favicon: "./src/assets/images/favicon.ico"
        }),
        // DefinePlugin allows you to create global constants which can be configured at compile time
        new DefinePlugin({
            "process.env": process.env.production || !process.env.development
        }),
        // MiniCssExtractPlugin extracts CSS into separate files to support On-Demand-Loading of CSS and SourceMaps.
        new MiniCssExtractPlugin({
            filename: "[hash].css",
        }),
        // Speeds up TypeScript type checking and ESLint linting (by moving each to a separate process)
        new ForkTsCheckerWebpackPlugin(),
    ],
});

export default webpackConfig;

This is my package.json

{
  "name": "Onepeice",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-cli serve --mode=development --env development --open --hot",
    "build": "npm run clean && webpack --mode=production --env production --progress",
    "lint": "eslint src/**/*.{ts,tsx} --quiet --fix",
    "clean": "rimraf dist"
  },
  "keywords": [],
  "author": "Luffy",
  "license": "ISC",
  "dependencies": {
    "@draft-js-plugins/editor": "^4.1.3",
    "@draft-js-plugins/mention": "^5.2.1",
    "@react-oauth/google": "^0.2.4",
    "add": "^2.0.6",
    "axios": "^0.27.2",
    "dotenv": "^16.0.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.3.0",
    "serve": "^13.0.2"
  },
  "devDependencies": {
    "@types/fork-ts-checker-webpack-plugin": "^0.4.5",
    "@types/html-webpack-plugin": "^3.2.6",
    "@types/node": "^17.0.21",
    "@types/react": "^17.0.41",
    "@types/react-dom": "^17.0.14",
    "@types/react-router": "^5.1.18",
    "@types/react-router-dom": "^5.3.3",
    "@types/webpack": "^5.28.0",
    "@types/webpack-dev-server": "^4.7.2",
    "@typescript-eslint/eslint-plugin": "^5.15.0",
    "@typescript-eslint/parser": "^5.15.0",
    "css-loader": "^6.7.1",
    "eslint": "^8.11.0",
    "eslint-plugin-import": "^2.25.4",
    "eslint-plugin-react": "^7.29.4",
    "eslint-plugin-react-hooks": "^4.3.0",
    "fork-ts-checker-webpack-plugin": "^7.2.1",
    "html-webpack-plugin": "^5.5.0",
    "mini-css-extract-plugin": "^2.6.0",
    "node-sass": "^7.0.1",
    "react-router": "^6.3.0",
    "sass-loader": "^12.6.0",
    "style-loader": "^3.3.1",
    "ts-loader": "^9.2.8",
    "ts-node": "^10.7.0",
    "tsconfig-paths-webpack-plugin": "^3.5.2",
    "typescript": "^4.6.2",
    "webpack": "^5.70.0",
    "webpack-cli": "^4.9.2",
    "webpack-dev-server": "^4.7.4"
  }
}

this is my .gitlab-ci.yml file

cache:
  paths:
    - node_modules/


image: node:16.13.0

before_script:
    - apt-get update -qy
    - apt-get install -y ruby-dev
    - gem install dpl

stages:    
  # - init   
  - dev-build
  - dev-deploy
  - test-dev
  - qa-deploy
  - prod-deploy
  # - build-qa
  # - test-qa
  # - deploy-qa

# init:
#   stage: init
#   image: node:12.16.1
#   script:
#     - npm install

dev-build:
    stage: dev-build
    image: node:16.13.0
    script:
        - npm i
        - npm run clean
        - npm run build
    only:
        - develop

dev-deploy:
    stage: dev-deploy
    image: ruby:latest
    script:
        - dpl --provider=heroku --app=dev-deploy --api-key=$HEROKU_API_KEY
    only:
        - develop

test-dev:   # This job runs in the test stage.
  stage: test-dev   # It only starts when the job in the build stage completes successfully.
  script:
    - echo "Running unit tests... This will take about 60 seconds."
    - sleep 11
    - echo "Code coverage is 90%"

# lint-test-job:   # This job also runs in the test stage.
#   stage: test    # It can run at the same time as unit-test-job (in parallel).
#   script:
#     - echo "Linting code... This will take about 10 seconds."
#     - sleep 10
#     - echo "No lint issues found."


qa-deploy:     
  image: node:12.16.1
  stage: qa-deploy
  script:
    - git push https://$HEROKU_USER:$HEROKU_API_KEY@git.heroku.com/qa-coditas.git HEAD:qa
    - echo "Deployed to qa Heroku"
  environment:  
    name: qadep
    url: https://qa-test.herokuapp.com/
  only:
    - qa


prod-deploy:       
  image: node:12.16.1
  stage: prod-deploy
  script:
    - git push https://$HEROKU_USER:$HEROKU_API_KEY@git.heroku.com/rnr-coditas.git HEAD:main
    - echo "Deployed to main/prod to Heroku"
  environment:  
    name: prod
    url: https://test-test.herokuapp.com/
  only:
    - main

And this is the Procfile

web: node dist/bundle.js

Build is success but in Heroku logs I’m getting this

2022-06-24T02:35:41.475016+00:00 app[web.1]:
2022-06-24T02:35:41.475018+00:00 app[web.1]: ReferenceError: document is not defined
2022-06-24T02:35:41.475019+00:00 app[web.1]: at /app/dist/bundle.js:2:5885509
2022-06-24T02:35:41.475019+00:00 app[web.1]: at Object.<anonymous> (/app/dist/bundle.js:2:5885575)
2022-06-24T02:35:41.475020+00:00 app[web.1]: at Module._compile (node:internal/modules/cjs/loader:1105:14)
2022-06-24T02:35:41.475020+00:00 app[web.1]: at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
2022-06-24T02:35:41.475021+00:00 app[web.1]: at Module.load (node:internal/modules/cjs/loader:981:32)
2022-06-24T02:35:41.475021+00:00 app[web.1]: at Function.Module._load (node:internal/modules/cjs/loader:822:12)
2022-06-24T02:35:41.475022+00:00 app[web.1]: at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
2022-06-24T02:35:41.475022+00:00 app[web.1]: at node:internal/main/run_main_module:17:47
2022-06-24T02:35:41.604108+00:00 heroku[web.1]: Process exited with status 1
2022-06-24T02:35:41.815335+00:00 heroku[web.1]: State changed from starting to crashed
2022-06-24T02:36:08.759352+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=deve-deploy.herokuapp.com request_id=05171739b-0218-49ba-abf5-8b0f429b9688 fwd="103.121.253.17" dyno= connect= service= status=503 bytes= protocol=https

Leave a Comment