수강이 제한됩니다.
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 해결됨[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
setImmediate / clearImmediate 질문
안녕하세요. 질문이 하나 있습니다. setImmediate가 즉시 실행되는 것처럼 보여도 백그라운드 - 테스크 큐 - 호출 스택 과정을 거치기 때문에 그 전에 clearImmediate를 하면 취소된다는 것은 이해했습니다. 궁금한 건 아래인데요, const immediate2 = setImmediate(() => { console.log('x'); }); clearImmediate(immediate2); 여기에서 clearImmediate(immediate2);가 실행되어 'x'가 출력되지 않는, 일련의 시간 순서가 잘 이해되지 않습니다. immediate2의 백그라운드 - 테스크 큐 - 호출 스택 과정보다 clearImmediate가 앞선 과정인지 어떻게 알 수 있는 건가요? 저는 찍어보기 전까지는 모를 것 같있는데 강사님은 미리 예측을 하신 것으로 보여 어떻게 그걸 알 수 있는지 궁금합니다. 감사합니다.
- 해결됨[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
퍼그에 대한 궁금한점!
선생님 안녕하세요! 이번에 노드로 이직을 하고 싶어서 구매를 하고 또 열심히 공부를 하고 있는데요 뷰 템플릿의 퍼그도 혹시 실무에서 많이 사용되는지 궁금합니다 물론 react나 vue 이런 개발자들이 있으면 좋겠지만 없는 환경이라면 그래도 퍼그를 사용하는곳이 있을까요?
- 미해결[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
PM2 + socket io 질문
제로초님 강의듣고 나름 열심히 만든앱 채팅입이 어제부터 동접자 7~8000명을 찍고 서버가 터진뒤 오늘 기세보니 만명을 찍을것같습니다. 우선 정말 감사드립니다. 그러나 현재 서버가 불안정해서 열심히 알아본결과 PM2 + socket.io를 사용하는게 지금 제가 빠르게 할 수있는방법으론 젤 괜찮을 것같아 해봤습니다. 공식문서 보고 따라했습니다. npm remove -g pm2 npm install -g @socket.io/pm2 를 실행하고 socket.js ... const SocketIo = require("socket.io"); const { createAdapter } = require("@socket.io/cluster-adapter");const { setupWorker } = require("@socket.io/sticky"); module.exports = (server) => { const io = SockeIo(server, {path: '/socket.io}) io.adapter(createAdapter()); setupWorker(io); .... } 이렇게 코드를 작성한뒤 package.json에 "start": "cross-env NODE_ENV=production pm2 start app.js -i 0" 이렇게하고 npm start를 하면 실행이 되지않습니다. 점검한다고 2시간가량 공백시간을 두었지만 결국 해결못하고 다시 하나의 cpu로 pm2 를 실행시켰습니다. 기세보니 오늘 동접자 만명 가까이 될듯한데, 정말 무섭습니다. aws 서버는 t3.xl 쓰고있고 프론트(앱), 백앤드(서버+db) 이렇게 2티어 구조 쓰고있습니다. pm2 clustering 만 어떻게 해결하면 문제없이 받아낼 수 있을것같은데, 어떻게 하면 해결할 수 있을까요.. ㅠㅠ 사적인 질문 너무 죄송하지만 너무 급해서 질문드립니다.. 답변해주시면 정말 감사하겠습니다.
- 미해결[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
시퀄라이즈 중복 메소드 처리 방식
안녕하세요시퀄라이즈 쓰다보니까 중복되는 메소드들이 많은데 아래와 같이 where 조건 처리 같은 메소드 중복 처리를 어떤 식으로 하시나요? 예를 들어 async function deleteInterestByGroupSeq(stockInterestGroupSeq) { await StockInterest.destroy({ where: { STOCK_INTEREST_GROUP_SEQ: stockInterestGroupSeq }, }); } async function deleteInterestBySeq(stockInterestSeq) { await StockInterest.destroy({ where: { STOCK_INTEREST_SEQ: stockInterestSeq }, }); } 이렇게 비슷한 2개가 있는 경우 파라미터로 분기치는 방식으로 통합해서 사용하는게 유용한가요? 아니면 저런식으로 나눠서 사용하는게 나은 방식인가요?
- 미해결[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
multer s3 질문
multer 말고 formidable도 있는데 multer를 쓰는 특별한 이유가 multer를 이용해 s3 하는게 편해서 그런건가요? 그리고 formidable을 이용해서도 s3 하는게 가능한가요?
- 미해결[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
app.use(passport.session()) 질문 입니다.
이게 로그인을 하든 안하든 항상 실행되는데,만일 로그인 세션쿠키가 없을 경우 어찌 동작하는지 궁금합니다.세션 쿠키가 없으니까 express.session에서 아무 반응 없이 next되고 req.session 객체가 없으니까, passport.session역시 아무반응없이 next되는 건가요?아니면 deSerializer에서 done(err)하고 다음 미들웨어로 넘어가는 건가요?
- 미해결[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
팔로우 관련 질문입니다
제가 회원가입한 계정 입니다. id 2번 계정으로 로그인을 한 뒤, id 1번 계정을 팔로우 하면 follow 테이블에 followingId : 2 ,followerId : 1 저장되는 것이 아닌 followingId : 1, followerId : 1이 저장됩니다. 혹시나 req.user.id 값이나 req.params.id 값이 잘못된건 아닌지, console로 찍어보았습니다. console로 찍어본 결과 현재 로그인 유저를 나타내는 req,user.id 2가 맞게 나오고, 팔로우 요청한 유저의 아이디를 나타내는 req.params.id 값도 1로 맞게 나오는 것을 확인했습니다. 혹시 Models의 User의 db관계 부분이 잘못 되었나 확인을 해보았는데, 제로초님께서 알려주신 코드랑 비교해서 다른 부분이 없는 것 같습니다. 혹시 제가 친 코드에 문제가 있는 것일까요... 참고로, id 1번계정을 로그인해서 2번계정을 팔로우하는 경우 팔로우가 이상없이 잘 됩니다.. 답변 부탁드리겠습니다!
- 미해결[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
비밀번호 DB저장 관련 질문입니다
안녕하세요, 제로초 님 제가 회원가입을 한 후, 로그인을 할때 계속 아래와 같은 오류가 발생합니다.. 제가 생각하기에는 아래 부분에서 제대로 된 데이터 값을 받지 못해서 오류가 발생하지 않을까? 라고 생각을 했습니다. 혹시나 하는 마음에 mysql workbench로 DataBase의 User테이블을 살펴봤습니다. User테이블의 row를 보니 password가 null값이 들어간 것을 확인했습니다. 원래는 해시화된 passoword 값이 들어가야 한다고 생각하는데, 혹시 제가 코드를 잘못 친 부분이나 저 에러 발생의 원인을 정확히 파악하고 있는지 답변 부탁드립니다!
- 미해결[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
시퀄라이즈 sql 로그 가독성
orm을 날리면 로그에 쿼리가 나타나는데가독성이 너무 최악입니다.쿼리도 확인해가며 공부하고 싶은데요, 어찌 해결방법이 없을까요?
- 미해결[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
쿠키 동작 방식 문의
// 코드 중간 name이라는 쿠키가 있는 경우 코드에 제가 임의로 콘솔로그를 찍어봤는데 동작방식이 이해가 안가서 질문드립니다! http.createServer(async (req, res) => { const cookies = parseCookies(req.headers.cookie); // { mycookie: 'test' } // 주소가 /login으로 시작하는 경우 if (req.url.startsWith('/login')) { const { query } = url.parse(req.url); const { name } = qs.parse(query); const expires = new Date(); // 쿠키 유효 시간을 현재시간 + 5분으로 설정 expires.setMinutes(expires.getMinutes() + 5); res.writeHead(302, { // 302 : redirect Location: '/', 'Set-Cookie': `name=${encodeURIComponent(name)}; Expires=${expires.toGMTString()}; HttpOnly; Path=/`, }); res.end(); // name이라는 쿠키가 있는 경우 } else if (cookies.name) { console.log("cookies :",cookies) // 질문! : 첫 로그인이나 새로고침하는 즉, 한번 실행하는 동작시 두번씩 콘솔로그가 찍히는 이유가 뭔가요? res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' }); res.end(`${cookies.name}님 안녕하세요`); } else { try { const data = await fs.readFile('./cookie2.html'); res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); res.end(data); } catch (err) { res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' }); res.end(err.message); } } }) .listen(8084, () => { console.log('8084번 포트에서 서버 대기 중입니다!'); }); // 출력 8084번 포트에서 서버 대기 중입니다! cookies : { name: '홍길동' } cookies : { name: '홍길동' }
- 미해결[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
시퀄라이즈 문법 질문 있습니다.
// 생성 const user = await User.findOne({ 옵션 }); // 참조 관계에 부합한 유저를 선택하고 const comment = await Comment.create({ 옵션 }); // 데이터를 comment테이블에 넣고 await user.addComment(comment); // user와 참조된 외래키를 comment에 add 한다. 이렇게 이해하면 될까요?
- 미해결[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
ClientClosedError: The client is closed 오류
프론트와 백엔드 서버 따로 사용중입니다. npm i redis connect-redis 하고 강의대로 따라했는데 프론트에서 새로고침해주면 req.user가 있으면 유저정보를 없으면 res.json(null)을 해주는 코드가 있는데, 잘되다가 레디스를 설치한후로 ClientClosedError: The client is closed 에러가 나옵니다. 윈도우라 안되는건가요??
- 미해결[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
급작스러운 시퀄라이즈 질문 있습니다.
const posts = await Post.findAll({ include: { model: User, attributes: ['id', 'nick'], }, order: [['createdAt', 'DESC']], }); 1. 저거를 sql문으로 표현하면 select * from posts left join users on posts.id = users.id order by posts.createdAt desc; 맞나요?2. 시퀄라이즈문법 include안에 attributes를 선언한 이유가, sql은 외래키 연결되어있으면 그냥 join만 하면 알아서 키가 연결되서 조인되는데,시퀄라이즈는 직접 외래키연결된 키를 명시해야되서 쓰는건가요? 3. 2번 질문이 정답이라면 nick은 왜 쓴건가요?로그를 보니 그냥 전체 필드들을 다 가져오던데..
- 미해결[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
cb 가 무슨 약자인가요?
6강에서는 done이라고 인수이름을 쓰셧는데,여기서는 cb라고 명명 지어서요. destination(req, file, cb)
- 미해결[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
_json 의미
_json 키는 어디다 쓰는것인가요? 데이터 중복도 있고요.
- 미해결[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
시퀄라이즈 질문드립니다..
안녕하세요 강사님 ch7에 해당하는 Sequelize 실습에서 hasMany - belongsTo 를 테이블 이름에 칼럼 만바꿔서 테스트를해보니 다음과 같은 에러가 계속 발생하였습니다. 강의에서 users ----------- comments 관계처럼 kakao ------------ talk 로 같은 관계로 테스트하였습니다. 1. kakao.js const Sequelize = require('sequelize'); module.exports = class Kakao extends Sequelize.Model { static init(sequelize) { return super.init({ name : { type : Sequelize.STRING(20), allowNull : false, unique : true, }, job : { type : Sequelize.STRING(30), allowNull : true, }, sex : { type : Sequelize.STRING(2), // 남자,여자 allowNull : false, }, created_at : { type : Sequelize.DATE, allowNull : false, defaultValue : Sequelize.NOW, }, },{ sequelize, timestamps : false, // 강제로 createAt,updatedAt 칼럼 만들지 말아줘 undescored : false, // 스네이크 케이스로 사용할꺼야 modelName : 'Kakao', tableName : 'kakao', paranoid: false, charset: 'utf8', collate: 'utf8_general_ci', }); } static associate(db) { db.Kakao.hasMany(db.Talk, { foreignKey: 'nicName', sourceKey: 'id' }); } }; 2.talk.js const Sequelize = require('sequelize'); module.exports = class Talk extends Sequelize.Model { static init(sequelize) { return super.init({ talk : { type : Sequelize.STRING(100), allowNull : true, }, created_at : { type : Sequelize.DATE, allowNull : false, defaultValue : Sequelize.NOW, }, },{ sequelize, timestamps: false, modelName : 'Talk', tableName : 'talk', paranoid: false, charset: 'utf8mb4', collate: 'utf8mb4_general_ci', }); } static associate(db) { db.Talk.belongsTo(db.Kakao, { foreignKey: 'nicName', targetKey: 'id' }); } }; 3. index.js const Sequelize = require('sequelize'); const Kakao = require('./kakao'); const Talk = require('./talk'); // NODE_ENV가 정의되지않으면 개발모드! const env = process.env.NODE_ENV || 'development'; const config = require('../config/config')[env]; const db = {}; // DB ID PWD Config_File const sequelize = new Sequelize(config.database, config.username, config.password, config); db.sequelize = sequelize; db.Kakao = Kakao; db.Talk = Talk; console.log(sequelize); Kakao.init(sequelize); Talk.init(sequelize); Kakao.associate(sequelize); Talk.associate(sequelize); module.exports = db; 어떤차이가 있는걸까요..? 저는 db.Kakao.hasMany(db.Talk, { foreignKey: 'nicName', sourceKey: 'id' }); db.Talk.belongsTo(db.Kakao, { foreignKey: 'nicName', targetKey: 'id' }); 이두줄을 kakao는 테이블의 고유한 pk가 talk테이블에 많다.(칼럼으로서는 id) 즉 talk 테이블에서 nicName이라는 칼럼을 foreignkey으로 사용하겠다.(kakao의 id를 가지고서) 라고 생각했습니다.
- 미해결[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
Jest 테스트 코드 작성 관련 질문
타입스크립트로 Jest 테스트 코드를 작성해보고 있는데요. 유닛테스트를 작성하여, 직접 작성한 미들웨어에서 next() 함수가 호출되는지 확인해보려고 합니다. class-validator로 req.body가 number인지 검증하는 미들웨어이고, 테스트코드는 다음과 같습니다. import 'reflect-metadata'; import { CreateCheckInDto } from '../check-in/create-check-in.dto'; import { validation } from './validation.middleware'; describe('validation middleware', () => { it('simple test', () => { const req: any = { body: { cardId: '22' }, }; const res: any = {}; const next = jest.fn(); validation(CreateCheckInDto)(req, res, next); expect(next).toBeCalledTimes(1); }); }); 미들웨어 코드는 다음과 같습니다(class validator로 req.body를 검증하는 코드입니다). import { plainToInstance } from 'class-transformer'; import { validate, ValidationError } from 'class-validator'; import { NextFunction, Request, Response, RequestHandler } from 'express'; export function validation(type: any): RequestHandler { return (req: Request, res: Response, next: NextFunction) => { validate(plainToInstance(type, req.body)).then( (errors: ValidationError[]) => { if (errors.length > 0) { res.redirect('redirect'); } else { console.log('nextttttttttttttttt'); next(); } }, ); }; } console.log('nextttttttttttttttt'); 이게 콘솔로그로 찍히는 걸보면 next()부분까지 도달하는 것 같은데 테스트 결과는 기대와 다르게 아래와 같습니다. console.log nextttttttttttttttt at src/middleware/validation.middleware.ts:12:19 FAIL src/middleware/validation.middleware.spec.ts validation middleware ✕ simple test (22 ms) ● validation middleware › simple test expect(jest.fn()).toBeCalledTimes(expected) Expected number of calls: 1 Received number of calls: 0 13 | validation(CreateCheckInDto)(req, res, next); 14 | > 15 | expect(next).toBeCalledTimes(1); | ^ 16 | }); 17 | }); 18 | at Object.<anonymous> (src/middleware/validation.middleware.spec.ts:15:18) 왜 received number of calls가 0이 나오는지 실마리를 찾지 못하여 질문으로 올립니다. 원인해결을 위한 키워드라도 실마리를 주신다면 정말 감사하겠습니다!
- 미해결[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
authenticate의 첫번째 인수인 local 의미
'local' 문자열이 의미하는 바가,passport/index.js에서local 변수를 의미하는건가요?passport.use()나 passport.serializeUser()나 결국 오버라이딩 처리 이고, 메소드끼리 서로가 서로를 부르는 것일 뿐인건 알겠는데이게 어떻게 등록을 하고 연결되어서 각 모듈을 찾아가는지 설명이 필요합니다.
- 미해결[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
bcrypt 질문입니다
저번 해시 암호화 강의를 열심히 듣고 단방향 암호화와 쏠트 원리를 공부하고 실제로 crypto pbkdf2로 로그인 로직을 구현해보기도 하였습니다.근데 bcrypt문법보니 현타오네요. 이렇게 간단하고 sha알고리즘 gpu문제도 해결하고요.대신에 음청 느리다고 배웠습니다.거두절미하고, pbkdf2를 쓸때는 db테이블에 쏠트라는 필드를 만들어 거기에 각 개인마다 할당되는 랜덤 쏠트값을 저장하여,로그인 비교할때 꺼내서 비교하였습니다.하지만 bcrypt는 그냥 compare()하고 끝이던데, 이놈 쏠트 원리는 어떻게 되는지 간단히 설명해 주실수 있나요?
- 해결됨[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
router to router 데이터 전송 질문
안녕하세요. router를 통해 json 형태로 시간 데이터를 가져 왔는데, 다른 router에서 이 데이터를 사용하려면 어떻게 해야 할까요 ???