생각기록

3차 타입스크립트&React & Socket .io 오류 정리 본문

프로젝트/개인 COZY

3차 타입스크립트&React & Socket .io 오류 정리

끼록관 2023. 4. 10. 04:56

모듈 에러

 Cannot find module 'socket.io' or its corresponding type declarations.

socket.io를 찾을수 없어서 발생하는 에러

 

해결방법

이를 해결하기위해 실행 js파일과 동일선 상에 node_modules 를 포함한 링크를 만들어주어야 합니다.

⇒ npm link socket.io

 

Module '"http"' has no default export.

HTTP 모듈에 기본 내보내기가 없다는 오류가 표시

내가 안됬던 이유  => socket.ts 파일에도 http를 쓰고있는데 import 안해놈

 

 

server.ts:3:8 - error TS1259: Module '"C:/Users/SBAUser/Desktop/\uC6A9\uC0B0 3\uCC28 \uAC1C\uC778/chat/node_modules/@types/cors/index"' can only be default-imported using the 'esModuleInterop' flag 3 import cors from 'cors';

해결방법

improt * as ~ 오류난부분 해주면 됨

 

git 에러

fatal: Unable to create 'C:/Users/SBAUser/Desktop/용산 3차 개인/COZYChat/.git/index.lock': File exists.

특정 Git 프로세스가 동작중일 때 다른 Git 프로세스가 실행되는 것을 막기 위해서 index.lock 이라는 파일이 생기는데,

의도된 프로세스가 아니라면 index.lock 파일을 지워주시면 해결이 되는 것이었다.

해결방법

⇒ rm -rf ./.git/index.lock

 

 

[git] 실수로 submodule add 했을 때

[git] 실수로 submodule add 했을 때
hint: You've added another git repository inside your current repository.
hint: Clones of the outer repository will not contain the contents of
hint: the embedded repository and will not know how to obtain it.
hint: If you meant to add a submodule, use:
hint:
hint:   git submodule add <url> chat
hint:
hint: If you added this path by mistake, you can remove it from the
hint: index with:
hint:
hint:   git rm --cached chat

해결방법

⇒ git rm --cached chat 힌트대로 chat 관련 없애주기

후 add commit 성공

 

타입 에러

This expression is not callable.
Type 'typeof e' has no call signatures.

import express from 'express' 로 바꾸어 해결하였다.

 

 

TypeError: (0 , express_1.default) is not a function at Object.<anonymous>

https://stackoverflow.com/questions/63744824/getting-express-default-is-not-a-function-error-when-i-run-node-server-in-a-co

 

해결못한 오류

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.

No index signature with a parameter of type 'string' was found on type '{}'.

string literal타입만 허용되는 곳에 string타입을 사용했기 때문에 것이다.

 

 

 

프로젝트 에러 중


소켓 & 서버 오류

소켓 에러 01

2번 검사하는 모드를 <> 빈태그로 감싸고

저렇게 된 원인

useEffect 마다 저 부분을 추가해놧기때문에 다중연결이 된 것!

socket = io (주소) 는 연결을 요청하는 것

그런데 버튼이라던가 따른 useEffect에 해야 할때, 저 부분이 필요하게 됬다.

 

해결 방법

import { io } from 'socket.io-client';
const socket = io('http://localhost:3010');

export default socket;

socket 요청을 따로 컴포넌트로 빼고

import socket from '../util/socket';

임포트해서 쓴다!

 

 

소켓 에러 02 서버에서 socketID에 값이 안들어온다

소켓 에러라기보단, 기본적인 실수 오류

시도 1. 위 아래랑 비슷한데 왜 undefined가 뜰까..

객체에서 key로 value 찾는 방법을 검색해봤더니

object[key] 는 object가 key를 갖고 있을 때 value를 리턴합니다. 존재하지 않는 key를 찾을 때는 undefined 가 리턴됩니다.

https://codechacha.com/ko/javascript-find-value-by-key/

 

