inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

묻고 답해요

173만명의 커뮤니티!! 함께 토론해봐요.

npm i typescript 설치 중 에러

미해결

Slack 클론 코딩[실시간 채팅 with React]

디펜던시 호환문제같은데 다른 게시글에서 본 https://www.npmjs.com/package/react-custom-scrollbars-2 여기 들어가서 npm i react-custom-scrollbars-2 설치하려고 해봐도 같은 에러가 뜹니다ㅠ

  • react
  • 웹팩
  • typescript
  • socket.io
  • babel
  • 클론코딩
바옹 댓글 1 좋아요 0 조회수 319

에러없이 png안뜨시는 분들

미해결

프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..)

webpack-cli3, webpack4, loader는 @2로 install 하시면 강의와 같이 잘 나옵니다. 저는 참고로 모든 웹팩, 로더 버전 최신으로 깔았다가 png가 안나왔네요.

  • node.js
  • 웹팩
  • babel
  • eslint
hjsim 댓글 1 좋아요 1 조회수 297

npx sequelize db:create시 에러 발생

미해결

Slack 클론 코딩[실시간 채팅 with React]

안녕하세요. 맥북프로 m1 사용중이며 홈브루를 통해 mysql을 설치했습니다. 터미널 명령어로 mysql container도 정상적으로 만들어졌고 mysql -u root -p 명령어도 정상적으로 잘 작동하고있습니다. 패스워드도 정상적으로 입력되구요. 그런데 back폴더 터미널에서 npm i 를 해준 뒤 npx sequelize db:create 명령어 입력 시 (base) jinjaehwan-ui-MacBookPro:back jinjaehwan$ npx sequelize db:create Sequelize CLI [Node: 18.18.2, CLI: 6.6.0, ORM: 6.28.0] Loaded configuration file "config/config.js". Using environment "development". ERROR: Access denied for user 'root'@'localhost' (using password: YES) 이런 에러가 발생합니다 ㅠㅠ

  • react
  • 웹팩
  • typescript
  • socket.io
  • babel
  • 클론코딩
jjh099 댓글 3 좋아요 0 조회수 525

(공유) react-toastify 사용 시 오류 및 해결법 (2024년 2월 기준)

해결됨

Slack 클론 코딩[실시간 채팅 with React]

ERROR in ./node_modules/react-toastify/dist/react-toastify.esm.mjs 2:4352-4353 export 'useSyncExternalStore' (imported as 'r') was not found in 'react' (possible exports: Children, Component, Fragment, Profiler, PureComponent, StrictMode, Suspense, __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, cloneElement, createContext, createElement, createFactory, createRef, forwardRef, isValidElement, lazy, memo, useCallback, useContext, useDebugValue, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState, version) @ ./layouts/Workspace/index.tsx 30:0-39 110:6-17 @ ./layouts/App/index.tsx 15:9-37 @ ./client.tsx 9:0-31 12:95-98 2024년 2월 기준, react-toastify를 최신 버전으로 install하게 되면 위와 같은 오류가 발생합니다. alecture의 package.json에 있는 react-toastify 버전으로 특정하여 설치하면 정상 실행 됩니다. npm i react-toastify@7.0.3

  • react
  • 웹팩
  • typescript
  • socket.io
  • babel
  • 클론코딩
Teirdarn Linkaden 댓글 1 좋아요 3 조회수 888

socket.io 관련 질문

미해결

Slack 클론 코딩[실시간 채팅 with React]

frontend에서 socket.io -client를 이용하여 websocket을 구현하면, backend에서도 socket.io 를 사용해야 하나요?? frontend는 react로, backend는 spring+kotlin으로 구현하려는데, frontend에서만 socket.io 를 사용해도 될까요?

  • react
  • 웹팩
  • typescript
  • socket.io
  • babel
  • 클론코딩
김도현 댓글 1 좋아요 0 조회수 410

중첩 라우팅 관련

해결됨

Slack 클론 코딩[실시간 채팅 with React]

