728x90

문제의 두번째 에러..

https://choq.tistory.com/112

 

[Firebase] Firebase Hosting Setup Complete 해결하기!(feat. Nextjs)

Nextjs로 만든 개인 프로젝트 서버에 배포하기 위해서 방법을 찾던 중에 Firebase를 선택했다! 서버나 백엔드에 시간을 들일 계획이 없었기에 최적의 선택이지 않나 싶다. 방법은 Firebase의 Hosting 메

choq.tistory.com

 

 

위 이야기에서 이어지는 내용이다.

짜라란 바꿨는데도 불구하고 해결되지 않는다.. 새로운 에러의 등장. 무엇이 문제일까?

 

 

원인은 디렉토리에 index.html 파일이 없어서 이다. 그러고 보니 빌드된 .next 폴더에 들어가 보면 index.html 파일이 보이지 않는다.

기본적으로 Firebase의 Hosting은 정적파일을 지원한다. 하지만 Next.js의 일반적인 빌드 방식으로는 해당 파일이 만들어지지 않기에 설정에서 손을 봐서 정적인 index.html을 뽑아낼 수 있도록 해야한다.

 

// next.config.mjs
const nextConfig = {
  output: "export",
};

 

 

위 next 설정파일에서 output 설정을  추가해주고 빌드를 시키면 out폴더에 우리가 원하는 index.html이 생기는걸 확인할 수 있다.

그리고 나서는 이전에 확인한 firebase.json 파일을 수정해두면 된다.

 

{
  "hosting": {
    "public": "out", // 요기!!!
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ]
  }
}

 

기존에 public 부분을 out으로 수정해주고 빌드/배포를 진행하면!?

드디어 우리의 url에 우리가 원하는 페이지가 나오는것을 확인할 수 있다!!!! 쨔스쨔아스~

 

자신의 프로젝트에서 빌드 결과물로 index.html이 있는 폴더를 확인하면 다른 케이스(다른 프레임워크나 환경)에 대해서도 금방 대처할 수 있지 않을까 싶다!

 


 

서버에 처음 이렇게 배포를 해보았는데,, 쉬우면서도 뭔가 귀찮은 그런..

728x90
728x90

 

 

Nextjs로 만든 개인 프로젝트 서버에 배포하기 위해서 방법을 찾던 중에 Firebase를 선택했다! 서버나 백엔드에 시간을 들일 계획이 없었기에 최적의 선택이지 않나 싶다. 방법은 Firebase의 Hosting 메뉴를 들어가면 친절하기 설명해준다. 하라는 내용들을 다 마무리하면 이제 배포가 완료되었으니 확인해보라며 URL을 던저준다. 두근거리는 마음으로 열어보았는데 내 페이지는 어디가고 위에 같은 화면만 출력된다. 저기 들어가서 세팅하면 되는건가? 싶지만 단순 다큐멘트로의 이동일뿐 다른 설정은 보이지 않는다... 왜 와이.. 원인은 무심코 지나갔던 설정에 있다.

 

Firebase 설정을 하나씩 하다보면 What do tou want to use as your public directory? public  이라는 페이즈가 있다. pulic 그냥해~ 하는 식으로 기본값을 미리 띄워준 상태로 말이다. 바로 한마리 어린양이 되어 무지성 엔터로 답가해주었고 이게 위 이슈로 이어졌다고 볼 수 있다.  

 

위 설정대로 진행하면 프로젝트 firebase.json 에 아래와 같이 생긴다. 

{
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ]
  }
}

 

위 코드에서 "public" 에 대한 필드값이 문제이다. public은 업로드할 정적 파일이 어디에 있나요? 물어보고 있는것이다. 그걸 묻따않고 public으로 해두었으니 빌드된 내용을 제대로 확인할 수 없어서 작업한 페이지를 볼 수 없는것이다.

 

여기까지 듣고 Nextjs의 빌드는 어느 폴더가 들어가는지 다들 알고있는 프로출신들은 public을 바로 .next로 변경해줄 것이다.

