Skip to content

azegas/iamjunior-home-service

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

About the project

https://www.iamjunior.lt/front-end-akceleratorius-javascript course task.

To find tasks of this project see TASKS.md file.

Live site

Frontend - https://frontend-one-mu-96.vercel.app/

Backend - https://backend-eta-sable-64.vercel.app/

Working directory - https://github.com/azegas/iamjunior-home-service

Run project

Clone the project

git clone https://github.com/azegas/iamjunior-home-service
# choose a correct branch
cd iamjunior-home-service

Run backend

To start the API server, run the following commands:

cd backend
# set the environment variables to .env file
cp .env_template .env
npm i
npm run dev

When site has been launched:

Database is in MongoDB over at - https://www.mongodb.com (accessed from all ips (0.0.0.0/0) - configured on mongo atlas side)

To recreate the database, run the following command:

cd utils
node recreate-db.js

Run frontend

# make sure backend server is running first
cd frontend
npm i
npm run client
# open http://localhost:5173/ in your browser to preview the site

Guides

Setup database

MongoDB is used for the database - https://www.mongodb.com/

Register/login, etc.

Create a new project, choose a free tier.

Create a cluster.

Take the connection string, it will look something like this:

mongodb+srv://<username>:<password>@<cluster-address>/<dbname>?retryWrites=true&w=majority

Add the connection string to the .env file in the backend folder. Use .env_template as a template.

Create a DB connecting function, use it when server is starting.

Then create models, whenever (tables in the db will be created automatically when you connect to the db).

Then when you are saving data, use the models to write/edit/delete entries to the db.

Setup linting/formatting

This step is totally optional, but recommended for development experience.

Both frontend and backend folders have their own linting/formatting rules, separate configuration files also.

Eslint linter CAN contain stylistic rules, but then it might conflict with Prettier (.prettierrc).

That is why we will use eslint for code quality rules, and Prettier for stylistic rules.

Linting

Install needed dependencies (frontend/backend):

# Linting for backend
cd backend
# choose (commonjs, no react, node(not browser))
npm init @eslint/config@latest


# Linting for frontend
cd frontend
# choose (commonjs, react, browser)
npm init @eslint/config@latest

Install needed extensions:

Name: ESLint
Id: dbaeumer.vscode-eslint
Description: Integrates ESLint JavaScript into VS Code.
Version: 3.0.10
Publisher: dbaeumer
VS Marketplace Link: https://marketplace.cursorapi.com/items?itemName=dbaeumer.vscode-eslint

Setup needed files (frontend/backend):

.eslint.config or something similar file should be setup already in your chosen folder by the previous command. One for frontend and one for backend.

# example rules:

rules: {
  'react/react-in-jsx-scope': 'off',
  'react/prop-types': 'off',
  'no-console': 'error'
}

configure eslint rules (all eslint rules - https://eslint.org/docs/latest/rules/)

Setup package.json (frontend/backend):

"scripts": {
    "lint": "eslint ."
}

Setup user settings JSON in vscode:

"editor.codeActionsOnSave": {
  "source.fixAll": "explicit"
}

Run lint manually for all the files in the folder (frontend/backend):

npm run lint

Formatting

Prettier is used for formatting().

Prettier already contains some rules, but we can add more/override existing ones by creating a configurations file. More about it later.

Install needed dependencies (frontend/backend):

npm install --save-dev prettier

Install needed extensions:

Name: Prettier - Code formatter
Id: esbenp.prettier-vscode
Description: Code formatter using prettier
Version: 11.0.0
Publisher: esbenp
VS Marketplace Link: https://marketplace.cursorapi.com/items?itemName=esbenp.prettier-vscode

Setup needed files (frontend/backend):

.prettierrc or something similar file should be setup already in your chosen folder by the previous command. One for frontend and one for backend.

Example .prettierrc file (try not to add rules you dont understand):

{
  "singleQuote": true
}

Setup user settings JSON in vscode:

  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  }