안녕하세요. v6 업데이트 후 중첩 라우터 문제가 있어 질문 드립니다. 로그인 성공 시, http://localhost:3090/workspace/channel 로 이동하게 하였는데 workspace 컴포넌트에서 channel 컴포넌트를 호출하도록 중첩 라우팅 처리한 부분이 동작하지 않습니다. Workspace/index.tsx import fetcher from '@utils/fetcher'; import React, { FC, useCallback } from 'react'; import useSWR from 'swr'; import axios from 'axios'; import { Redirect, Switch } from 'react-router'; import { BrowserRouter, Routes, Route, useNavigate, Navigate, Outlet } from 'react-router-dom'; import { Header, RightMenu, ProfileImg, ProfileModal, LogOutButton, WorkspaceWrapper, Chats } from '@layouts/Workspace/styles'; import gravatar from 'gravatar'; import loadable from '@loadable/component'; const Channel = loadable(() => import('@pages/Channel')); const DirectMessage = loadable(() => import('@pages/DirectMessage')); const Workspace : FC = ({children}) => { const { data, error, mutate } = useSWR('http://localhost:3095/api/users', fetcher); // 전역 const onLogout = useCallback(() => { axios .post('http://localhost:3095/api/users/logout', null, { withCredentials: true, }) .then(() => { mutate(false); }); }, []); if (!data) { console.log('data', data); return <Navigate to="/login" replace />; } console.log("workspace page rendering"); return ( <Chats> <div>테스트</div> <Routes> <Route path="/channel/:channel" element={<Channel />} /> <Route path="/dm/:id" element={<DirectMessage />} /> </Routes> </Chats> ); } export default Workspace; pages/index.tsx import React from 'react'; import { Container, Header } from './styles'; const Channel = () => { console.log("channel page rendering"); return ( <div>채널!</div> ); } export default Channel; App/index.tsx import React from 'react'; import loadable from '@loadable/component'; import { Redirect } from 'react-router'; import { Routes, Route, Navigate, BrowserRouter } from 'react-router-dom'; const LogIn = loadable(() => import('@pages/LogIn')); const SignUp = loadable(() => import('@pages/SignUp')); const Workspace = loadable(() => import('@layouts/Workspace')); const App = () => { return ( <Routes> <Route path="/" element={<Navigate replace to="/login" />} /> <Route path="/login" element={<LogIn />} /> <Route path="/signup" element={<SignUp />} /> <Route path="/workspace/:workspace/*" element={<Workspace />} /> </Routes> ); }; export default App; http://localhost:3090/workspace/channel 로그인에 성공하여 위의 주소로 이동 시, 테스트 라는 글씨만 표시되고 채널! 이라는 글씨가 표시되지 않습니다. 코드는 공지사항에 있는 링크와 동일하게 작성을 하였는데 잘못 처리한 부분이 있을까요? 바쁘실텐데 확인 한번 해주시면 감사하겠습니다.

  • react
  • 웹팩
  • typescript
  • socket.io
  • babel
  • 클론코딩
냥냐리냥냥 댓글 1 좋아요 0 조회수 356

npx sequelize db:create시 오류발생

미해결

Slack 클론 코딩[실시간 채팅 with React]

npx sequelize db:create 명령어 실행 시 이러한 오류가 발생합니다. npm i 와 mysql이 시작된 걸 확인한 후에 npx sequelize db:create 명령어를 실행해도 위의 오류가 발생합니다. 구글링을 통해 찾아서 해결해보려했지만 , 해결이 잘 되지않아 질문을 드립니다.

  • react
  • 웹팩
  • typescript
  • socket.io
  • babel
  • 클론코딩
sehun910124 댓글 2 좋아요 0 조회수 314

Error: Cannot find module &#x27;node:crypto&#x27;

미해결

프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..)

"devDependencies": { "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.2", "husky": "^8.0.3", "lint-staged": "^15.2.0", "prettier": "^3.1.1", "webpack": "^4.41.5", "webpack-cli": "^3.3.10" }, 일때 module.exports = { env: { node: true, browser: true, }, extends: ["eslint:recommended", "plugin:prettier/recommended"], globals: { Atomics: "readonly", SharedArrayBuffer: "readonly", }, parserOptions: { ecmaVersion: "latest", sourceType: "module", }, plugins: ["prettier"], rules: { "prettier/prettier": "error", }, }; 노드 버전이 원인인가요 ? 14 버전 입니다..

  • node.js
  • 웹팩
  • babel
  • eslint