하지만 저렇게 변경하고 배포하면... 이번엔 새로운 화면에 직면하게 된다..

 

 

 

to be continuned...

728x90
728x90

 

 

 

요즘 cursor와 거의 함께 하다 싶이 하다. vscode 와는 이별한지 오래..
가끔 퍼블리싱 작업을 진행할때 피그마에서 해당 내용을 스크린샷 해다가 사진을 넣고 '해줘'라고 부탁한다. 퍼블리싱에 시간을 줄이고 비즈니스 로직에 집중하기 위한 ^^;

하지만 사진으로 하다보면 이상하게 퍼블리싱을 뽑아줄 때가 있다. 색이 다르다거나 폰트 크기가 다르다 든가 말이다. 당연히 사진의 한계겠지.. 하지만 이런 이슈를 한 번에 잡아줄 방법이 하나 있다. 프로출신들은 이미 알고 있는 방법, Figma MCP를 cursor에 연결하는 것이다. 해당 MCP를 연결하면 정확한 값을 가지고 와서 퍼블리싱을 진행해 준다. 그럼 빠르게 알아가 보자.

 

 

순서는 아래와 같다. 이미지도 함께 했으니 쉽게 따라올 수 있을 것이다.

1. 피그마에서 토큰값 확인하기

2. 커서 설정에서 MCP 연결해 주기 (with 토큰)

3. 적용해 보기

 

 

 

1. Figma에서 토큰값 확인하기

피그마 홈 좌측 상단에 본인 아이디를 클릭하면 메뉴가 출력되는데  Settins → Security 로 이동한다.

 

 

 

하단에 Personal access tokens 부분에서 Generate new tokens를 클릭해서 생성해 주고 토큰값을 복사해 둔다.

생성한 직후에만 값을 확인할 수 있기 때문에 반드시 바로!! 저장해 둘 것. 

 

 

2. Cursor 설정에서 MCP 연결해 주기 (with 토큰)

 

커서를 켜고 Preference → Cursor Settings에 접속한다.

 

 

이후 [Tools & Integrations] 메뉴에서 [New MCP Server]를 클릭해 준다.

 

 

 

 

그러고 나면 json 파일을 추가할 수 있는데 아래의 값을 복사해 주고 저장해 주면 끝!

[복사한 토큰 값]에는 조금 전에 복사해 둔 피그마 토큰 값을 넣어주면 된다.

 

{
  "mcpServers": {
    "Framelink Figma MCP": {
      "command": "npx",
      "args": [
        "-y",
        "figma-developer-mcp",
        "--figma-api-key=복사한 토큰 값",
        "--stdio"
      ]
    }
  }
}

 

아래와 같이 불이 들어왔다면 연결이 완료된 것이다! 정말 쉽죠?

 

 

 

3. 적용해 보기

이제 피그마에서 아래같이 링크 복사 버튼을 가지고 와서 agent에게 붙여 넣으면서 작업을 부탁하면 정확하게 작업을 진행해 준다. 이제 당신의 퍼블리싱 시간은 예전에 비해 현저히 줄어들 것이다~!

 

 

 

해당 기능은 node 18 이상의 상태에서만 정상 작동한다고 한다.

그래서 본인은 기존에 16인 상태에서 에러가 처음에 났었는데, 노드 버전을 변경하고 cursor를 재부팅하고 나니 정상 적용 되었다! 

(에러 상황에서 agent가 알아서 방법을 추천해 주고 진행해 주긴 한다!)

 

 


 

 

퍼블리싱은 처리했으니 비즈니스 로직에 집중하라구~!

 

728x90
728x90

 

 

관심사 분리소프트웨어 디자인 원칙으로, 하나의 모듈이나 컴포넌트가 여러 관심사를 동시에 처리하는 대신, 각 부분은 하나의 특정 관심사만 담당하도록 코드를 분리하는 것을 의미한다.

