44,000원
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
jwt, local authguard에 관해서
안녕하세요. 저번에 NESTJS를 이용해서 MSA환경에서 gRPC프로토콜을 이용하는 시스템을 만들고있다고 질문했었는데, jwt와 local을 이용한 인증전략을 구성하는데 문제가 생겨서 ,질문 남깁니다.서버는 gateway를 통해 클라이언트와 통신하고, 각 서버끼리는 gRPC를 통해 통신하고, 클라이언트와는 HTTP통신을 합니다.jwt, local 가드는 게이트웨이의 각 모듈(user의 컨트롤러 등)에서 사용되기때문에 게이트웨이 모듈의 프로바이더에 JwtStrategy, LocalStrategy를 작성해놨는데Nest can't resolve dependencies of the LocalStrategy, Nest can't resolve dependencies of the JwtStrategy의 오류가 납니다.인증 전략을 가져오는데 문제가 생긴거같은데, 게이트웨이가 아닌 서버의 모듈에 추가해야하는건가요?일반적인 방법이 궁금합니다. 검색을 해보면 다 auth모듈을 만들어서 사용하는데, 저는 그냥 strategy파일만 만들어서 inject하려고 합니다...
- 해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
HttpExceptionFilter에 단순 HttpException 예외처리도 필요하지 않나요?
HttpExceptionFilter에서 에러처리시exception.getStatus() 로 err 변수값을 넣을떄HttpException 의 경우 string 타입BadRequestException, UnauthorizedException 와 같이 미리 정의된 경우 { message: any; statusCode: number } 타입class-validator의 경우 { error: string; statusCode: 400; message: string[] } 타입의 3가지 형태가 되는데이번강의에서 string 타입 자체를 제거하셧는데 HttpException 를 사용하게되면 에러 메시지가 제대로 안 날라 가게 됩니다. class-validator를 도입하면서 HttpException 케이스를 제거 하신거 같은데 해당 예외도 포함은 되어있어야 하지 않나요?class-validator 가 완전히 HttpException 를 대체하게 한다면 HttpException를 사용못하게 막을 방법이 있을까요?import { ExceptionFilter, Catch, ArgumentsHost, HttpException, } from '@nestjs/common'; import { Response } from 'express'; @Catch(HttpException) export class HttpExceptionFilter implements ExceptionFilter { catch(exception: HttpException, host: ArgumentsHost) { const ctx = host.switchToHttp(); const response = ctx.getResponse<Response>(); const status = exception.getStatus(); const err = exception.getResponse() as | string | { message: any; statusCode: number } | { error: string; statusCode: 400; message: string[] }; //class-validator if (typeof err !== 'string' && err.statusCode === 400) { return response.status(status).json({ success: false, code: err.statusCode, data: err.message, }); } //HttpException if (typeof err == 'string') { return response.status(status).json({ success: false, code: status, data: err, }); } //BadRequestException, UnauthorizedException return response.status(status).json({ success: false, code: status, data: err.message, }); } }
- 해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
module.ts에서도 process.env 대신 configService를 사용할수 있나요?
이전강의떄 app.module.ts에서 외부에서 Env값을 불러오는 방법도 있다는것을 알려주셧는데 const getEnv = async () => { //외부에 저장된 Env값 // const response = await axios.get("/loadEnv") // return response.data; return { DB_PASSWORD: '~~~', }; }; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, load: [getEnv] }), UsersModule, ChannelsModule, DmsModule, WorkspaceModule, TypeOrmModule.forRoot({ type: 'mariadb', host: process.env.DB_HOST, port: parseInt(process.env.DB_PORT, 10), username: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_DATABASE, entities: ['entities/*.js'], // autoLoadEntities: true, // TypeOrmModule.forFeature 내의 entities를 읽어서 자동 연결 synchronize: true, logging: true, keepConnectionAlive: true, //핫리로딩시 연결종료 방지 charset: 'utf8mb4', }), ], controllers: [AppController], providers: [AppService, ConfigService], }) export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer.apply(LoggerMiddleware).forRoutes('*'); } } @Injectable() export class AppService { constructor(private configService: ConfigService) {} getHello() { return this.configService.get('PORT'); } }제가 이해한 바에 따르면 app.module.ts 에서 ConfigModule을 임포트하여 app.service.ts에서 ConfigService를 사용하여 외부 env값을 사용할수 있는데 app.module.ts 에서도 자체적으로 외부env를 이용하여 db설정값을 지정할수 있는지 궁금합니다.
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
백엔드부터 해도 되나요???
git에서 소스 안받고 강의보면서 직접 타이핑해가면서학습하려고 합니다.백엔드 강의부터 진행해도 문제 없을까요?
- 해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
터미널 명령어에서 특수문자를 일반 택스트로 인식시키는 방법이 있나요?
mysql의 비밀번호를 자동생성을 통해 생성해서 ~+kmisB1[@l1&FH 로 설정해 놓았는데 아래 명령어에서 특수문자로 인해 인식이 정상적으로 못하는것 같습니다. & 앞에 \를 추가하여 ~+kmisB1[@l1\&FH 로 시도해도 인식이 되지 않았습니다.명령어 : npx typeorm-model-generator -h localhost -d sleact -u root -x ~+kmisB1[@l1&FH -e mysql 에러 : 필수 인자를 받지 못했습니다: e'FH'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는 배치 파일이 아닙니다.
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
msa환경에서 서버끼리는 gRPC로 통신을 하는 형태로 만들어보려고 합니다.
안녕하세요. 이번에 신입으로 입사한 주니어 개발자입니다.입사한 회사에서 msa환경에서 서버끼리는 gRPC통신를 이용해서 통신을 하고 클라이언트와는 게이트웨이를 통해서 통신하는 프로젝트를 nest.js를 이용해서 만드는 온보딩 미션을 주셨는데요.공식문서를 계속 읽어보고 하는데 아직 gRPC와 msa환경을 처음 접해서 그런가 만들어보려니 감이 잡힐거같으면서도 어렵네요.먼저 nest.js의 기본적인 http로 통신하는 시스템을 만들어보고 그 이후에 리팩토링해서 요구조건을 만족하게 만드는게 나을까요?
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
슬랙 참여주소가 작동하지않습니다.
확인 부탁드립니다~
- 해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
궁금한 사항
강의보던중 front 도 시작하시는걸봤는데 프론트없어도 클론코딩할 수 있는건가요??
- 해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
제네레이트 마이그레이션 오류
yujinseung@yujinseung-ui-MacBookPro slack_nest % npm run db:generate-migration > study_nest@0.0.1 db:generate-migration > npm run typeorm migration:generate -- ./src/migrations -d ./dataSource.ts > study_nest@0.0.1 typeorm > typeorm migration:generate ./src/migrations -d ./dataSource.ts Error during migration generation: Error: Unable to open file: "/Users/yujinseung/Desktop/slack_nest/dataSource.ts". Cannot use import statement outside a module at CommandUtils.loadDataSource (/Users/yujinseung/Desktop/slack_nest/node_modules/typeorm/commands/CommandUtils.js:22:19) at async Object.handler (/Users/yujinseung/Desktop/slack_nest/node_modules/typeorm/commands/MigrationGenerateCommand.js:68:26)yujinseung@yujinseung-ui-MacBookPro slack_nest % npm run db:migrate > study_nest@0.0.1 db:migrate > npm run typeorm migration:run -- -d ./dataSource.ts > study_nest@0.0.1 typeorm > typeorm migration:run -d ./dataSource.ts Error during migration run: Error: Unable to open file: "/Users/yujinseung/Desktop/slack_nest/dataSource.ts". Cannot use import statement outside a module at CommandUtils.loadDataSource (/Users/yujinseung/Desktop/slack_nest/node_modules/typeorm/commands/CommandUtils.js:22:19) at async Object.handler (/Users/yujinseung/Desktop/slack_nest/node_modules/typeorm/commands/MigrationRunCommand.js:41:26)위 두 오류가 뜹니다..! 뭐가문제일까요..ㅠㅠ
- 해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
이 강의에 관해서 출판 된 책이나 문서 같은 건 없는 건가요?
완강후 실무에 써먹어 보려는 데 종종 다시 찾아봐야 할 때가 있을꺼 같아서요.없어도 크게 불편 할 것은 없습니다.
- 해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
MySQL이 연결되지않습니다
Error: connect ECONNREFUSED ::1:3306at TCPConnectWrap.afterConnect [as oncomplete] 라는 오류가 뜹니다상황설명 : create~~ 가 뜨면서 sleact DB가 만들어졌다가 3306이 이미 써져있어서 그렇다라는 글을 보고 sudo killall mysqld 를 썼다가 DB가 다 날라가고 나서 다시 MySQL을 깔고 db:create, start:dev를 하였더니 똑같이 저런 오류가 뜹니다..import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { LoggerMiddleware } from './middlewares/logger.middlware'; import { UsersModule } from './users/users.module'; import { WorkspacesModule } from './workspaces/workspaces.module'; import { ChannelsModule } from './channels/channels.module'; import { DmsModule } from './dms/dms.module'; import { UsersService } from './users/users.service'; import { TypeOrmModule } from '@nestjs/typeorm'; import { Users } from './entities/Users'; import { WorkspaceMembers } from './entities/WorkspaceMembers'; import { ChannelChats } from './entities/ChannelChats'; import { ChannelMembers } from './entities/ChannelMembers'; import { Channels } from './entities/Channels'; import { DMs } from './entities/DMs'; import { Mentions } from './entities/Mentions'; import { Workspaces } from './entities/Workspaces'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true }), UsersModule, WorkspacesModule, ChannelsModule, DmsModule, TypeOrmModule.forRoot({ type: 'mysql', host: 'localhost', port: 3306, username: process.env.DB_USERNAME, password: process.env.DB_PASSWORD, database: process.env.DB_DATABASE, entities: [ ChannelChats, ChannelMembers, Channels, DMs, Mentions, Users, WorkspaceMembers, Workspaces, ], synchronize: true, logging: true, keepConnectionAlive: true, charset: 'utf8mb4_general_ci', }), TypeOrmModule.forFeature([Users]), ], controllers: [AppController], providers: [AppService, ConfigService, UsersService], }) export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer.apply(LoggerMiddleware).forRoutes('*'); } } DB_USERNAME=root DB_PASSWORD=저의 비밀번호입력했습니다 DB_DATABASE=sleact PORT=3000
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
설명하시는 소스 git 주소 어디에 있을까요
설명하시는 소스 git 주소 어디에 있을까요커뮤니티 검색해 봤는데 안나오네요...
- 해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
typeorm 설치하고 설정하는 강의가 어떤건지 알려주세요!
안녕하세요. 제로초님의 강의를 다 들었었는데요.typeorm 설치하고 설정하는 강의가 있었던 것 같은데 어떤 강의인지 알려주실 수 있나요??
- 해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
서비스 파일의 쿼리 빌더 관련 질문입니다.
안녕하세요.강의를 듣던 도중 갑자기 궁금한게 생겨서 글을 남기게 되었습니다.service 파일에서는 어떤 서비스의 로직만을 구현하는 것으로 들었었습니다.다만 해당 강의에서는 service 파일에 로직 + 쿼리빌더로 쿼리까지 사용하는 부분에서 repository.ts 파일을 따로 만들어서 분리시킬 필요는 없는건가요??
- 해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
로그인 테스트 중 발생했던 express-session 관련 질문입니다!
안녕하세요.로그인 코드 작성 완료 후 테스트로 포스맨을 호출했을 때 2가지 오류가 발생했었습니다.Error: Login sessions require session support. Did you forget to use express-session middleware?secret option required for sessions 1번은 express-session 아래에 passport를 작성하라는 것 같아서 강사님의 깃 보고 아래 코드를 추가했었고 app.use(cookieParser()); app.use( session({ resave: false, saveUninitialized: false, secret: process.env.COOKIE_SECRET, cookie: { httpOnly: true, }, }), ); 2번은 검색해보니 secret 설정을 하면 된다고 해서 .env 파일에 COOKIE_SECRET에 대한 값을 넣어줘서 1,2번 전부 해결했었습니다. 다만, 강의에는 이미 들어가있던 부분이였던 아래 코드와 passport.session을 같이 사용하는 이유가 궁금합니다! passport.session만 사용하니 express session의 미들웨어를 사용하라는 것 같았고, express session을 찾아보니 express session만 사용해서 로그인을 구현하기도 하는 것 같았습니다.app.use(cookieParser()); app.use( session({ resave: false, saveUninitialized: false, secret: process.env.COOKIE_SECRET, cookie: { httpOnly: true, }, }), ); 그리고 secret는 express session의 암호로만 알고 있어도 되는걸까요? .env 파일에 제가 임으로 설정한 암호를 예를들어 COOKIE_SECRET=12314 이런식으로 작성해놓는게 맞는건가요?? ++ 그리고 수업 별개로 추가 질문 사항이 있습니다!현재 강의에서 사용되는거는 typeORM 0.3 버전인가요? 실무에서는 0.2 버전보다 0.3으로 많이 사용되는건가요??
- 해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
Entity, Dto 관련해서 궁금증이 있습니다! (오류 사항은 아니지만.. 갑자기 궁금해져서 글을 남기게 되었습니다.)
안녕하세요. 해당 강의를 보다가 궁금증이 생겨서 글을 남기게 되었습니다.Entity는 디비 테이블의 컬럼들을 작성(실제 컬럼 및 디비에 없는 컬럼들까지)하고 Dto는 요청에서 받는 타입들을 작성하고 해당 타입들을 Controller 전에 검증해주는 클래스라고 알고 있었습니다. 궁금한건 아래 2가지 인 것 같습니다.Entity는 디비 테이블의 컬럼을 / Dto는 타입 검증을 위한 데코레이터들을 작성하는 클래스로 분리되는 개념으로 생각해왔었는데 잘 못 생각하고 있었던건가요??만약, Dto 클래스에 있는 컬럼들을 생략하면 nickName?: string; 처럼 선택적 옵션들과 @IsString()등 타입 검증을 해주는 데코레이터들을 전부 Entity에 작성해주는 건가요?? 저는 Entity는 건들이지 않고 Dto에서 선택적 옵션과 타입 검증들의 데코레이터를 사용하고 있었어서 궁금해졌습니다..!
- 미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
npm run seed 실행해도 테이블의 기본값이 생성되지 않는 이유가 뭔가요..??
안녕하세요.npm run seed를 실행하면 아래와 같은 내용만 나오고 기본 값 생성이 되지 않습니다. 에러 메세지가 Unknown arguments: d, seed 이것뿐인 것 같은데.. 알 수 없는 인수.. d, seed가 무슨 말인지 모르겠습니다.a-nest@0.0.1 seed > ts-node ./node_modules/typeorm-extension/bin/cli.cjs seed -d ./dataSource.ts Usage: typeorm-extension <command> [options] Commands: typeorm-extension db:create Create database. typeorm-extension db:drop Drop database. typeorm-extension seed:run Populate the database with an initial data set or generated data by a factory. typeorm-extension seed:create Create a seeder file. Options: -h, --help Show help [boolean] -v, --version Show version number [boolean] Unknown arguments: d, seed dataSource.tsimport { DataSource } from 'typeorm'; import dotenv from 'dotenv'; import { ChannelChats } from './src/entities/ChannelChats'; import { ChannelMembers } from './src/entities/ChannelMembers'; import { Channels } from './src/entities/Channels'; import { DMs } from './src/entities/DMs'; import { Mentions } from './src/entities/Mentions'; import { Users } from './src/entities/Users'; import { WorkspaceMembers } from './src/entities/WorkspaceMembers'; import { Workspaces } from './src/entities/Workspaces'; dotenv.config(); const dataSource = new DataSource({ type: 'mysql', host: 'localhost', port: 3306, username: process.env.DB_USERNAME, password: process.env.DB_PASSWORD, database: process.env.DB_DATABASE, entities: [ ChannelChats, ChannelMembers, Channels, DMs, Mentions, Users, WorkspaceMembers, Workspaces, ], migrations: [__dirname + '/src/migrations/*.ts'], charset: 'utf8mb4_general_ci', synchronize: false, logging: true, }); export default dataSource; create-initial-data.tsimport { Seeder, SeederFactoryManager } from 'typeorm-extension'; import { DataSource } from 'typeorm'; import { Workspaces } from '../../entities/Workspaces'; import { Channels } from '../../entities/Channels'; export default class UserSeeder implements Seeder { public async run( dataSource: DataSource, factoryManager: SeederFactoryManager, ): Promise<any> { const workspacesRepository = dataSource.getRepository(Workspaces); await workspacesRepository.insert([ { id: 1, name: 'Sleact', url: 'sleact', }, ]); const channelsRepository = dataSource.getRepository(Channels); await channelsRepository.insert([ { id: 1, name: '일반', WorkspaceId: 1, private: false, }, ]); } } .envSECRET=제로초강의 PORT=3095 DB_USERNAME=root DB_PASSWORD=password DB_DATABASE=sleact package.json{ "name": "a-nest", "version": "0.0.1", "description": "", "author": "", "private": true, "license": "UNLICENSED", "scripts": { "build": "nest build", "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", "start": "nest start", "start:dev-backup": "nest start --watch", "start:dev": "nest build --webpack --webpackPath webpack-hmr.config.js --watch", "start:debug": "nest start --debug --watch", "start:prod": "node dist/main", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "test": "jest", "test:watch": "jest --watch", "test:cov": "jest --coverage", "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", "typeorm": "node --require ts-node/register ./node_modules/typeorm/cli.js", "db:create": "ts-node ./node_modules/typeorm-extension/bin/cli.cjs db:create -d ./dataSource.ts", "db:drop": "ts-node ./node_modules/typeorm-extension/bin/cli.cjs db:drop -d ./dataSource.ts", "seed": "ts-node ./node_modules/typeorm-extension/bin/cli.cjs seed -d ./dataSource.ts", "schema:drop": "ts-node ./node_modules/typeorm/cli.js schema:drop", "schema:sync": "ts-node ./node_modules/typeorm/cli.js schema:sync", "db:migrate": "npm run typeorm migration:run -- -d ./dataSource.ts", "db:migrate:revert": "npm run typeorm migration:revert -- -d ./dataSource.ts", "db:create-migration": "npm run typeorm migration:create -- ./src/migrations/", "db:generate-migration": "npm run typeorm migration:generate -- ./src/migrations -d ./dataSource.ts" }, "dependencies": { "@nestjs/common": "^10.0.0", "@nestjs/config": "^3.0.0", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.0.0", "@nestjs/swagger": "^7.1.2", "@nestjs/typeorm": "^10.0.0", "bcrypt": "^5.1.0", "class-validator": "^0.14.0", "mysql2": "^3.6.0", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1", "swagger-ui-express": "^5.0.0", "typeorm-extension": "^3.0.1" }, "devDependencies": { "@nestjs/cli": "^10.0.0", "@nestjs/schematics": "^10.0.0", "@nestjs/testing": "^10.0.0", "@types/express": "^4.17.17", "@types/jest": "^29.5.2", "@types/node": "^20.3.1", "@types/supertest": "^2.0.12", "@typescript-eslint/eslint-plugin": "^5.59.11", "@typescript-eslint/parser": "^5.59.11", "eslint": "^8.42.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-prettier": "^4.2.1", "jest": "^29.5.0", "prettier": "^2.8.8", "run-script-webpack-plugin": "^0.2.0", "source-map-support": "^0.5.21", "supertest": "^6.3.3", "ts-jest": "^29.1.0", "ts-loader": "^9.4.3", "ts-node": "^10.9.1", "tsconfig-paths": "^4.2.0", "typeorm-model-generator": "^0.4.6", "typescript": "^5.1.3", "webpack": "^5.88.2", "webpack-node-externals": "^3.0.0" }, "jest": { "moduleFileExtensions": [ "js", "json", "ts" ], "rootDir": "src", "testRegex": ".*\\.spec\\.ts$", "transform": { "^.+\\.(t|j)s$": "ts-jest" }, "collectCoverageFrom": [ "**/*.(t|j)s" ], "coverageDirectory": "../coverage", "testEnvironment": "node" } } 혹시 경로를 못찾는 건가 싶어서 데이터소스 파일쪽에 seeds의 경로를 넣어주려고 했으나 seeds에 오류가 발생해서 다시 원복 시켰었습니다.(src>database>seeds>create-initial-data.ts 파일은 제로초님 깃에서 복붙했습니다.)강의에서 듣기로는 dataSource > create-initial-data 로 넘어가면서 기본 값이 생성된다고 들었는데요 어디 부분을 확인해봐야 할까요??
- 해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
DB 생성시 Error: Cannot find module './index.js 가 계속 뜨는데 뭐가 문제인가요??
강의를 듣던 도중 npm run db:create를 실행시켰는데 아래 에러 메세지가 나옵니다.> a-nest@0.0.1 db:create > ts-node ./node_modules/typeorm-extension/dist/cli/index.js db:create -d ./dataSource.ts node:internal/modules/cjs/loader:942 throw err; ^ Error: Cannot find module './index.js' Require stack: - C:\nestStudy\slack-clone-app\a-nest\node_modules\typeorm-extension\dist\cli\imaginaryUncacheableRequireResolveScript at Module._resolveFilename (node:internal/modules/cjs/loader:939:15) at Function.resolve (node:internal/modules/cjs/helpers:108:19) at requireResolveNonCached (C:\nestStudy\slack-clone-app\a-nest\node_modules\ts-node\dist\bin.js:549:16) at getProjectSearchDir (C:\nestStudy\slack-clone-app\a-nest\node_modules\ts-node\dist\bin.js:519:40) at phase3 (C:\nestStudy\slack-clone-app\a-nest\node_modules\ts-node\dist\bin.js:267:27) at bootstrap (C:\nestStudy\slack-clone-app\a-nest\node_modules\ts-node\dist\bin.js:47:30) at main (C:\nestStudy\slack-clone-app\a-nest\node_modules\ts-node\dist\bin.js:33:12) at Object.<anonymous> (C:\nestStudy\slack-clone-app\a-nest\node_modules\ts-node\dist\bin.js:579:5) at Module._compile (node:internal/modules/cjs/loader:1105:14) at Module._extensions..js (node:internal/modules/cjs/loader:1159:10) { code: 'MODULE_NOT_FOUND', requireStack: [ 'C:\\nestStudy\\slack-clone-app\\a-nest\\node_modules\\typeorm-extension\\dist\\cli\\imaginaryUncacheableRequireResolveScript' ] } Node.js v18.0.0 package.json{ "name": "a-nest", "version": "0.0.1", "description": "", "author": "", "private": true, "license": "UNLICENSED", "scripts": { "build": "nest build", "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", "start": "nest start", "start:dev-backup": "nest start --watch", "start:dev": "nest build --webpack --webpackPath webpack-hmr.config.js --watch", "start:debug": "nest start --debug --watch", "start:prod": "node dist/main", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "test": "jest", "test:watch": "jest --watch", "test:cov": "jest --coverage", "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", "typeorm": "node --require ts-node/register ./node_modules/typeorm/cli.js", "db:create": "ts-node ./node_modules/typeorm-extension/dist/cli/index.js db:create -d ./dataSource.ts", "db:drop": "ts-node ./node_modules/typeorm-extension/dist/cli/index.js db:drop -d ./dataSource.ts", "seed": "ts-node ./node_modules/typeorm-extension/dist/cli/index.js seed -d ./dataSource.ts", "schema:drop": "ts-node ./node_modules/typeorm/cli.js schema:drop", "schema:sync": "ts-node ./node_modules/typeorm/cli.js schema:sync", "db:migrate": "npm run typeorm migration:run -- -d ./dataSource.ts", "db:migrate:revert": "npm run typeorm migration:revert -- -d ./dataSource.ts", "db:create-migration": "npm run typeorm migration:create -- ./src/migrations/", "db:generate-migration": "npm run typeorm migration:generate -- ./src/migrations -d ./dataSource.ts" }, "dependencies": { "@nestjs/common": "^10.0.0", "@nestjs/config": "^3.0.0", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.0.0", "@nestjs/swagger": "^7.1.2", "@nestjs/typeorm": "^10.0.0", "mysql2": "^3.6.0", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1", "swagger-ui-express": "^5.0.0", "typeorm-extension": "^3.0.1" }, "devDependencies": { "@nestjs/cli": "^10.0.0", "@nestjs/schematics": "^10.0.0", "@nestjs/testing": "^10.0.0", "@types/express": "^4.17.17", "@types/jest": "^29.5.2", "@types/node": "^20.3.1", "@types/supertest": "^2.0.12", "@typescript-eslint/eslint-plugin": "^5.59.11", "@typescript-eslint/parser": "^5.59.11", "eslint": "^8.42.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-prettier": "^4.2.1", "jest": "^29.5.0", "prettier": "^2.8.8", "run-script-webpack-plugin": "^0.2.0", "source-map-support": "^0.5.21", "supertest": "^6.3.3", "ts-jest": "^29.1.0", "ts-loader": "^9.4.3", "ts-node": "^10.9.1", "tsconfig-paths": "^4.2.0", "typeorm-model-generator": "^0.4.6", "typescript": "^5.1.3", "webpack": "^5.88.2", "webpack-node-externals": "^3.0.0" }, "jest": { "moduleFileExtensions": [ "js", "json", "ts" ], "rootDir": "src", "testRegex": ".*\\.spec\\.ts$", "transform": { "^.+\\.(t|j)s$": "ts-jest" }, "collectCoverageFrom": [ "**/*.(t|j)s" ], "coverageDirectory": "../coverage", "testEnvironment": "node" } } index.js 를 못 찾는다는 에러같은데 어디 부분이 잘 못된건지 모르겠습니다ㅠ이 에러 때문에 테이블들도 생성되지 않았습니다.
- 해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
spec.ts 파일이 자동으로 생기는데 왜 생기는 건가요??
안녕하세요. 강의를 따라하면서 파일을 생성할때 항상 아래 이미지처럼 spec.ts 파일이 자동으로 생성되는 이유가 뭔가요?? 강사님은 안 생기시는 것 같은데 저는 1개 파일당 1개씩 전부 생겨버려서 너무 많은 양의 파일들이 만들어집니다..
- 해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
One-to-Many Self Referencing 문제
안녕하세요 One-to-Many 관계 정의 시에 해결이 잘 안되서 문의 드립니다. Typeorm 사이트에서 정보를 참조도 해보고 구글링도 해봐서 시도해봤지만 명확하게 원하던 결과가 나오지 않아서 문의드립니다.@Entity("Parts", { schema: "workplaces" }) export class Parts { @PrimaryColumn('varchar', { name: "partsNumber", unique: true, nullable: false }) partsNumber: string; @Column('varchar', { name: 'partsName', length: 500, nullable: true }) name: string; @Column('bool', { name: 'isMain', nullable: false, default: false }) isMain: boolean; @CreateDateColumn() createDate: Date; @UpdateDateColumn() updateDate: Date; @DeleteDateColumn() deleteDate: Date | null; // 여기부터가 문의 드리는 One to Many 관계설정 코드입니다. @ManyToOne(() => Parts, (parts) => parts.alternative, { onDelete: "SET NULL", onUpdate: "CASCADE" }) parts: Parts; @OneToMany(() => Parts, (alternative) => alternative.parts) @JoinColumn([{ name: "alternative", referencedColumnName: "partsNumber" }]) alternative: Parts[]; }보시면 아시겠지만, Parts 테이블에 alternative란 항목의 다수의 Parts 타입을 데이터로 받도록 구성한 것인데요, 부품의 경우, 대체 부품이 여럿이 존재해서 isMain 항목을 통해서 부품이 main부품일 경우에만 데이터를 저장하고 호출해주며, main 부품이 아닌경우, 연결된 main parts 의 정보를 호출해주도록 하기 위해서 입니다. 실제로 이렇게 구성할 경우, 아래와 같은 데이터를 저장할시{ "partsNumber": "341241", "name": "341241 Dryer Drum Belt", "isMain": true, "alternative": [ { "partsNumber": "14210003" }, { "partsNumber": "20065315" }, ] }이상없이 저장이 완료됩니다.Main part(parent) 검색시에 보통 사용하던 One to Many에서처럼 alternative에 제대로 2개의 배열객체가 출력이 됩니다만, 문제는 alternative 데이터를 검색하여 main이 되는 part를 출력하지 못하는 점인데요. Self Referencing 으로 One to Many관계를 설정시에 children측에서 parent 쪽의 정보를 호출하려면 어떻게 설정해야 하나요?항상 답변을 주셔서 감사합니다!