alkalisummer 댓글 1 좋아요 1 조회수 486

DefinePlugin 관련; env와 관련하여, (21.06.22 16:15, aloha_jh) 답변포함

미해결

프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..)

DefinePlugin 보고 이런생각이 들었습니다. React.js나 Next.js로 프론트엔드 개발을 할 때, 서버주소를 보통 env || env.develop 등으로 관리했습니다. 강의와 답변을 보기 전에는 이러한 라이브러리 및 프레임워크가 env 파일을 웹팩으로 설정하여 자동으로 불러오게 만들어 주는것이라고 여겼습니다. console.log(process.env.NODE_ENV); 설정한 부분을 콘솔에 기록하는 부분의 코드가 동일했기 때문입니다. 그런데 답변을 보니 DefinePlugin 과 env 설정이 다른 것으로 보여서 개념상의 차이가 어떤 부분인지 싶어 질문드립니다.

  • node.js
  • 웹팩
  • babel
  • eslint
Edwin Y. Park 댓글 1 좋아요 1 조회수 430

초기세팅

미해결

Slack 클론 코딩[실시간 채팅 with React]

안녕하세요! 초기 설정 시 제로초님 깃에서 back과 setting/ts(js는 지워도 되나요?) 만 남겨둔 후 각각 터미널에서 npm i 해서 package-lock.json 의존관계에 의해 모듈 설치한 뒤 시작하면되는건가요?

  • react
  • 웹팩
  • typescript
  • socket.io
  • babel
  • 클론코딩
전소영 댓글 2 좋아요 0 조회수 411

채팅을 인피니티 스크롤로 구현하려면 lastId 방식이 맞을까요?

해결됨

Slack 클론 코딩[실시간 채팅 with React]

인피니티 스크롤로 페이지 방식으로 구현했을때 새로운 채팅 입력시 게시글이 1~50개까지 있을 때 처음 1~10번을 가져왔는데 새로운 게시글이 추가되어서 11~20번을 가져오는 게 아니라 12~21번을 가져오는 문제가 발생해서 어찌어찌 페이지로 해결을 해보려고 해도 방법이 떠오르지 않네요.. 이걸해결하려면 채팅서비스의 경우 lastId 방식을 사용할 수 밖에 없는지 궁금합니다.

  • react
  • 웹팩
  • typescript
  • socket.io
  • babel
  • 클론코딩
qutuzm 댓글 1 좋아요 1 조회수 350

정적파일을 불러오는 방법 부탁드려요

미해결

Slack 클론 코딩[실시간 채팅 with React]

아이콘...등을 직접만든 이미지로 적용해보려 합니다. 프로젝트 루트폴더에 resource폴더 생성 후 여기에 이미지파일을 넣고 상대경로로 지정하거나 public폴더 생성 후 process.env.PUBLIC_URL로 불러오는 등의 방식을 써봤는데 정적리소스를 불러오지 못하네요. webpack.config.ts의 devServer에 static: { directory: path.resolve(__dirname) }는 추가 되어있습니다.

  • react
  • 웹팩
  • typescript
  • socket.io
  • babel
  • 클론코딩
sim jr 댓글 1 좋아요 0 조회수 265

local:host3095 사이트에 연결할 수 없음 문제

미해결

Slack 클론 코딩[실시간 채팅 with React]

안녕하세요. local:host3095 주소로 사이트가 열리지 않아 질문 남깁니다. (과정) db연결성공했고, 그 다음에 npx run dev 입력하고, 주소창에 local:host3095을 입력했더니 에러가 납니다. 포트번호가 잘못됐나 확인을 해봤는데 뭐가 문제인지 잘 모르겠습니다ㅠ 포트번호 확인 app.js에 3095라고 잘 적혀있는데 sql들어가서 server > serverstatus>test connection을 실행해보면 3306이라고 적혀있습니다. sql 종료했다 다시 실행하기

  • react
  • 웹팩
  • typescript
  • socket.io
  • babel
  • 클론코딩