관심사 분리는 프런트엔드와는 거리가 있다고 하는 분이 있다면, 이는 명백한 오판이었다. (내가 그랬다..!!)

프런트엔드에서도 관심사 분리를 염두에 두고 코드를 작성하면, 유지보수성과 확장성이 눈에 띄게 좋아진다. 각 로직의 책임이 명확해지면서 협업이나 디버깅 과정에서도 훨씬 효율적으로 일할 수 있다. 어떻게 하는지 간락하게 살펴보자.

 

 

/Main.tsx

export default function Main() => {

	const handleInput = () => {}

	return (
		<input onClick={handleInput} />
	)
}

 

 

위 처럼  input을 그려야하는 페이지를 하나 예를 들어보자. Main 이라는 컴포넌트에 input을 컨트롤하는 함수와(로직) 사용자에게 보여지는 return (뷰) 부분이 하나의 페이지에 구성되어있다. 이 코드에서는 관심사 분리의 필요성이 크게 느껴지지 않는다. 한눈에 뷰의 구성과 해당되는 함수가 한눈에 들어오기 때문이다. 하지만 필요한 함수가 늘어나고 보여줘야하는 컴포넌트가 무수히 많아진다면 위 코드는 어떻게 될까? 코드 자체의 길이도 늘어나는것은 물론이고 한눈에 파악하기도 매우 어려워 진다. 

예전의 나였다면 return(뷰) 쪽의 컴포넌트들을 나누는 선택지만을 선택했다. 그러면 하나의 코드에 보여지는 함수도 줄어들고 뷰도 훨신 쉽게 파악할 수 있기 때문이다. 물론 좋은 방법이지만 여기에 관심사 분리를 적용한다면 더욱 깔끔하게 코드를 관리할 수 있다.

 

https://choq.tistory.com/109

 

이전의 글에서 featured-based 구조를 다룬적이 있다. 이를 기반으로 위 코드에 관심사 분리를 적용해보자.

src/
├── features/
│   ├── Main/
│   │   ├── components/              // 공틍으로 사용되는 컴포넌트 
│   │   ├── hooks/                   // REACT와 의존적, 상태관리, 생명주기, UI와 밀접
│   │   ├── services/                // 단순 함수
│   │   └── Main.tsx

 

현재 코드에서는 컴포넌트와 단순 함수는 없으니 hooks 만 추가해보려고 한다. hooks 와 services 차이점은 단순한가, 다른 상태관리, 생명주기 등과 엮겨있나 이다. 단순하게 string의 형식 변경 같은 함수는 services 폴더에, 값에 따라서 팝업을 보여주는 함수는 hooks 에 추가하면된다. (위 handleInput 은 이런 함수라고 가정해본다.)

 

 

/hooks/useMainLogic.ts

const useMainLogic = () => {
  const handleInput = () => {}
  
  return {
   handleInput
  }
}

 

/Main.tsx

export default function Main() => {
 const { handleInput } = useMainLogic();
 
 return(
  <input onClick={handleInput} / >
 )
}

 

 

위 처럼 관심사 분리를 통한 코드 관리는 코드의 양이 커져갈 수록 더 큰 힘을 발휘한다. 

오늘 한번 함수와 뷰가 많이 섞여있는 페이지를 하나 나눠본다면 그 힘을 바로 체감할 수 있을것이다! 

 


 

 

728x90
728x90

프로젝트에서 폴더와 파일들을 어떻게 구성하는게 좋을까?

초기에 대충 짜 놓은 방식으로 간다면 프로젝트가 점점 커질수록 유지보수의 발목을 잡게 된다.

프로젝트가 방대해질 수록 아키텍처는 큰 힘을 발휘한다. 코드 탐색도 쉬워지고, 기능 변경시 영향 범위 파악도 쉬워지고 이에 따라 리팩토링도 수월하게 진행할 수 있다.

 

