next and nest
This commit is contained in:
1 parent
55f69fbbb4
commit
90125aede9
30 files changed
+3754
-344
No files matched your search
+8
-5
@@ -1,7 +1,7 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
node_modules
|
||||
/.pnp
|
||||
.pnp.*
|
||||
.yarn/*
|
||||
@@ -11,14 +11,17 @@
|
||||
!.yarn/versions
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
.next/
|
||||
out/
|
||||
|
||||
# nest.js
|
||||
dist/
|
||||
|
||||
# production
|
||||
/build
|
||||
build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
|
||||
@@ -1,36 +1,51 @@
|
||||
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
|
||||
Monorepo con [npm workspaces](https://docs.npmjs.com/cli/v10/using-npm/workspaces) que combina un backend [NestJS](https://nestjs.com) y un frontend [Next.js](https://nextjs.org).
|
||||
|
||||
## Getting Started
|
||||
## Estructura
|
||||
|
||||
First, run the development server:
|
||||
```
|
||||
apps/
|
||||
api/ NestJS — servidor HTTP real del proyecto
|
||||
web/ Next.js (App Router) — frontend
|
||||
```
|
||||
|
||||
En **desarrollo y producción se levanta un único servidor**: `apps/api` (Nest) arranca, monta sus controladores bajo el prefijo `/api`, y luego delega cualquier otra ruta al request handler programático de Next.js (`apps/web`). No hay dos puertos ni dos procesos — Nest "sirve" a Next.
|
||||
|
||||
Ver `apps/api/src/main.ts` para el detalle de la integración.
|
||||
|
||||
## Empezar
|
||||
|
||||
Instala las dependencias una sola vez desde la raíz (los workspaces se resuelven juntos):
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
### Desarrollo
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
# or
|
||||
pnpm dev
|
||||
# or
|
||||
bun dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
Levanta Nest en modo watch (`nest start --watch`), que a su vez prepara Next en modo desarrollo. Todo queda disponible en [http://localhost:3000](http://localhost:3000) (API bajo `/api/*`).
|
||||
|
||||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||
### Build y producción
|
||||
|
||||
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
|
||||
```bash
|
||||
npm run build # compila apps/web (next build) y luego apps/api (nest build)
|
||||
npm run start # node apps/api/dist/main.js
|
||||
```
|
||||
|
||||
## Learn More
|
||||
### Solo frontend (aislado)
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
Si necesitas iterar en `apps/web` sin levantar Nest:
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
```bash
|
||||
npm run dev --workspace=@pdv/web
|
||||
```
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
|
||||
Ten en cuenta que en ese modo las rutas `/api/*` de Nest no estarán disponibles.
|
||||
|
||||
## Deploy on Vercel
|
||||
## Notas de configuración
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
|
||||
- El custom server de Next (`next({ dev, dir })`) no es compatible con `output: "standalone"` — no lo actives en `apps/web/next.config.ts` mientras Nest siga sirviendo el build.
|
||||
- `apps/api` usa TypeScript 6.x (distinto de `apps/web`, que usa TypeScript 5.x) porque `@nestjs/cli`/`nest build` aún no soportan la API programática del compilador de TypeScript 7.
|
||||
@@ -0,0 +1,32 @@
|
||||
import eslint from '@eslint/js';
|
||||
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
|
||||
import globals from 'globals';
|
||||
import tseslint from 'typescript-eslint';
|
||||
|
||||
export default tseslint.config(
|
||||
{
|
||||
ignores: ['dist/**'],
|
||||
},
|
||||
eslint.configs.recommended,
|
||||
...tseslint.configs.recommendedTypeChecked,
|
||||
eslintPluginPrettierRecommended,
|
||||
{
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.node,
|
||||
},
|
||||
sourceType: 'commonjs',
|
||||
parserOptions: {
|
||||
projectService: true,
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
rules: {
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-floating-promises': 'warn',
|
||||
'@typescript-eslint/no-unsafe-argument': 'warn',
|
||||
},
|
||||
},
|
||||
);
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/nest-cli",
|
||||
"collection": "@nestjs/schematics",
|
||||
"sourceRoot": "src",
|
||||
"compilerOptions": {
|
||||
"deleteOutDir": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "@pdv/api",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "nest build",
|
||||
"start": "nest start",
|
||||
"start:dev": "nest start --watch",
|
||||
"start:prod": "node dist/main.js",
|
||||
"lint": "eslint \"{src,test}/**/*.ts\" --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nestjs/common": "^12.0.3",
|
||||
"@nestjs/core": "^12.0.3",
|
||||
"@nestjs/platform-express": "^12.0.3",
|
||||
"next": "^16.3.5",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"rxjs": "^7.8.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.39.5",
|
||||
"@nestjs/cli": "^12.0.3",
|
||||
"@nestjs/schematics": "^12.0.0",
|
||||
"@nestjs/testing": "^12.0.3",
|
||||
"@types/express": "^5.0.6",
|
||||
"@types/node": "^20.19.43",
|
||||
"eslint": "^9.39.5",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-prettier": "^5.5.6",
|
||||
"globals": "^14.0.0",
|
||||
"prettier": "^3.9.8",
|
||||
"typescript": "^6.0.3",
|
||||
"typescript-eslint": "^8.70.0"
|
||||
}
|
||||
}
|
||||
@@ -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("health")
|
||||
getHealth() {
|
||||
return this.appService.getHealth();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
import { AppController } from "./app.controller";
|
||||
import { AppService } from "./app.service";
|
||||
|
||||
@Module({
|
||||
imports: [],
|
||||
controllers: [AppController],
|
||||
providers: [AppService],
|
||||
})
|
||||
export class AppModule {}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
|
||||
@Injectable()
|
||||
export class AppService {
|
||||
getHealth() {
|
||||
return { status: "ok" };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import "reflect-metadata";
|
||||
import path from "node:path";
|
||||
import { NestFactory } from "@nestjs/core";
|
||||
import type { NestExpressApplication } from "@nestjs/platform-express";
|
||||
import next from "next";
|
||||
import { AppModule } from "./app.module";
|
||||
|
||||
async function bootstrap() {
|
||||
const dev = process.env.NODE_ENV !== "production";
|
||||
const port = Number(process.env.PORT ?? 3000);
|
||||
|
||||
// apps/api siempre corre compilado desde dist/, por lo que apps/web
|
||||
// queda dos niveles arriba tanto en desarrollo como en producción.
|
||||
const nextApp = next({ dev, dir: path.join(__dirname, "../../web") });
|
||||
const handleNextRequest = nextApp.getRequestHandler();
|
||||
await nextApp.prepare();
|
||||
|
||||
const app = await NestFactory.create<NestExpressApplication>(AppModule);
|
||||
app.setGlobalPrefix("api");
|
||||
|
||||
// Se inicializa antes de registrar el catch-all para que las rutas de
|
||||
// Nest queden montadas primero y Next solo reciba lo que Nest no maneja.
|
||||
await app.init();
|
||||
app
|
||||
.getHttpAdapter()
|
||||
.getInstance()
|
||||
.all(/.*/, (req, res) => handleNextRequest(req, res));
|
||||
|
||||
await app.listen(port);
|
||||
console.log(
|
||||
`> Servidor listo en http://localhost:${port} (${dev ? "development" : "production"})`,
|
||||
);
|
||||
}
|
||||
|
||||
void bootstrap();
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"declaration": true,
|
||||
"removeComments": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"target": "ES2023",
|
||||
"sourceMap": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"incremental": true,
|
||||
"skipLibCheck": true,
|
||||
"strictNullChecks": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noImplicitAny": true,
|
||||
"strictBindCallApply": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
}
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "@pdv/web",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "eslint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@heroui/react": "^3.2.6",
|
||||
"framer-motion": "^13.4.0",
|
||||
"next": "16.3.5",
|
||||
"react": "19.2.8",
|
||||
"react-dom": "19.2.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"eslint": "^9",
|
||||
"eslint-config-next": "16.3.5",
|
||||
"tailwindcss": "^4",
|
||||
"typescript": "^5"
|
||||
}
|
||||
}
|
||||
File renamed without changes.
@@ -1,4 +1,4 @@
|
||||
@import "tailwindcss";
|
||||
@import "@heroui/react/styles";
|
||||
|
||||
:root {
|
||||
--background: #ffffff;
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Generated
+3508
-297
File diff suppressed because it is too large.
Load diff
+8
-20
@@ -1,26 +1,14 @@
|
||||
{
|
||||
"name": "pdv-frontend",
|
||||
"name": "pdv",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"workspaces": [
|
||||
"apps/*"
|
||||
],
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "eslint"
|
||||
},
|
||||
"dependencies": {
|
||||
"next": "16.3.5",
|
||||
"react": "19.2.8",
|
||||
"react-dom": "19.2.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"eslint": "^9",
|
||||
"eslint-config-next": "16.3.5",
|
||||
"tailwindcss": "^4",
|
||||
"typescript": "^5"
|
||||
"dev": "npm run start:dev --workspace=@pdv/api",
|
||||
"build": "npm run build --workspace=@pdv/web && npm run build --workspace=@pdv/api",
|
||||
"start": "npm run start:prod --workspace=@pdv/api",
|
||||
"lint": "npm run lint --workspace=@pdv/web && npm run lint --workspace=@pdv/api"
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user