바옹 댓글 1 좋아요 0 조회수 337

Access denied for user 'root'@'localhost' (using password: NO) 에러

미해결

Slack 클론 코딩[실시간 채팅 with React]

npx sequelize db:create을 설치하다가 오류가 나서 1. 최신 업데이트: npm install -g npx 2. npm install -g sequelize-cli 이렇게 해보았는데 Access denied for user 'root'@' localhost ' (using password: NO) 에러가 떴습니다. sql설치할때 패스워드 설정했고, 그 패스워드를 .env파일에 있는 MYSQL_PASSWORD에 적어뒀는데 에러가 고쳐지질 않습니다ㅠ

  • react
  • 웹팩
  • typescript
  • socket.io
  • babel
  • 클론코딩
댓글 1 좋아요 0 조회수 532

reactQuery로 짜고있는데...

해결됨

Slack 클론 코딩[실시간 채팅 with React]

useQuery 나 mutation같은걸 통해 데이터를 가져오는데 데이터 렌더링이랑 훅스랑겹치지않게 가장 함수끝부분에 배치해야된다해서 그렇게 배치했는데 data 의 null 값여부를 젤 밑에서 하니까 그위에 훅스들은 수동으로 null 값을 체크해야되는데 이런경우는 어떤식으로 하는게 좋을까요? interface Props { children?: React.ReactNode } const Comp: FC<Props> = () => { const {p1, p2} = useParams() if (!p1|| !p2) { return <>loading error</>; } const {data} = useQuery({ queryKey: mykey, queryFn: () => myfunc1(userId, codeId) }); const {mutate} = useMutation({ mutationFn: async (data: CodeRequestEntity) => { await myfunc2(data) return true } }) if(!data){ return <>loading</> } const onClickConfirm = useCallback(() => { mutate(data) onClose() }, []) return ( <> <Button variant={"outlined"} onClick={onClickConfirm}>예 </Button> </> ); }; export default Comp; 이런식으로 하게되면 분기문을통해 데이터 null 처리를 해서 분기문 밑어부터는 null 처리를 안해도되는데 null 처리를 가장 밑에 렌더링부분에 넣으면 그위에 훅스에선 데이터쓸때마다 null 처리해줘야되서 혹시 다른 방법 있을까요?

  • react
  • 웹팩
  • typescript
  • socket.io
  • babel
  • 클론코딩
쵸잉 댓글 1 좋아요 1 조회수 287

unread Count 같은 경우 실무에선는 DB에 마지막 일자를 기록하나요?

해결됨

Slack 클론 코딩[실시간 채팅 with React]

강의에서 localStorage 를 이용하여 접속시간 or 마지막 불러온 일자를 저장하고 그 local 값을 unreads 에 after 파람으로 전송하여 읽지않은 메시지를 카운트 햇는데 해당 방식은 다른 아이디로 로그인 시 같은 local 데이터를 활용하기도 하고 다른 기기에 접속시 해당값은 날라가게 될텐데 이는 에러사항으로 이어질 것으로 예상됩니다. 마지막 일자를 활용하게 된다면 이 값은 db에 저장되야 할걸로 생각이 되는데 맞을까요?

  • react
  • 웹팩
  • typescript
  • socket.io
  • babel
  • 클론코딩
최석우 댓글 1 좋아요 0 조회수 271

내부디비를 세부적으로 쓰고싶은데...

해결됨

Slack 클론 코딩[실시간 채팅 with React]

sleact 서비스에 내부스토리지 (web스토리지,indexedDB) 를 좀더 체계적으로 써야될것같은데 zustand 같은 상태관리 라이브러리에 내부스토리지를 연결하는게 좋을까요? 아니면 swr 같은데다 연결하는게 좋을까요? 아니면 내부스토리 접근하는 코드 따로 빼놓고 데이터 가져와서 state 에 관리하는게 나을까요?

  • react
  • 웹팩
  • typescript
  • socket.io
  • babel
  • 클론코딩