오늘은 두 가지 아키텍처 구조를 알아보고자 한다.

layered-based 와 featured-based 이다.

 

Layered-based 

역할 기반으로 나누는 방식이다. 폴더 구조를 보면 바로 느낌이 온다.

src/
├── components/
├── pages/
├── services/
├── hooks/
├── utils/
├── types/

 

장점 : 역할별로 나뉘어있기에 책임이 명확하고, 작은 프로젝트에서 빠르게 진행하기에 최적화

단점 : 기능단위로 개발하기가 어렵고, 규모가 커질수록 폴더가 커짐

 

이에 작은 프로젝트나, 개인 프로젝트를 진행할때 편한 방식이라고 볼 수 있겠다. 다만 큰 프로젝트에서는 그 단점이 부각되기 시작되는 것으로 생각하면된다.

 

 

Featured-based

한단계 자세한 기능으로 폴더를 구별하는 방식이다.

src/
├── features/
│   ├── login/
│   │   ├── components/
│   │   ├── hooks/
│   │   ├── services/
│   │   └── LoginPage.tsx
│   shared/
│   ├── components/

 

장점 : 기능단위의 개발 편의, 협업 용이

단점 : 재사용 가능한 코드가 각각의 feature에 포함될 위험성 존재, 초기 설계가 필요함

 

재사용에서 이슈가 있고 초기에 설계 비용이 필요로 되지만 여러명이서 협업하기에는 적합하다.

 

 

이에 각 프로젝트의 성격별로 폴더 아키텍처를 선택해서 진행하면 된다. 

개인이나, 규모가 작은 프로젝트라면 layered-based, 규모가 크고 협업을 진행해야한다면 featured-based 가 적합하지 싶다.


 

featured-based는 하나의 feature 내부에 hooks 과 component등을 분리하게 되면서,

관심분리를 자연스럽게 진행되기에 개인적으로 마음이 가는 방식이다.

 

728x90
728x90

 

 

 

MVC 패턴, MVVM 패턴 등의 용어를 들어본적이 있는가? 컴공을 나왔다면 디테일하게 설명 할 수는 없어도 모를 내용은 아닐 것이다. 어 대충 각각 하는일 분리하는 그런 내용이다. 본인은 아마 JAVA 수업때 처음으로 들어봤던 것 같다. 함수별로 하는 일을 분리하고 어쩌구 저쩌구..  하지만 프런트엔드 개발자가 되기로 하고 React 개발을 본격적으로 하면서 해당 개념은 내게 조금씩 잊혀져 갔다. 패턴이나 아키텍처의 개념은 DB 와 DB에서 값을 호출하는 함수를 짜는 백엔드 개발에서 주로 사용되는 개념이겠거니 싶었다. 

 

 

그러다가 이를 계몽시켜주는 일이 내게 생겼다. 

 

 

규모가 있는 회사에 인터뷰 볼 기회가 생겼다. 인터뷰 중에 ‘관심사의 분리’에 대한 화두가 던져졌다.

위에 말했듯 평소에 패턴이니 관심사 분리니 하는 부분에 대해 깊이 생각해본적이 없었다.

물론 너무 덩치가 큰 컴포넌트는 여러 개로 나눠서 관리하는 편이었고, 공통으로 쓰는 컴포넌트, 함수 정리, 딱 그 정도가 나에게는 '관심사 분리'라고 생각했다.

 

하지만 인터뷰를 진행한 그 팀에서는 훨씬 더 명확하고 체계적인 분리를 하고 있었다. 단순히 컴포넌트 단위로 나누는 것을 넘어서, featured-based 방식으로 폴더 구조부터 철저히 설계되어 있었고, MVC 패턴을 기준으로 각 파일과 로직이 어디에 위치해야 하는지에 대한 기준이 명확했다. 내가 가볍게 여겼던 부분이, 혹은 전혀 생각지도 않은 부분이, 규모가 있는 팀에서는 엄연히 개발 문화이자 기술적인 기준으로 작동하고 있었던 것이다. 

 

 

