θΏ™ζ˜―indexlocζδΎ›ηš„ζœεŠ‘οΌŒδΈθ¦θΎ“ε…₯任何密码
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions examples/with-nestjs-nextjs-shadcn/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// This configuration only applies to the package manager root.
/** @type {import("eslint").Linter.Config} */
module.exports = {
ignorePatterns: ["apps/**", "packages/**"],
extends: ["@repo/eslint-config/library.js"],
parser: "@typescript-eslint/parser",
parserOptions: {
project: true,
},
};
36 changes: 36 additions & 0 deletions examples/with-nestjs-nextjs-shadcn/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# Dependencies
node_modules
.pnp
.pnp.js

# Local env files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# Testing
coverage

# Turbo
.turbo

# Vercel
.vercel

# Build Outputs
.next/
out/
build
dist


# Debug
npm-debug.log*

# Misc
.DS_Store
*.pem
Empty file.
144 changes: 144 additions & 0 deletions examples/with-nestjs-nextjs-shadcn/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Turborepo Template: Next.js + NestJS + ShadCN

A modern, full-stack monorepo template built with Turborepo, featuring Next.js frontend, NestJS backend, and beautiful ShadCN UI components.

## πŸš€ Features

- **Frontend**: Next.js 15 with App Router, TypeScript, and Tailwind CSS
- **Backend**: NestJS with TypeScript, decorators, and dependency injection
- **UI**: ShadCN UI components with Lucide React icons
- **Monorepo**: Turborepo for fast, incremental builds and caching
- **Shared**: ESLint, TypeScript, and Jest configurations
- **Package Manager**: pnpm with workspace support

## πŸ“ Project Structure

```
β”œβ”€β”€ apps/
β”‚ β”œβ”€β”€ web/ # Next.js frontend
β”‚ └── api/ # NestJS backend
β”œβ”€β”€ packages/
β”‚ β”œβ”€β”€ ui/ # ShadCN UI components
β”‚ β”œβ”€β”€ api/ # Shared DTOs and entities
β”‚ β”œβ”€β”€ eslint-config/ # Shared ESLint config
β”‚ β”œβ”€β”€ typescript-config/ # Shared TypeScript config
β”‚ └── jest-config/ # Shared Jest config
```

## πŸ› οΈ Getting Started

### Prerequisites

- Node.js 20+
- pnpm 8+

### Installation

```bash
# Clone the repository
git clone <your-repo-url>
cd examples/with-nestjs-nextjs-shadcn

# Install dependencies
pnpm install

# Start development servers
pnpm dev
```

### Development

```bash
# Start all apps in development mode
pnpm dev

# Build all apps and packages
pnpm build

# Lint all apps and packages
pnpm lint

# Type check all apps and packages
pnpm typecheck
```

### Adding ShadCN Components

```bash
cd apps/web
npx shadcn@latest add <component-name>
```

## 🎨 UI Components

This template includes several ShadCN components ready to use:

- **Button** - Various sizes and variants
- **Card** - Content containers with header, content, and footer
- **Input** - Form input fields
- **Badge** - Status indicators and labels

## πŸ”§ Configuration

### Turborepo

The project uses Turborepo for build orchestration with:

- Incremental builds
- Intelligent caching
- Parallel execution
- Shared configurations

### TypeScript

Shared TypeScript configurations for:

- Next.js apps
- NestJS apps
- React libraries

### ESLint

Shared ESLint configurations for:

- Next.js apps
- NestJS apps
- React libraries

## πŸ“¦ Packages

### `@repo/ui`

Shared UI components built with ShadCN and Tailwind CSS.

```tsx
import { Button } from "@repo/ui/components/button";
import {
Card,
CardContent,
CardHeader,
CardTitle,
} from "@repo/ui/components/card";
```

### `@repo/api`

Shared DTOs and entities for the NestJS backend.

```typescript
import { CreateLinkDto, UpdateLinkDto, Link } from "@repo/api";
```

## πŸš€ Deployment

### Frontend (Next.js)

Deploy to Vercel, Netlify, or any static hosting platform.

### Backend (NestJS)

Deploy to Railway, Render, or any Node.js hosting platform.