시도 2. typeof로 찍어보려고함

⇒ 아님.. 둘다 string이였다.

dm만 하면, socket 아이디로 변경이 됬다.

서버의 이부분이 문제 인줄 알았는데.. 아니였다.

문제 해결

  1. key = json.to 라고 했기때문에 // json.to의 소켓 아이디값이 userList[key] 에 들어간것…

=이라고하면, 값을 넣는것 == 부터 비교하는것임!!!!... 

이런 오류도 못찾다니.......

  1. 그리고 userList[key] = json.to(소켓아이디) 비교자체가 잘못되었다.

⇒ 닉네임 =  소켓아이디 비교 x / 소켓아이디값이 같은지 비교해야 했다.

이것이 정답

 

 

콘솔의 실행

번외로 충격적인 사실을 처음알았는데........

콘솔에서 넣은 값들도 실행이 된것이기 때문에, 전체에 영향을 준다는 사실..

콘솔이 살아있다면, 계속 위의 것이 실행되서 username에 영향을 준다 🤦‍♀️

이것처럼 a에 값을 다르게 넣어 실행한 콘솔이 있으면, 값도 달라진다

 

 

 

에러 03 드디어 나도 겪어보는 cors 에러

Access to XMLHttpRequest at '
http://localhost:3010/userFileUpload
' from origin '
http://localhost:3000
' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

CORS 오류는 교차출처 리소스 공유 기능으로 실행 중 웹 어플리케이션이 다른 출처의 리소스에 접근 권한을 부여하는 기능…

 

해결 방법

npm i cors

소켓에 말고, server.ts 파일에

// 미들웨어 cors 어떤 주소로 요청해도 에러가 뜨지 않도록
const cors = require('cors');
app.use(cors());

꼼수같지만, 미들웨어로 처리

 

 

 

에러 04  [node] multer 이미지 이름 깨져서 오는 오류(인코딩 오류)

이것때매 프론트에 보져주기 좀 힘들것같아서 오류 해결하기 위해 찾아봄

 

https://paulpung.dev/blog/Multer 한글 파일명 깨짐 이슈

이분거 보고 해결

 

왜 생긴 오류인가?

⇒ multer는 chrset설정이 불가능하다고 합니다. 

