묻고 답해요
140만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
경매 시간을 자유롭게 조정할 수 있게 만들때, 경매 시작 시간도 유저가 조정할 수 있게 만들어야 할까요
숙제로 경매 시간을 자유롭게 조정할 수 있게 구현하라고 하셨는데, 처음 사용자가 상품을 생성할 때 경매 종료 시간과 경매 시작 시간을 입력받을 수 있게 만들라는 말씀이실까요? 경매 시작 시간도 조정할 수 있게 하면 sse로 서버 시간을 매초마다 클라이언트에게 보내는 의미가 없을 것 같아 여쭤봅니다!
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
강의에 사용한 js파일들 받을수 있을까요?
현재 개정3판 노드 강의를 듣고 있는데 강의에서 사용하시는 js파일들 받을수있을까요?아니면 이미 올려두신곳이 있다면 알려주세요!
-
미해결[웹 개발 풀스택 코스] Node.js 프로젝트 투입 일주일 전 - 기초에서 실무까지
mysql연동건너뛰기
제가 mysql연동이 잘 되지 않아 건너뛰고 보려고 하는데express라우터부터 그냥 봐도 크게 영향받지않고 진행할 수 있을까요??
-
미해결Slack 클론 코딩[실시간 채팅 with React]
로그인 페이지 무한 새로고침 현상
안녕하세요 어느 날 갑자기 로그인 페이지가 무한 새로고침 현상이 발생 됩니다 백엔드 쪽에는 로그 /api/users 304로 새로고침마다 계속 응답해줘서 문제가 없는 것 같고 프런트쪽 문제인 것 같은데 개발자 도구를 볼 수 없을정도로 계속 새로고침 되서 당황스럽네요 ㅠㅠ 그래서 제로초님 깃허브 front/App/index.tsx, front/LogIn/index.tsx 코드 전체 붙여넣어도 동일 현상이 발생됩니다... 무언가 라이브러리 충돌이 있나 싶은데 package.json 코드입니다{ "name": "artus-sleact-front", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "dev": "webpack serve --env development", "build": "cross-env NODE_ENV=production webpack", "test": "echo \"Error: no test specified\" && exit 1" }, "author": "ethan", "license": "MIT", "dependencies": { "@emotion/babel-plugin": "^11.11.0", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", "@loadable/component": "^5.16.4", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.15", "autosize": "^6.0.1", "axios": "^1.7.2", "cross-env": "^7.0.3", "css-loader": "^7.1.2", "dayjs": "^1.11.12", "gravatar": "^1.8.2", "react": "^17.0.2", "react-custom-scrollbars": "^4.2.1", "react-dom": "^17.0.2", "react-mentions": "^4.4.10", "react-refresh": "^0.14.2", "react-router": "^5.3.4", "react-router-dom": "^5.3.4", "react-toastify": "^7.0.4", "regexify-string": "^1.0.19", "socket.io-client": "^4.7.5", "style-loader": "^4.0.0", "swr": "^2.2.5", "ts-node": "^10.9.2", "typescript": "^5.5.3", "webpack-bundle-analyzer": "^4.10.2", "webpack-cli": "^5.1.4" }, "devDependencies": { "@babel/core": "^7.24.7", "@babel/preset-env": "^7.24.7", "@babel/preset-react": "^7.24.7", "@babel/preset-typescript": "^7.24.7", "@types/autosize": "^4.0.3", "@types/loadable__component": "^5.13.9", "@types/node": "^20.14.9", "@types/react-custom-scrollbars": "^4.0.13", "@types/react-mentions": "^4.1.13", "@types/react-router": "^5.1.20", "@types/react-router-dom": "^5.3.3", "@types/socket.io-client": "^1.4.35", "@types/webpack": "^5.28.5", "@types/webpack-bundle-analyzer": "^4.7.0", "@types/webpack-dev-server": "^4.7.2", "@types/gravatar": "^1.8.6", "@types/react": "^17.0.80", "@types/react-dom": "^17.0.25", "babel-loader": "^9.1.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", "eslint-config-react-app": "^7.0.1", "eslint-plugin-flowtype": "^8.0.3", "eslint-plugin-import": "^2.29.1", "eslint-plugin-jsx-a11y": "^6.9.0", "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-react": "^7.34.4", "fork-ts-checker-webpack-plugin": "^9.0.2", "prettier": "^3.3.2", "webpack": "^5.92.1", "webpack-dev-server": "^4.15.2" } }
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
vscode 자동완성 확장 질문
안녕하세요! 강의 잘 듣고 있는 수강생 입니다!제로초님 강의를 보면 다음과 같은 코드가 있을 때const express = require('express'); const path = require('path'); const app = express(); app.get('/',(req,res)=>{ res.sendFile(path.join(__dirname,'index.html')); console.log('GET / '); })app에 대한 HTTP METHOD 를 지원하는 라우팅 함수 및 req, res 에서 사용할 수 있는 함수들에 대해 자동 완성 되는 부분을 봤는데요. (예:`app.get()`,`res.writeHead()` 등) vscode의 각종 extensions 들을 설치해보고 vscode 자체의 옵션도 찾아봤지만 도저히 제로초님 처럼 자동 완성 되지가 않네요ㅜㅜ제가 이클립스를 사용하다가 이번에 노드 공부해보려고 다른 IDE를 사용해서 그런지 자동완성이 되지 않는 부분이 매우 불편한데 혹시 강사님 개발 환경 공유 가능할까요?강의와는 상관이 없는 질문인 점 죄송합니다
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
chat.adapter.rooms의 시간순 정렬 여부
// socket.js socket.on('disconnect', async () => { console.log('chat 네임스페이스 접속 해제'); // /room/방아이디 => URL에서 가져오기. const { referer } = socket.request.headers; const roomId = new URL(referer).pathname.split('/').at('-1'); const currentRoom = chat.adapter.rooms.get(roomId); // 현재 방의 인원이 0이면(방장도 나감) 자동삭제. const userCount = currentRoom?.size || 0; if (userCount === 0) { await removeRoom(roomId); room.emit('removeRoom', roomId); // room 네임스페이스에 이 방이 제거됬다고 알려서 실시간으로 제거할 것임. console.log('방 제거 요청 성공'); } else { // 시스템 메시지 DB 저장 const systemChat = `${socket.request.session.color}님이 퇴장하셨습니다.`; await createChat(roomId, 'system', systemChat); const memberList = [...currentRoom].map((socketId) => { return { color: chat.sockets.get(socketId).request.session.color, socketId, }; }); // 누군가 나가면 그 방의 모든 사람에게 시스템 메시지 및 정보 전달. socket.to(roomId).emit('exit', { user: 'system', chat: systemChat, memberList, }); } }); }); }; 여기서 chat.adapter.rooms.get(roomId) = currentRoom이 Set객체인데 여기 쌓이는 socketId들은 접속한 순서대로 쌓이나요? 그러니까, 시간순 정렬이 되어있는 건가요? 방장 위임하는 기능 구현 중인데 '방에 방장 정보를 저장한다' 이걸 어떻게 해야할 지 모르겠습니다🤔
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
강의 9장 - 3 실습중에 오류를 못찾겠어요.
Error: Route.post() requires a callback function but got a [object Undefined] at Route.<computed> [as post] (C:\nodeSns\sns\node_modules\express\lib\router\route.js:216:15) at proto.<computed> [as post] (C:\nodeSns\sns\node_modules\express\lib\router\index.js:521:19) at Object.<anonymous> (C:\nodeSns\sns\routes\auth.js:13:8) at Module._compile (node:internal/modules/cjs/loader:1358:14) at Module._extensions..js (node:internal/modules/cjs/loader:1416:10) at Module.load (node:internal/modules/cjs/loader:1208:32) at Module._load (node:internal/modules/cjs/loader:1024:12) at Module.require (node:internal/modules/cjs/loader:1233:19) at require (node:internal/modules/helpers:179:18) at Object.<anonymous> (C:\nodeSns\sns\app.js:12:20) npm start 하면 자꾸 이 오류가 뜨는데 원인을 못 찾겠습니다.
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
authorization 헤더와 jwt 저장 위치
내 게시물 모두 불러오기나 해시태그로 검색하기 등 api 서버에 요청 보낼 때 authorization 헤더에 jwt를 넣어서 보내도록 코딩 했는데 이를 확인할 수 있는 방법이 궁금합니다. 그리고 아래 화면에서 connect.sid로 전달된 세션 키와 연결된 세션에 해당 사용자의 jwt 값이 req.session.jwt로 들어있는 건가요?
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
에러 처리 방법
9강에서는 대체로 console.error(err); next(err);이런 식으로 에러를 처리했고 10강에서는 res.json으로 에러 코드, 메세지를 반환하고 있는데 이 둘의 차이가 뭔가요?에러 처리 미들웨어를 사용할 때와 json을 반환할 때를 어떻게 정할 수 있는지(?) 기준이 궁금합니다.
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
NodeBird 서비스의 화면 렌더링 방식에 대해 질문 드립니다!
궁금한 점이 있습니다.9강에서 만든 NodeBird 서비스의 구조는 프론트엔드가 따로 있는 것이 아니라 서버 측에서 nunjucks와 html 파일들을 사용하여 화면을 구성하는 것이 맞나요?1번이 맞고, 백엔드에서 직접 html을 생성하여 클라이언트에게 제공하는 구조라면 제가 공부한대로는 SSR 방식인 것 같은데 맞나요?프론트엔드를 따로 만들어서 서버와 연동하려면 app.js의 아래 코드와 views 폴더를 삭제하고 프론트 쪽에서 서버 측에서 만든 주소들을 호출하면 되나요?// app.js의 일부 app.set("view engine", "html"); nunjucks.configure("views", { express: app, watch: true, });
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
테스트 환경 질문드립니다!
안녕하세요!아파트에 거주하고 있습니다.저희 세대로 들어오는 네트워크 신호를 담당하는 기기가 신발장 안쪽에 있고 굉장히 여러 케이블이 꽂혀 있습니다. 가끔씩 집 컴퓨터 인터넷이 안 될 때가 있는데 그 기기를 리부팅하곤 합니다. 각 방의 벽에 랜선 케이블을 꽂을 수 있게 되어 있습니다.PC는 전부 벽에 있는 랜선 포트에 랜선 케이블을 꽂습니다.거실에 있는 공유기는 거실 벽면에 있는 랜선 포트와 연결되어 있습니다.제가 파악한 걸 말씀드려보겠습니다.1. 세대로 들어오는 네트워크 신호는 신발장 안쪽에 있는 설비를 통해 집의 각 벽면의 랜선 포트로 전달한다공유기가 내보내는 신호 역시 벽면의 랜선 포트로 전달된 신호를 받아서 동작한다. PC가 랜선으로 수신하는 네트워크 신호와 공유기가 뿌리는 무선 신호는 같은 망에 속한다 이 상황에서, PC는 랜선으로 연결하고 노트북은 공유기에 연결하는 것이, 강의에서 말씀하신 하나의 공유기에 랜선으로 두 PC를 연결하는 것과 동일한 것처럼 느껴집니다. 맞을까요?이게 맞다면 영상에서 말씀하신 클라이언트 PC의 케이블 연결 해제가 노트북의 와이파이 연결 해제와 동일한 것 아닌가 하는 생각이 들었습니다.
-
미해결Slack 클론 코딩[실시간 채팅 with React]
Module not found: Error: Can't resolve './App' 에러
안녕하세요. 강의에서 배운 내용 응용해서 사이드 프로젝트 만드는 중인데 Module not found: Error: Can't resolve './App' in '/Users/taetae/Documents/github/PicKIvy/frontend/src' 오류가 고쳐지지 않아 질문드립니다. (시도해본 해결방법들)[ Tsconfig.json ]“jsx": "react-jsx" 으로 설정됐는지 확인 -> 그래도 안됌“paths" 확인> "baseUrl": "src", (원래 “.”이었음) "paths": { "@pages/*": ["pages/*"], "@components/*": ["components/*"], "@layouts/*": ["layouts/*"], "@hooks/*": ["hooks/*"], "@utils/*": ["utils/*"], "@typings/*": ["typings/*"] }, 패스에 전부 src/붙여서 "@pages/*": [“src/pages/*"], 해봤는데 안됨 “moduleResolution": "node", 확인 -> 그래도 안됌 [ Web pack.config]Extensions: [ “.tsx”] 으로 설정됐는지 확인 -> 그래도 안됌package-lock.json지우고 다시 Npm install안됌 ( rm -rf node_modules package-lock.json ->npm cache clean --force -> npm install ) [ index.tsx ]import App from './App'; 을 import App from './App.tsx; ‘ 로 해봤는데 안됌[ 폴더구조, tsconfig ][ 웹팩 ]import path from 'path'; import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin'; import webpack, { Configuration as WebpackConfiguration } from 'webpack'; import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'; // import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; import { Configuration as WebpackDevServerConfiguration } from 'webpack-dev-server'; interface Configuration extends WebpackConfiguration { devServer?: WebpackDevServerConfiguration; } const isDevelopment = process.env.NODE_ENV !== 'production'; const config: Configuration = { name: 'PicKivy', mode: isDevelopment ? 'development' : 'production', devtool: isDevelopment ? 'inline-source-map' : 'hidden-source-map', resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'], alias: { '@hooks': path.resolve(__dirname, 'src/hooks'), '@components': path.resolve(__dirname, 'src/components'), '@layouts': path.resolve(__dirname, 'src/layouts'), '@pages': path.resolve(__dirname, 'src/pages'), '@utils': path.resolve(__dirname, 'src/utils'), '@typings': path.resolve(__dirname, 'src/typings'), }, }, entry: { app: './src/index.tsx', }, target: ['web', 'es6'], module: { rules: [ { test: /\.tsx?$/, loader: 'babel-loader', exclude: /node_modules/, options: { presets: [ [ '@babel/preset-env', { targets: { browsers: ['> 0.25%', 'not dead'] }, // 최신 브라우저 타겟팅 debug: isDevelopment, }, ], '@babel/preset-react', '@babel/preset-typescript', ], plugins: [ '@babel/plugin-transform-runtime', isDevelopment && 'react-refresh/babel', '@emotion/babel-plugin', ].filter(Boolean), }, }, { test: /\.css$/, use: ['style-loader', 'css-loader'], }, { test: /\.(png|jpg|gif|svg)$/, type: 'asset/resource', }, ], }, plugins: [ new ForkTsCheckerWebpackPlugin({ async: false, }), new webpack.EnvironmentPlugin({ NODE_ENV: isDevelopment ? 'development' : 'production' }), ], output: { path: path.join(__dirname, 'dist'), filename: '[name].[contenthash].js', publicPath: '/dist/', }, devServer: { historyApiFallback: true, port: 3000, devMiddleware: { publicPath: '/dist/' }, static: { directory: path.resolve(__dirname, 'public') }, proxy: { '/api/': { target: 'http://localhost:3000', changeOrigin: true, ws: true, }, }, }, }; if (isDevelopment && config.plugins) { config.plugins.push(new webpack.HotModuleReplacementPlugin()); config.plugins.push( new ReactRefreshWebpackPlugin({ overlay: { useURLPolyfill: true, }, }), ); // config.plugins.push(new BundleAnalyzerPlugin({ analyzerMode: 'server', openAnalyzer: false })); } if (!isDevelopment && config.plugins) { config.plugins.push(new webpack.LoaderOptionsPlugin({ minimize: true })); // config.plugins.push(new BundleAnalyzerPlugin({ analyzerMode: 'static' })); } export default config; 코드 복붙하니까 코드가 이상하게 나와서 캡쳐본도 올립니다. (test: /\.tsx? 아래부분부터) [ App, index ]@page 하니까 에러떠서 ./로 했습니다. 이것때문에 계속 못하고 있는데 저에게 답을 알려주시면 감사하겠습니다...ㅠ.ㅜ
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
팔로잉과 팔로워 관계
deserializeUser에서 req.user에 넣을 팔로잉이랑 팔로워 찾으실 때, as는 모델 관계의 as를 따라간다고 하셨는데 왜 위 코드에서 Follwers가 //팔로잉이고 Followings가 //팔로워라고 하신 건지 모르겠습니다ㅜ 예를 들어, 저의 팔로잉을 찾으려면 제 아이디를 팔로워 아이디에서 찾아야 하니까 기준 아이디가 followerId가 되는 Followings가 맞는거 아닌가요?
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
connect.sid를 쿠키에 넣는 시점과 express-session
req.login를 통해 req.session에 { 랜덤값: 유저아이디}를 저장하는 건 알겟는데, connect.sid=랜덤값을 쿠키에 넣는 시점은 언제인가요?그리고 서버가 connect.sid를 세션 쿠키로 전송할 때, express-session 은 자동으로 이 값을 secret으로 서명하여 전송하나요?
-
미해결[웹 개발 풀스택 코스] Node.js 프로젝트 투입 일주일 전 - 기초에서 실무까지
sql버전안맞음
저의 경우 client sql 버전이 안맞다고 나옵니다 workbench는 8.0Mysql 9.0 Configurator로 설치했습니다 stackoveflow에서 찾아보니ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';Where root as your user localhost as your URL and password as your passwordThen run this query to refresh privileges:flush privileges;Try connecting using node after you do so.If that doesn't work, try it without @'localhost' part. 이런 답변이 있는데 어떻게 적용하는지 알 수 있을까요?
-
미해결Slack 클론 코딩[실시간 채팅 with React]
배포 방법
제가 백엔드 강의는 수강한 적이 없어서요, 대신 노드js 교과서 책을 구매해서 가지고 있는데..우선 프론트는 네트리파이로 배포 완료했습니다https://admirable-donut-f22cc6.netlify.app/백엔드 배포는 선생님 책 노드js 교과서 722쪽 AWS 배포하기 부터 보면서 하면 별 문제없지 진행할 수 있을까요? 추가적으로 백엔드쪽 코드 수정이 필요할지..배포할 레포 구조는 아래 처럼 루트 폴더 하위에 백엔드, 프론트 폴더 각각 있습니다
-
해결됨[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
express.static의 요청 처리
app.use('/', express.static(path.join(__dirname, 'public')));다른 코드들에서는 이런 식으로 경로를 지정하면 경로와 똑같은 요청만 처리를 하거나 모든 요청에 대해 처리하고 싶으면 그냥 경로를 생략하였는데 express.static은 왜 localhost:3000/ 에 대한 요청만 받아들이는 것이 아니라, 모든 요청에 대해 해당 파일이 있는지 확인하게 되는지 궁금합니다. 예시)localhost:3000/about -> public 폴더 안에 about 파일이 있는지 찾음 localhost:3000/hello.css-> public 폴더 안에 hello.css 파일이 있는지 찾음express.static은 특별한 미들웨어 인가요?
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
`app.use`의 용도에 대해 질문 드립니다!
궁금한 점이 있습니다. 지금까지는 다음과 같이 app.use 안에 요청 처리를 위한 미들웨어를 작성했는데, app.use((req, res, next) => { console.log("모든 요청에 실행하고 싶어요"); next(); });다음과 같이 app.use에 다운받은 미들웨어를 장착하는 건 "이 파일에서 특정 미들웨어를 사용하겠다"는 의도로 사용하는 건가요?? 아니면 둘 다 같은 동작을 하는건데 제가 둘을 다르다고 생각하는 걸까요?app.use(morgan("dev")); app.use(cookieParser()); app.use(express.json()); app.use(express.urlencoded({ extended: true }));추가로, 위 미들웨어들로 인해 req이나 res 객체에서 편하게 .cookie나 .body를 사용할 수 있게 되는데 그럼 미들웨어 내에서 미들웨어를 사용하는 건가요 🤔🤔?
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
어떤 객체가 이벤트를 발생시키는지
여러 챕터에서 객체의 on 메서드를 사용하는 코드가 자주 보여서 개념에 대해 알아보았습니다.const fs = require("fs"); console.log("before:", process.memoryUsage().rss); // 메모리 체크 // 스트림 방식으로 파일 읽고 보내기 const readStream = fs.createReadStream("./big.txt"); const writeStream = fs.createWriteStream("./big3.txt"); readStream.pipe(writeStream); readStream.on("end", () => { console.log("stream: ", process.memoryUsage().rss); });그런데 이렇게 이벤트가 발생하는 객체의 종류를 모두 외우고 있어야 하나요? 아니면 이 객체가 이벤트를 발생시키는지 예상(?), 판단할 수 있는 기준이 있나요?
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
ThreadAcceptLoop 의 우아한(?) 종료에 대해 질문드립니다.
안녕하십니까, TCP/IP, IOCP 개념을 배우는데 강사님의 강의가 큰 도움이 되었습니다. 다름이 아니라, IOCP 코드를 C++ Class 로 작성중에 소멸자에서 리소스들을 해제 하려고 작성 중에 있는데 ThreadAcceptLoop 스레드를 우아하게 종료하기 위한 방법이 있는지 궁금하여 질문을 하나 드려봅니다. g_hSocket : Server Listen SocketDWORD WINAPI ThreadAcceptLoop(LPVOID pParam)while ((hClient = ::accept(g_hSocket, &ClientAddr, &nAddrSize)) != INVALID_SOCKET){ // Do Something...} 보시다싶이 ThreadAcceptLoop 함수 내부에서 ::accept() 를 처리해주고 있고 accept 에 들어가는 순간 Blocking 이 되어버립니다. 저는 스레드의 완전 종료를 위해 accept 함수를 빠져나가기 위한 방법을 찾아보니 g_hSocket = NULL 또는 INVALID_SOCKET 을 할당 해주는것 말고는 Accept 함수를 빠져나갈 수 있는 방법이 없는 것 처럼 보이더라구요. 하지만 이런식으로 NULL 할당하여 accept 를 빠져나가도록 하고 WSAGetLastError 를 호출해보면 "WSACancelBlockingCall를 호출하여 차단 작업이 중단되었습니다." 라는 에러를 확인할 수 있었습니다. g_hSocket = NULL 호출 후 해당 오류를 무시해도 지나가도 되는 코드인지, 아니면 accept Blocking 상태를 빠져나가기 위한 "우아한 방법" 이 있는지 궁금합니다. 현재 작성한 코드 순서는 아래와 같습니다. 스레드는 _beginthreadex 로 호출해서 핸들을 가지고 있습니다. ::shutdown(g_hSocket, SD_BOTH); if (g_hSocket!= INVALID_SOCKET) { ::closesocket(g_hSocket); g_hSocket= INVALID_SOCKET; // 이 시점에 accept blocking 이 풀린다! } // Accept Thread 종료를 대기하자 WaitForSingleObject(IOCPAcceptThreadHandle._threadHandle, INFINITE); CloseHandle(IOCPAcceptThreadHandle._threadHandle); 감사합니다.