해당 인터뷰 이후에 많은 것을 피부로 느끼고 내 코드 생활에 적용해보려고 하고있다. 다시금 패턴과 아키텍처 개념에 대해서 리마인드하고 각각의 관심사 분리가 되어있는 코드를 짜보려고 한다. 아직 익숙치 않음에도 부분씩 관심사 분리를 하고나면 확실히 코드를 확인하는것 부터가 수월해지는 감도 있다. 규모가 훨씬 큰 프로젝트에서는 필수적일수밖에 없겠구나 라는 생각도 피부로 느낄수 있는것 같다.

 

 

혹시나 본인처럼 FE 개발자로서 패턴이나 아키텍처 부분에 등한시 하고 있다면, 다시 한번 생각해보기를 추천드립니다~

 


 

인터뷰를 통해서 생각이 변경되고 앞으로 더 나아가는 기회가 된 것에는 건설적인(?) 분위기를 이끌어 주셨던 너무나도 좋은 면접관을 만난 운도 한몫하는것 같다. 감사합니다 :)

728x90
728x90

 

Hot Reload

Hot reload는 코드에서의 변경사항이 어플리케이션 새로고침 없이도 바로 반영하는 기능을 이야기한다.

우리가 화면에서 텍스트 변경이나 디자인을 수정했을 때 페이지 새로고침 없이도 특정 변경사항만 반영되는게 이러한 기능 덕분이다.

프런트엔드 개발에서 이제는 수정 기능을 새로고침이 되고나서야 확인할 수 있다면 그만큼 어색한 상황도 없을 것이다. 어색함 뿐만 아니라 새로고침하면서 페이지가 전체적으로 다시 그려지는걸 기다리자면.. 개발하는 시간에도 유의미한 영향을 준다.프런트엔드 개발에서 Hot Reloading은 더 이상 옵션이 아닌, 당연한 기능이 되었다.

 

여느날과 같이 개발 중, 특정 페이지에서 이상하게도 Hot Reload가 작동하지 않고 전체 페이지가 새로고침되는 현상을 경험했다.
단순히 텍스트 한 줄을 수정했을 뿐인데, 페이지가 통째로 다시 로드되니 무시할 수가 없었다.
기능을 많이 고쳐야 할 상황에서 이 현상은 생산성 저하로 이어졌고, 원인을 파악하기 시작했다.

 

 

Hot Reload가 실패하는 대표적인 케이스

아래와 같은 케이스에서 React의 Hot Reload 기능이 자동으로 비활성화된다는 것을 확인했다.

 

1. 컴포넌트 이름이 소문자로 시작할 때

아래와 같이 컴포넌트 이름이 소문자 일때 내용을 변경하면 페이지가 강제 새로고침 된다.

// ❌ 잘못된 예시
export default function myComponent() {
  return <div>Hello</div>;
}

 

위 코드처럼 컴포넌트 이름이 myComponent로 소문자로 시작하면, 수정 시 페이지가 강제로 새로고침된다.
정상적으로 Hot Reload를 사용하려면 컴포넌트 이름을 반드시 대문자로 시작해야 한다고 한다. 

이는 소문자로 되어있으면 React 컴포넌트 파일이 아니라 일반 함수로 판단해서 그렇다고 한다.

// ✅ 올바른 예시
export default function MyComponent() {
  return <div>Hello</div>;
}

 

2. React 컴포넌트와 Non-React 값을 함께 export할 때

 

아래와 같이 하나의 파일에서 React 컴포넌트와 일반 상수 값을 함께 export하면, React는 해당 모듈의 전체 변경 사항이 다른 곳에 영향을 줄 수 있다고 판단하여 전체 새로고침을 진행된다고 한다.

// ❌ Hot Reload가 비활성화되는 예시
export const API_URL = 'https://api.example.com';