(multer가 의존하는 busboy 패키지가 파일의 기본 chrset을 litin1 으로 설정해뒀기때문

 

해결

오리지널 파일이름을 변환시켜주는 작업

다른 방법도 있다고 합니다.

try {
  busboy = Busboy({
    headers: req.headers,
    limits: limits,
    preservePath: preservePath,
    defParamCharset: charset,
*// 추가된 부분 - busboy는 defParamCharset이 없으면 바이너리 데이터를 latin1으로 인식함*

})
} catch (err) {
  return next(err)
}

 

 

에러 05  socket.on 안에 socket.on 하면 안됨!!!!!!!!

서로 다른 이벤트이기 때문에.. 안에 쓸 수 없다 😂

 

 


타입 스크립트 오류

01 자식 컴포넌트에게 props 값을 보낼때

username의 값을 하위 컴포넌트에 props로 보내주려고 한다.

Type '{ sendName: string; }' is not assignable to type 'IntrinsicAttributes & userNameType'.

Property 'sendName' does not exist on type 'IntrinsicAttributes & userNameType'.

Type '{ sendName: string; }' 유형은 IntrinsicAttributes(고유속성) & userNameType 유형에 할당 하지 못함

해결방법

보낼때 부모 컴포넌트에서 보낸 이름을 자식컴포넌트의 인터페이스에 똑같이 sendName 으로 이름을 해줘야 합니다.

 

저는 name으로 받아와서 안됬던것

 

02 Object is Possibly null

useRef로 선언되고 컴포넌트의 실행되고 평가가 진행되는 시점에서는 current 객체는 null로 평가된다.

이거, 초기값에 전달을 아무것도 안해놔서 그런거 아닌가? 싶을 수도 있지만 초기값에 어떠한 값을 전달해 두더라도

null

이 출력된다.

 

Object is Possibly null 오류 해결하기

이 오류를 해결하려면 두가지 방법이 있다.

첫번째로는 useLayoutEffect 훅을 사용하는 방법이다.이렇게 사용함으로써 렌더링 하면서-ref를 연결해 ref의 current 객체가 만들어져서 current 객체가 생성되지 않을 가능성 없이 ref를 사용할 수 있다.

두번째는, ref를 사용할때마다 null 체크를 해주는 것이다.

const onChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
    ...
    if (e.target.id === 'minPrice') {
      if (!isValidRatio && minPriceRef.current) {
        	// 여기서 current 객체가 있을때만 작동하게 해준다.
        minPriceRef.current.value = String(currentMaxRatio - MIN_BETWEEN_RATIO);
        return;
      }
    }

이런 방식으로 current  객체를 사용할 때마다 null 여부를 확인하면 오류 없이 문제를 해결할 수 있다.

 

03 Argument of type 'string | undefined' is not assignable to parameter of type 'string | string[]'. Type 'undefined' is not assignable to type 'string | string[]'.

타입으로 undefined 를 넣을 수가 없다는 말이다. 이 에러는 undefined 에 대한 처리를 해주지 않아 난다.

 

 

https://cesarwbr.github.io/react-input-emoji/

 

04. 타입스크립트에서 쓰지 못하는 라이브러리도 있다. 

왠지 아무리 깔아도 오류나더라 모듈오류!! 밑에거 못썼다.

https://cesarwbr.github.io/react-input-emoji/

 

 

05. This module is declared with 'export =', and can only be used with a default import when using the 'esModuleInterop' flag.

This module is declared with 'export =', and can only be used with a default import when using the 'esModuleInterop' flag.

 

모듈은 esModuleInterop 플래그를 사용하여 기본적으로 가져올 수만 있습니다.

시도 1. 파일 에서 esModuleInterop옵션을 로 설정

tsconfig.json
{
  "compilerOptions": {
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    // ... rest}
}

되어있었음

 

시도 2. import * as multer from 'multer'; 실패!

해결 ⇒ 그냥 const 땡땡 = require('땡떙'); 으로 하니까 해결

 

 

06.  module.exports = router 를 추가안해서 생기는 오류

****[Node.js 에러]****throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn))

TypeError: Router.use() requires a middleware function but got a Object

해결 방법

routes 폴더의 .js의 폴더 마지막에 module.exports = router 를 추가해주면 된다.

 

 

 

07.TypeError: (0 , socket_1.default) is not a function

⇒ 함수 socket파일에다가 router랑 해서 그러려는것같은데.. 

socket을 함수로써만 쓸 수 있으려면, 라우팅 관련 export 하면 오류가 생긴다.

 

 

08. SyntaxError: Unexpected token u in JSON at position 0

https://webcorgi.tistory.com/45

해결 ⇒ 값이 없는데, parse 하려고해서 생긴 오류입니다.

 

09. 값을 넣어서 formdata 전송하려고했는데, 바로 안되는 오류

값을 넣어서 formdata 전송하려고했는데, 바로 안되는 오류가 있었다.

이런저런 방법을 해보다가

input자체에 그냥 onchange를 걸어버렸더니 업로드는 되는데, 서버오류 해결해야한다.

 

원인

⇒ 업로드는 제대로 되는게 맞았는데!

서버에서 formdata === undefined 조건을 빼야 했고,… formdata가 undefined 뜨는것 맞고, 그 값을 안사용할것!

res.send를 else부분에만 걸었기 떄문

😅

app.post('/userFileUpload', upload.array('userFile'), async (req:any, res:any) => {
    if ( req.files === undefined )
     {
        console.log('파일이 없습니다.')
        res.send(false)
    } else {
        console.log('req.files : ', req.files);
        res.send(req.files)
    }
  })

 


