GithubHelp home page GithubHelp logo

node-js-webapp-monorepo's Introduction

node-js-webapp-monorepo

(WIP)

This repository showcases an example of a full-stack web application using NestJS for the backend and Next.js for the frontend, organized within a monorepo structure. The goal is to provide a seamless development experience while maintaining clear separation of concerns between the server and client-side code.

Features

  • NestJS Backend: A robust, scalable server-side framework for building efficient and reliable server-side applications.
  • Next.js Frontend: A React-based framework for building user-friendly and performant web frontends.
  • Monorepo Structure: Utilizing Turborepo to manage both backend and frontend in a single repository, enabling shared code and easier dependency management.
  • TypeScript Support: Full TypeScript support for type-safe code across both NestJS and Next.js.
  • Containerized: Both the backend and frontend applications are fully containerized, allowing for consistent development environments and easy developing.
  • OpenAPI support: Automatically generate interactive API documentation with Swagger, integrated seamlessly within the NestJS backend.

Prerequisites

  • Node.js (version 20 or later)
  • npm/yarn/pnpm

Structure

  • /backend: NestJS Backend Application
  • /frontend: Next.js Frontend Application
  • /docker-compose.yaml:

How to use

$ git clone https://github.com/Kourin1996/node-js-webapp-monorepo.git
$ docker-compose up
$ cd apps/backend && pnpm dlx prisma migrate dev

How to setup project in your environment

This section guides you how to setup such environment step by step.

Initialize monorepo style project by Turborepo. Type name of root project and the directory will be created after the command.

$ pnpm dlx create-turbo@latest

? Where would you like to create your turborepo? node-js-webapp-monorepo
? Which package manager do you want to use? pnpm workspaces

Turborepo setup some child projects called app and package. You can remove existing projects apps/docs & apps/web

Setup Backend

Initialize NestJS

Initialize NestJS project under apps.

$ pnpm add @nestjs/cli -g
$ cd apps && nest new backend

Create packages/eslint-config/nest.js.

// packages/eslint-config/nest.js
const { resolve } = require("node:path");

const project = resolve(process.cwd(), "tsconfig.json");

/** @type {import("eslint").Linter.Config} */
module.exports = {
  extends: [
    "plugin:@typescript-eslint/recommended",
    "plugin:prettier/recommended",
    "eslint-config-turbo",
  ],
  plugins: ["@typescript-eslint/eslint-plugin"],
  env: {
    node: true,
    jest: true,
  },
  rules: {
    "@typescript-eslint/interface-name-prefix": "off",
    "@typescript-eslint/explicit-function-return-type": "off",
    "@typescript-eslint/explicit-module-boundary-types": "off",
    "@typescript-eslint/no-explicit-any": "off",
  },
  settings: {
    "import/resolver": {
      typescript: {
        project,
      },
    },
  },
  ignorePatterns: [".*.js", "node_modules/"],
  overrides: [{ files: ["*.js?(x)", "*.ts?(x)"] }],
};

Modify apps/backend/.eslintrc.js.

// apps/backend/.eslintrc.js

/** @type {import("eslint").Linter.Config} */
module.exports = {
  root: true,
  extends: ["@repo/eslint-config/nest.js"],
  parser: "@typescript-eslint/parser",
  parserOptions: {
    project: true,
  },
};

Create packages/typescript-config/nestjs.json.

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "display": "NestJS",
  "extends": "./base.json",
  "compilerOptions": {
    "module": "NodeNext",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "ES2021",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "skipLibCheck": true,
    "strictNullChecks": false,
    "noImplicitAny": false,
    "strictBindCallApply": false,
    "forceConsistentCasingInFileNames": false,
    "noFallthroughCasesInSwitch": false
  }
}

Modify apps/backend/tsconfig.json.

{
  "extends": "@repo/typescript-config/nextjs.json",
  "compilerOptions": {
    "plugins": [
      {
        "name": "next"
      }
    ]
  },
  "include": ["**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}

Initialize Prisma

$ cd apps/backend
$ pnpm add prisma @prisma/client
$ pnpm dlx prisma init

Add docker-compose.yaml in project root.

version: "3.9"
services:
  postgres:
    image: postgres:16.1-alpine
    ports:
      - 5432:5432
    volumes:
      - ./persist/postgres:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=database
      - POSTGRES_USER=test_user
      - POSTGRES_PASSWORD=test_password

Run docker-compose up -d to start DB in project root.

$ docker-compose up -d

[+] Running 2/2
 ✔ Network node-js-webapp-monorepo_default       Created                                                                                                                                                                                                            0.1s
 ✔ Container node-js-webapp-monorepo-postgres-1  Started

Modify apps/backend.env and set DATABASE_URL using database name, username, password set in docker-compose.yaml.

DATABASE_URL="postgresql://test_user:test_password@localhost:5432/database?schema=public"

Add new model in apps/backend/prisma/schema.prisma

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model Book {
  @@map("books")

  id Int @id @default(autoincrement())
  name String
  UUID String @unique
  price Int
  created_at DateTime @default(now())
  updated_at DateTime @default(now())
}

Run migrate dev command to create migration files and db pull to apply migrations to DB.

$ cd apps/backend
$ pnpm dlx prisma migrate dev --name init

# apps/backend/prisma/migrations will be created and migrations will be applied to DB

Run generate command to generate client code under apps/backend/src/generated/prisma, which is set in schema.prisma.

$ pnpm dlx prisma generate

Install dependencies

$ cd apps/backend && pnpm add @nestjs/swagger class-validator

Create directories

Setup Next.js

$ cd apps && pnpm dlx create-next-app@latest

Rename apps/frontend/eslintrc.json to apps/frontend/.eslintrc.js and modify it.

// apps/frontend/eslintrc.js

/** @type {import("eslint").Linter.Config} */
module.exports = {
  root: true,
  extends: ["@repo/eslint-config/next.js"],
  parser: "@typescript-eslint/parser",
  parserOptions: {
    project: true,
  },
};

Modify apps/frontend/tsconfig.json

{
  "extends": "@repo/typescript-config/nextjs.json",
  "compilerOptions": {
    "plugins": [
      {
        "name": "next"
      }
    ]
  },
  "include": [
    "next-env.d.ts",
    "next.config.js",
    "**/*.ts",
    "**/*.tsx",
    ".next/types/**/*.ts"
  ],
  "exclude": ["node_modules"]
}

Setup Commands

Add start command in turbo.json

{
  "$schema": "https://turbo.build/schema.json",
  "globalDependencies": ["**/.env.*local"],
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "!.next/cache/**"]
    },
    "lint": {
      "dependsOn": ["^lint"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    },
    "start": {
      "cache": false,
      "persistent": true
    }
  }
}

Docker

node-js-webapp-monorepo's People

Contributors

kourin1996 avatar turbobot-temp avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.