export default function MyComponent() {
  return <div>Hello</div>;
}

 

 

React Fast Refresh는 React 컴포넌트만을 추적하여 변경된 부분만 빠르게 업데이트 한다.
그런데 컴포넌트 외의 일반 export가 포함된 경우, 해당 파일의 변화가 다른 모듈에 영향을 줄 수도 있다고 판단해, Hot Reload 대신 전체 페이지 새로고침을 수행하게 된다고 한다.

 

나의 경우는 위 두 번째 케이스에 해당했다.
페이지 파일에서 상수와 컴포넌트를 함께 export하고 있었고, 이로 인해 매번 페이지 전체가 리프레시되고 있었다...
컴포넌트를 분리해서 해당 이슈를 해결했다~!

 

 

외에도 새로고침 되는 케이스가 추가적으로 있으니 파악해보는것이~!

728x90
728x90

 

로딩 관련 컴포넌트를 페이지에 추가할때 보통 위와 같이 추가하기 마련이다. 

그런데 위와 같이 넣을때 에러가 발생하는 경우가 있다. 그러면 습관성 삼항 연상자를 이용해서 로딩이 아닌경우  fragement(<></>) 를 리턴하게 함으로 타입 에러를 처리하고 턴을 마친다.

 

그런데 이 날따라 (혹은 이제서야) 의문이 들었다. 아니 분명 위와 같이 작성해도 문제가 되지 않는 부분도 있는데, 왜 타입 에러가 발생하는 케이스가 생기는걸까?


 

React.Element 와 React.Node 를 먼저 잠깐 살펴보자. 이를 보통 컴포넌트 props 를 넘겨줄때 children의 타입으로 지정하면서 본적이 있을 것이다. 각각의 의미를 살짝 보자면 아래와 같다.

 

React.Element

- 앱을 구성하는 작은 블록으로 일반 JavaScript 객체 형태이다.

- JSX 문법 (<MyComponent />, <div></div>)을 사용하면 Babel과 같은 트랜스파일러가 내부적으로 React.createElement() 함수 호출로 변환하여 이 객체를 생성한다.

 

React.Node

- React 컴포넌트가 렌더링 할 수 있는 모든것.

- React Node들을 담고 있는 배열 ([<li key="1">A</li>, <li key="2">B</li>]). React는 배열 내부의 노드들을 순서대로 렌더링한다.

 

쉽게 말해서 <div> 처럼 태그로 이루어진 컴포넌트 들은 Element 라고 할 수 있고,

이를 포함해서 단순한 number, string 등 화면에 그릴 수 있는 모든 값이  Node에 포함된다.

 

이제 다시 처음의 문제로 돌아가보자.

위 코드가 적혀있는 컴포넌트 children의 타입은 React.Element로 선언되어 있다. 

로딩중이라면 <LoadingScreen> 이라는 Element를 정상적으로 반환하겠지만 로딩중이 아니면 null 값이 리턴이 되는데 이는  Element범위에 속하지 않는다. 이에 타입에러가 발생했던 것이다. 

리턴되는 children의 타입을 React.Node 로 수정하면 null 이 리턴되더라도 문제가 없기에 타입에러는 사라지게된다!

 

추가적으로 React 자체 타입정의(@types/react)에서도 PropsWithChildren 유틸리티 타입을 사용하면 children의 타입이 ReactNode로 되어있는것을 확인할 수 있다. ReactNode를 사용하는게 표준으로 봐도 무방하지 않나 싶다. 

 

앞으로 children 의 타입은 ReactNode 를 사용하자~!

 

 

728x90
728x90

pm2 를 쓰고 있다면 최근에 빌드하면서 위와 같은 에러를 마주했을 수도 있다.

 RUN yarn && yarn global add pm2....

 

위와 같은 명령어로 실행시키면 저번주만해도 문제 없이 잘 진행되었지만 오늘 갑자기 아래와 같은 오류가 발생했다.

 

 