react & 기본 에러 & 기타 에러

채팅보내기 enter 허용했는데, 초기화되서 메인으로 나가짐

엔터 자체 문제라고 판단하셔서 e.preventDefault 함수를 거심

 

 

02 ‘let' declarations can only be declared inside a block.t

'let' 선언은 블록 내에서만 선언할 수 있기 때문입니다.

{ } 중괄호 안에 안써서 난 오류

 

 

03 React input 태그에 text가 써지지 않는 버그

input 태그에 value={스테이트} 값을 주었던것때문에 오류가 생김

input 태그에 onchange를 걸어야 한다고 한다.

 

1. 전체값을 input state에 받는다.

onchange를 input 에 현재 값을 받도록 한다.

 

2. 이모지나 기타 등등 값들을 넣어주고 싶다.

setInput( input(현재 인풋값) + e.native( 이모지 값) ) 을 더해주면, input state 값에 변화가 온다

<button
                  onClick={(e: any) => {
                    e.preventDefault(); // 기본 동작 막기
                    setIsEmoji(!isEmoji);
                  }}
                  // onClick={onEmojiSelectBtn}
                  className={isEmoji ? 'd-none' : 'd-block emoji_btn'}
                >
                  이모지 선택
                </button>
                <div className={isEmoji ? 'd-block Picker' : 'd-none'}>
                  <Picker
                    data={data}
                    previewPosition="none"
                    onEmojiSelect={(e: any) => {
                      setInput(input + e.native);
                      setIsEmoji(!isEmoji);
                    }}
                  />
                </div>

                <input
                  type="text"
                  id="msgBox"
                  name="msgInput"
                  placeholder="메세지를 입력하세요.."
                  onKeyDown={(e: any) => {
                    if (e.key == 'Enter') {
                      e.preventDefault(); // 기본 동작 막기
                      btnSend();
                    }
                  }}
                  value={input}
                  onChange={(e) => {
                    setInput(e.currentTarget.value);
                  }}
                />

 

04 백틱 안에 이미지 경로 쓰고, 제대로 사진이 안나온다면 확인 tip

if (json['is_file']) {
          let fileName = json.file[0];
          console.log('fileName  :  =  = ', fileName.filename);
          file_div.innerHTML = `<img src="/uploads/${fileName.filename}" alt="업로드이미지"/>`;
        }

이미지 경로 코드가 잘못됫는지 확인해보고 싶으면

http://localhost:3000/uploads/2.png

내가 업로드한 파일명으로 확인하는 방법이 있고!

 

또 한가지는

페이지 검사로 내 코드 보기

보면 + 가 보이죠 저거 지워야함 !!!!!!

 

 

05 값에 읽을 수 없는 값이 있다.

typeError : cannot read properties of undefined (reading ''ddd'')

검사로 확인해보니 빨간줄 부분이 문제임

해결 

payload부분이 msg였던부분을 다시 payload로 변경했더니 값들이 들어옴


EsLint 오류 01

[eslint] Failed to load config "airbnb-base" to extend from.

https://github.com/airbnb/javascript/issues/2233

그냥 해결법은 아닌데..

내 eslintrc.js 파일이 루트폴더 밖에 있었고, 그것을 src 폴더 안으로 옮겼더니 정상 작동 한다.

 


꿀팁

css 채팅 좌우 정렬

https://seons-dev.tistory.com/entry/display-flex-좌우-정렬

채팅창은 이렇게 함!

 

 

서버 실행과 tsc server.ts를 동시에 하고싶다면?

서버 json 파일에 scripts 부분에 같이 실행할 파일들을 묶음

npm run dev 라고 하면 둘이 실행된다.

 

 

 

채팅창 로그가 새로 생기면, 해당 엘리먼트를 호출해 유저가 보도록 하는 방법

scrollIntoView

이 메소드는 scrollIntoView()가 호출된 엘레멘트를 유저가 볼수있는 부분으로 상위 컨테이너를 스크롤 한다