Setup package.json (frontend/backend):

"scripts": {
    "format": "prettier --write ."
}

Run formatting manually for all the files in the folder (frontend/backend):

npm run format

Setup deployment

Install vercel GLOBALLY:

npm i -g vercel
vercel login

Deploy backend (Node/Express)

You will notice that we don't need to "build" the backend.

Environment variables can be used in the backend code, they don't need to have any prefix, can be reached with process.env.VARIABLE_NAME.

Make sure you are in the main/master branch.

cd backend

Make sure to have:

...
import path from "path";

const app = express();
app.use(express.static(path.join(__dirname, "../", "public")));

Also have index.html file in the public folder.

Create backend/vercel.json:

For a JavaScript project:

{
  "version": 2,
  "builds": [
    {
      "src": "server.js",
      "use": "@vercel/node",
      "config": { "includeFiles": ["./**"] }
    }
  ],
  "routes": [
    {
      "src": "/(.*)",
      "dest": "server.js"
    }
  ]
}

For a TypeScript project:

Vercel can not deploy our TypeScript files, it has to deploy .js files. For that we first transpile the TypeScript files to .js files with the tsc command. during build process package.json. It generates the dist folder with all the .js files and this folder can be deployed.

A hack was also made for swagger-ui-express to work with Vercel by including the node_modules/swagger-ui-dist folder in the build process (otherwise we would get "uncaught ReferenceError: SwaggerBundle is not defined" error). I feel like this is a workaround, not a solution. Good enoguh for my case now, but should be investigated more in the future. Now we just found what swagger needs and provided it to it to work. This was not needed for JavaScript project as you can see in the vercel.json example above.

{
  "version": 2,
  "builds": [
    {
      "src": "dist/server.js",
      "use": "@vercel/node",
      "config": {
        "includeFiles": ["./dist/**", "./node_modules/swagger-ui-dist/**"]
      }
    }
  ],
  "routes": [
    {
      "src": "/(.*)",
      "dest": "dist/server.js"
    }
  ]
}

package.json add deploy commands:

"scripts": {
    "deploy": "vercel --prod"
}

TODO write docs about vercel deployment (after ts conversion)

Vercel most likely automatically sets this variables - NODE_ENV to be "production" when we are deploying. SOOOOOOO, we can use it and make some conditional logic in the code. Find all the process.env.NODE_ENV === 'production' to see what we change to run in production and locally.

cd backend
vercel login
npm run deploy

Deploy frontend (Vite/React)

You will notice that we need to "build" the frontend.

Environment variables can be used in the frontend code, but they need to be prefixed with VITE_, can be reached with import.meta.env.VITE_VARIABLE_NAME.

Make sure you are in the main/master branch.

cd frontend
vercel login
vercel

Make sure all the http://localhost:3000/api/... endpoints are changed to use backend vercel url. Don't place it directly in the code, but in .env file instead. The trick is to use import.meta.env.VITE_SERVER_URL_PROD in the frontend code instead of process.env.SERVER_URL.

import.meta.env: In Vite, you use import.meta.env to access environment variables instead of process.env.

Prefix with VITE*: Vite requires all environment variables to be prefixed with VITE* to expose them in the client code.

Package.json add deploy commands:

"scripts": {
    "deploy": "npm run build && vercel --prod"
}

Create frontend/vercel.json:

When deploying to production with npm run deploy, the VITE_PROD environment variable will always be forced to be true (as a consequence backend server will be used instead of localhost). Locally we can set it to false by changing the value in .env file.

{
  "build": {
    "env": {
      "VITE_PROD": "true"
    }
  }
}

Deploy frontend:

cd frontend
vercel login
npm run deploy

CORS

Add frontend url to backend cors config.

Redeploy backend.

Database server is open to all ips (0.0.0.0/0) - configured on mongo atlas side.

Backend server is open to - ?????????

Frontend server is open to - ?????????