## πŸ“ License

MIT
4 changes: 4 additions & 0 deletions examples/with-nestjs-nextjs-shadcn/apps/api/.prettierrc.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import config from "@repo/eslint-config/prettier-base";

/** @type {import("prettier").Config} */
export default config;
25 changes: 25 additions & 0 deletions examples/with-nestjs-nextjs-shadcn/apps/api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# With-NestJs | API

## Getting Started

First, run the development server:

```bash
pnpm run dev
```

By default, your server will run at [http://localhost:3000](http://localhost:3000). You can use your favorite API platform like [Insomnia](https://insomnia.rest/) or [Postman](https://www.postman.com/) to test your APIs

You can start editing the demo **APIs** by modifying [linksService](./src/links/links.service.ts) provider.

### ⚠️ Note about build

If you plan to only build this app. Please make sure you've built the packages first.

## Learn More

To learn more about NestJs, take a look at the following resources:

- [Official Documentation](https://docs.nestjs.com) - A progressive Node.js framework for building efficient, reliable and scalable server-side applications.
- [Official NestJS Courses](https://courses.nestjs.com) - Learn everything you need to master NestJS and tackle modern backend applications at any scale.
- [GitHub Repo](https://github.com/nestjs/nest)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { nestJsConfig } from "@repo/eslint-config/nest-js";

/** @type {import("eslint").Linter.Config} */
export default nestJsConfig;
3 changes: 3 additions & 0 deletions examples/with-nestjs-nextjs-shadcn/apps/api/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { nestConfig } from '@repo/jest-config';

export default nestConfig;
8 changes: 8 additions & 0 deletions examples/with-nestjs-nextjs-shadcn/apps/api/nest-cli.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"deleteOutDir": true
}
}
45 changes: 45 additions & 0 deletions examples/with-nestjs-nextjs-shadcn/apps/api/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"name": "api",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "nest start --watch",
"build": "nest build",
"start": "nest start",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"test": "jest",
"test:watch": "jest --watch",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\""
},
"dependencies": {
"@nestjs/common": "^11.0.0",
"@nestjs/core": "^11.0.0",
"@nestjs/platform-express": "^11.0.0",
"@repo/api": "workspace:*",
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1"
},
"devDependencies": {
"@jest/globals": "^29.7.0",
"@nestjs/cli": "^11.0.0",
"@nestjs/schematics": "^11.0.0",
"@nestjs/testing": "^11.0.0",
"@repo/eslint-config": "workspace:*",
"@repo/jest-config": "workspace:*",
"@repo/typescript-config": "workspace:*",
"@types/express": "^4.17.17",
"@types/node": "^22.10.7",
"@types/supertest": "^6.0.0",
"jest": "^29.7.0",
"source-map-support": "^0.5.21",
"supertest": "^7.0.0",
"ts-jest": "^29.2.5",
"ts-loader": "^9.4.3",
"ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0",
"typescript": "5.5.4"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Test, TestingModule } from '@nestjs/testing';
import { describe, it, expect, beforeEach } from '@jest/globals';
import { AppController } from './app.controller';
import { AppService } from './app.service';

describe('AppController', () => {
let appController: AppController;

beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();

appController = app.get<AppController>(AppController);
});

describe('root', () => {
it('should return "Hello World!"', () => {
expect(appController.getHello()).toBe('Hello World!');
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}

@Get()
getHello(): string {
return this.appService.getHello();
}
}
13 changes: 13 additions & 0 deletions examples/with-nestjs-nextjs-shadcn/apps/api/src/app.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Module } from '@nestjs/common';

import { LinksModule } from './links/links.module';

import { AppService } from './app.service';
import { AppController } from './app.controller';

@Module({
imports: [LinksModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Test, TestingModule } from '@nestjs/testing';
import { describe, it, expect, beforeEach } from '@jest/globals';

import { LinksController } from './links.controller';
import { LinksService } from './links.service';

describe('LinksController', () => {
let controller: LinksController;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [LinksController],
providers: [LinksService],
}).compile();

controller = module.get<LinksController>(LinksController);
});

it('should be defined', () => {
expect(controller).toBeDefined();
});
});
Loading