- error pm2@6.0.5: The engine "node" is incompatible with this module. Expected version ">=16.0.0". Got "14.21.3"

- error Found incompatible module

 

 

일단 코드쪽에서 버전을 변경한게 없어서  서버 관리자분께 혹시 버전 변경된게 있나 문의를 넣었지만 따로 변경된 부분은 없었다.

그러다가 pm2 가 최근에 새로운 버전이 나왔다는 것을 확인했다.

 

https://www.npmjs.com/package/pm2/v/2.0.15?activeTab=versions

 

pm2

Production process manager for Node.JS applications with a built-in load balancer.. Latest version: 6.0.5, last published: 9 days ago. Start using pm2 in your project by running `npm i pm2`. There are 1737 other projects in the npm registry using pm2.

www.npmjs.com

 

기존에는 5.4.3을 사용했는데 오늘 날짜 기준으로 9일전에 새로운 6.0.5 버전이 출시된것.. 하지만 이 6버전은 node가 14인 환경에서는 정상적으로 작동하지 않아서 해당 에러가 발생했던 것이다.

 

@근데 왜 내 버전은 갑자기 5.4.3에서 6.0.5 버전으로 변경되서 빌드가 시작된것일까?

 

그건 명령어를 yarn global add pm2 로 해두었기 때문이다.

 

global이 들어가 있기 때문에 최신 버전을 받아서 진행되는데, 이에 빌드할때 최신 버전인 6.0.5가 사용된것이다. 그렇다면 해당 명령어만 수정해준다면 해결될 것이다. 나의 경우 직전의 버전까지 정상작동을 확인했기 때문에 아래와 같이 pm2 설치시에 버전을 특정해주었다. 

 

$ yarn global add pm2@5.4.3

 

 

pm2가 아니더라도 global로 진행되는게 있다면 이런 문제가 발생할 수 있다는 것을 인지해두고 사용을 지양해야하지 않나 싶었다.

728x90
728x90

api의 결과물이 CORS라면, 프로 출신들은 다음의 대사가 머릿속에 떠오른다.

 

"백엔드에게 CORS 관련 설정을 추가해달라고해야지~ 해줘~"

 

하지만 그에 대한 대답이 다음과 같다면 어떨까?

 

"이미 cors 설정 다 되어있습니다."

 

"what?????????????"

 


 

 

특정 api 에서 cors가 발생하고, 관련 확인 요청을 드렸는데 위와 같은 대답이 돌아왔다.

생각해보니 같은 엔드 포인트를 가지고 있는 다른 api 들은 잘 사용하고 있었다.

그런데 왜 유독 이 api에서만 갑자기 cors 에러가 발생한것일까?

 

결론 부터 말하자면 보내는 데이터의 크기가 문제였다.

사용하는 Django의 POST요청 최대 크기 기본값은 2.5MB 였는데, 보내는 데이터가 사진으로 4MB를 넘어버렸다.

이런 상황에서 아래 두 원인중 하나로 인해서 에러가 발생했던 것이다.

 

1.  이에 서버는 400이나 413 을 응답했으나 브라우저에서 구분을 못해서 해당 CORS오류가 발생 가능성

2.  크기가 너무 커서 OPTION요청을 무시해버렸고 이 때문에 CORS 오류 처럼 보이는 메세지가 나왔을 가능성

 

해결 방법은 행복(?)하게도 백엔드에게 다시 요청드리면 된다.

 

"요청 허용 용량을 늘려주세요~"

 

그러면 백엔드에서 아래와 같은 설정을 통해 허용 용량을 늘려줄것이다.

그러고 나면 문제 해결!

 

DATA_UPLOAD_MAX_MEMORY_SIZE = {허용 사이즈}

 

 

CORS에러가 발생했을때 원인이 크기에도 있는지 상상도 못했는데,

보내는 파일이 크다면 한번 쯤 생각해보는것으로!

728x90

+ Recent posts