쵸잉 댓글 1 좋아요 1 조회수 295

onScroll 스크롤 위치 유지가 안됩니다 ㅠ

미해결

Slack 클론 코딩[실시간 채팅 with React]

import Chat from '@components/Chat'; import { ChatZone, Section, StickyHeader } from '@components/ChatList/style'; import { IChat, IDM } from '@typings/db'; import React, { FC, RefObject, VFC, forwardRef, useCallback, useRef } from 'react'; import { Scrollbars } from 'react-custom-scrollbars'; interface Props { scrollRef: RefObject<Scrollbars>; chatSections: { [key: string]: IDM[] }; setSize: (f: (index: number) => number) => Promise<IDM[][] | undefined>; isEmpty: boolean; isReachingEnd: boolean; } const ChatList: VFC<Props> = (({ chatSections, setSize, isEmpty, scrollRef, isReachingEnd}) => { const onScroll = useCallback((values) => { // 끝에 도달하면 불러오지 않기 if(values.scrollTop === 0 && !isReachingEnd){ console.log('가장 위'); setSize((prevSize) => prevSize + 1).then(()=>{ // 스크롤 위치 유지 if(scrollRef?.current){ scrollRef.current?.scrollTop(scrollRef.current?.getScrollHeight() - values.scrollHeight); } }); } }, []); return ( <ChatZone> <Scrollbars autoHide ref={scrollRef} onScrollFrame={onScroll}> {Object.entries(chatSections).map(([date, chats]) => { return ( <Section className={`section-${date}`} key={date}> <StickyHeader> <button>{date}</button> </StickyHeader> {chats.map((chat) => ( <Chat key={chat.id} data={chat} /> ))} </Section> ); })} </Scrollbars> </ChatZone> ); }); export default ChatList; 이쪽 코드는 문제가 없는것같은데 희한하게 위치가 유지가 되지않고 원래처럼 쭉 올라가버립니다.. ref쪽이 문제인가요..? 혹시몰라 DirectMessage 컴포넌트도 아래에 첨부하겠습니다. import React, { useCallback, useEffect, useRef } from 'react'; import gravator from 'gravatar'; import useSWR, { mutate } from 'swr'; // swr 인피니티스크롤링 전용 메서드 import useSWRInfinite from 'swr/infinite'; import { IDM, IUser } from '@typings/db'; import fetcher from '@utils/fetcher'; import { useParams } from 'react-router'; import ChatBox from '@components/ChatBox'; import { Container, Header } from '@pages/DirectMessage/style'; import ChatList from '@components/ChatList'; import useInput from '@hooks/useInput'; import axios from 'axios'; import makeSection from '@utils/makeSection'; import Scrollbars from 'react-custom-scrollbars'; const DirectMessage = () => { const { workspace, id } = useParams<{ workspace: string; id: string }>(); const { data: userData } = useSWR(`http://localhost:3095/api/workspaces/${workspace}/users/${id}`, fetcher); // 내정보 const { data: myData } = useSWR(`http://localhost:3095/api/users`, fetcher); const [chat, onChangeChat, setChat] = useInput(''); // 과거 채팅리스트에서 채팅을 치면 최신목록으로 바로 스크롤을 내려줄려면 ref를 // 이 컴포넌트에서 props로 내려줘야하기 때문에 forwardRef를 사용해서 props로 넘겨준다 // 💡 HTML 엘리먼트가 아닌 React 컴포넌트에서 ref prop을 사용하려면 React에서 제공하는 forwardRef()라는 함수를 사용해야 합니다 const scrollbarRef = useRef<Scrollbars>(null); // 채팅 받아오는곳 (setSize : 페이지수를 바꿔줌) // useSWRInfinite를 쓰면 [{id:1},{id:2},{id:3},{id:4}] 1차원배열이 [[{id:1},{id:2}],[{id:3},{id:4}]] 2차원배열이 된다. const { data: chatData, mutate: mutateChat, setSize, } = useSWRInfinite<IDM[]>( (index) => `http://localhost:3095/api/workspaces/${workspace}/dms/${id}/chats?perPage=20&page=${index + 1}`, fetcher, ); // 데이터 40 개중에 20개씩 사져오면 첫번째페이지부터 20 + 20 + 0 세번째 페이지 0 이되면 isEmpty, isReachingEnd는 true가 됨 // 반대의 상황에서 데이터가 45개면 20 + 20 + 5 isEmpty는 0이 아니라서 false isReachingEnd는 여전히 데이터 가져옴 const isEmpty = chatData?.[0]?.length === 0; const isReachingEnd = isEmpty || (chatData && chatData[chatData.length - 1]?.length < 20) || false; const onSubmitForm = useCallback( (e) => { e.preventDefault(); if (chat?.trim() && chatData) { const savedChat = chat; // 💡 옵티미스틱 UI // 서버쪽에 다녀오지 않아도 성공해서 데이터가 있는거처럼 보이게 미리 만듦 mutateChat((prevChatData) => { // infinite 스크롤링은 2차원 배열이다. prevChatData?.[0].unshift({ // unshift : 앞쪽에 추가 id: (chatData[0][0]?.id || 0) + 1, content: savedChat, SenderId: myData.id, Sender: myData, ReceiverId: userData.id, Receiver: userData, createdAt : new Date(), }); return prevChatData; },false) // 옵티미스틱 UI 할땐 이부분이 항상 false .then(()=>{ setChat(''); // 버튼클릭 시 기존 채팅지우기 scrollbarRef.current?.scrollToBottom(); // 채팅 첬을때 맨 아래로 }) axios .post( `http://localhost:3095/api/workspaces/${workspace}/dms/${id}/chats`, { content: chat, }, { withCredentials: true, }, ) .then(() => { mutateChat(); // SWR에서 데이터를 다시 불러와서 캐시를 갱신하는 역할을 합니다. }) .catch(() => { console.error; }); } }, [chat, chatData, myData, userData, workspace, id], ); // (채팅이 최신것을 아래에 두기 위함) = 기존것 데이터를두고 새 데이터를 뒤집어서 출력 / flat() 배열을 1차원 배열로 만들어줌 const chatSections = makeSection(chatData ? [...chatData].flat().reverse() : []); // 로딩 시 스크롤바 제일 아래로 useEffect(()=>{ if(chatData?.length === 1){ // 채팅 데이터가 있어서 불러온 경우 scrollbarRef.current?.scrollToBottom(); // 가장 아래쪽으로 내려줌 } },[chatData]) // 로딩 if (!userData || !myData) { return null; } return ( <Container> <Header> <img src={gravator.url(userData.email, { s: '24px', d: 'retro' })} alt={userData.nickname}></img> <span>{userData.nickname}</span> </Header> {/* 컴포넌트 위치를 미리 지정해도 좋다. */} {/* 전역 상태관리 라이브러리를 사용해도 컴포넌트상황에따라 props 로 넘겨줌*/} <ChatList scrollRef={scrollbarRef} chatSections={chatSections} setSize={setSize} isEmpty={isEmpty} isReachingEnd={isReachingEnd} /> <ChatBox chat={chat} onChangeChat={onChangeChat} onSubmitForm={onSubmitForm} /> </Container> ); }; export default DirectMessage;

  • react
  • 웹팩
  • typescript
  • socket.io
  • babel
  • 클론코딩
복실묘 댓글 2 좋아요 0 조회수 530

useSwr 여러컴포넌트에 사용가능한가요

미해결

Slack 클론 코딩[실시간 채팅 with React]

workSpace 에도 useSwr 로 유저데이터랑 채널데이터 요청하고 모달안에서도 유저데이터랑 채널데이터 요청하는데 이러면 불필요한 요청이 모달하나 띄운다고 실행되는거 아닌가요? workSpace에서 revalidate 함수만 넘겨서 하면 어떤가요?

  • react
  • 웹팩
  • typescript
  • socket.io
  • babel
  • 클론코딩
쵸잉 댓글 1 좋아요 0 조회수 359

인기 태그

인프런 TOP Writers

주간 인기글