이 durable object는 가만히 없으면 사라짐
저장하려면 durable objects의 저장소를 사용해야 함.

 

웹소켓 페어란?
왼쪽 소켓은 서버, 
오른쪽 소켓은 브라우저
가운데 실은 웹소켓 프로토콜
REAL TIME MESSAGE 

브라우저가 웹 소켓 연결 보내면 백엔드가 요청을 받음.
백엔드는 한쌍의 웹소켓을 만들고 처음꺼는 유저주고 다음꺼는 자기가 받음

왼쪽만 커넥트 누른 상태. 오른쪽은 초기상태
오른쪽도 connect 누르면 기존 내용 불러옴

그러나 cloudflare에서 durable object는 유료가 되었다.

일반적으로 state를 가질 수 없다.
다른 workers간에 공유하고 싶은 데이터의 한 종류
durable objects없이는 불가능해.

해당 코드는 cloudflare의 지역에 복사되어 퍼짐.
근데 한국의 cloudflare접속자와, 독일의 cloudflare접속자 들이 해당 웹사이트 접속하면
해당 지역의 코드가 각각 실행됨. 다른 컴퓨터에서 실행되기 때문에 state를 유지하지 못함
cloudflare workers에 있는 state가 다른 지역으로 복제 되지 않기 때문.
그냥  cloudflare 한정된 얘기임
리턴하면 코드가 죽음.

KV database에 저장하면 해결되긴 함.

모든 사람이 한 방의 채팅방에 연결 되어있다면?
worker코드의 모든 실행들 간에 공유되는  state를 저장 할 수 있는 무언가가 필요 함.
그게 durable object.

durable object와 javascript 클래스를 작성하면, 그 자바스크립트 클래스가 cloudflare에 의해 기억 됨!
이 클래스가 cloudflare메모리로 가게 되고 모든 worker들이 접근 가능하게 되겠지.


carrot market에서 채팅을 할 수 없었던 이유는
next.js에서 실행되는 모든 함수들이 우리가 컴퓨터에 접근 권한이 없는 serverless환경에서 실행되기 때문.
그 환경에서 state는 지속 될 수가 없어. 항상 새 state가 되는거지. durable object는 채팅에 연결된 모든 사람을 유지 시키는 것.

방문자 카운팅 하는 법
홈 경로로 오면 html파일을 주고, 
그 안에 있는 src가 /visit?page=lalala인 이미지를 렌더링 하기 위해
브라우저는 src를 찾아서 request를 하게 되는데
그러면 해당 url(/visit)에서는 DB로 request hit을 했다고 알려준다.

이메일 읽었는지 판단하는 원리
이런 식으로 상대가 메일을 봤는지 안봤는지 확인 할 수 있다.
보이지 않는 이미지 태그를 심어서 메일을 보내면
메일을 읽었을 때 브라우저가 해당 url을 hit하게 됨.
그럼 서버에서는 email이 열렸는지 알 수 있음.

22.4 Preview Deployments

바로 배포 시키기 전에 preview 할 수 있어야 하겠지?
깃에서 브랜치 따서 push 하면 알아서 배포가 된다.
일단  enter-message라는 이름의 깃 브랜치를 따자.

git checkout -b enter-message

그리고 코드 수정하고 바로 커밋하면

git add .
git commit -m "New Welcome Msg"
git push origin enter-message

브랜치에서 보낸 코드가 빌드 되고, 볼 수 있는 preview 도메인이 생긴다.
그리고 prod로 배포 하려면
promote to production 누르면 끝!



22.5 Limits in Vercel
https://vercel.com/docs/concepts/limits/overview

<Image> 태그 사용할 때만 해당.

Edge Middleware Invocations는 middleware.ts임
한달에 100만회로 제한. 알아서 잘 활용해라.

역시 제한이 있다.

아래로 가면 내 앱의 사용현황을 볼 수 있다.
https://vercel.com/dashboard/usage

근데 serverless function은 revalidate할 때도 카운팅 되기 때문에 조심해라.
https://vercel.com/docs/concepts/limits/usage#invocations

Vercel은 NextJS앱을 배포하는 플랫폼에선 압도적 1위임.

두가지 방식이 있다. NextJS를 활용 하는.
1. 풀스택 프레임워크 - api route, 미들웨어, 서버컴포넌트,image컴포넌트 등 전부 활용
2. getStaticProps 만 사용 - HTML을 생성하는 정적사이트 생성기(SSG)로 사용

2번의 경우 어디에 배포해도 상관 없음. 
1번으로 활용한 경우는 배포할 곳이 Vercel밖에 없음.Netlify, cloudflare, github pages, heroku도 안됨.
NextJS를 만든 곳이니까. 

이제 배포를 해보자.
1. Vercel 가입(github으로 가입하면 편함)하고 https://vercel.com/dashboard로 가자.
create a New Project 누르고

2. git을 import한다.

3. .env에서 사용하던 변수들을 아래에 입력한다.

일단 저기에 DATABSE_URL이 들어가야 하는데
Planetscale가서 보자. connect버튼 누르고. Prisma를 선택하고. 아래 스트링을 넣음 된다.

4. 그리고 빌드하면 에러가 난다.
환경 변수들 다 추가해서 고쳐주고,
빌드가 다 돼도 에러난다.
Uncaught SyntaxError: Unexpected token '<'
Uncaught SyntaxError: Unexpected token '<'
js,css로딩이 안된다. 미들웨어의 문제인듯하다.
stackoverflow 검색결과 middleware.ts파일에 아래를 넣어주니 해결 되었다.

export const config = {
  matcher: "/",
};

the problem is Next.js is making some request to /_next/* and you redirect request to the login page, those are requests are needed and are never finished. You need to avoid redirect any requests made to /_next/*
Next.js가 보내는 /_next/라는 리퀘스트를 내 코드가 login페이지르 리다이렉트 시켜서 그렇단다.
https://stackoverflow.com/questions/73229148/uncaught-syntaxerror-expected-expression-got-while-using-next-js-middlewar






planet scale에서 Database를 dev와 prod로 나누어보자.
prod 브랜치로 promote하면 아래 3가지 좋은 점이 있다.
1, 스키마 직접수정 불가
2. 가용성 증대
3. 자동백업

그리고 브랜치를 만들고 연결해보자.

pscale connect carrot-market indexes
//indexes는 새 브랜치 이름

To update your main branch, you can make schema changes to this branch. Once you're ready, open a deploy request with your changes.

브랜치 바뀌면 데이터도 사라짐. 같은 스키마를 갖고 있지만 data는 다르다.

21 FUTURE: REACT 18
21.0 Suspense
21.1 Server Components
21.2 Promise Me Your Love
21.3 Throwing Our Promise
21.4 Parallelism
21.5 Recap

현재는 SWR, Prisma와 사용불가 (alpha에서)

페이지에 대해 신경 쓸 필요없다. 컴포넌트에 대해 신경 쓴다.
몇몇 컴포넌트를 서버에서 만들 수 있다.
SSR이 아니다. SSR은 페이지에 접속하면 페이지가 서버에서 렌더링이 되는거.
페이지 전체 로딩하는데 시간이 많이 걸림. 

서버컴포넌트를 사용하면 페이지 접근 시
클라이언트에서 렌더링된 모든 컴포넌트를 볼 수 있음. 
뒤에서 서버가 리액트 서버 컴포넌트를 렌더링 한다.
렌더링이 끝나면 HTTP를 이용해 렌더링 결과물을 보내준다.


브라우저 상단의 로딩은
서버에서 브라우저 페이지로 다 전송했는지 알려주는 로딩표시


핵심은 컴포넌트 단위로 서버에서 렌더링 할지 클라이언트에서 할지 고를 수 있게된다는 것.
컴포넌트 단위로 SQL을 사용 할 수 도 있다는 것.
https://reactjs.org/blog/2022/03/29/react-v18.html

server component 아직도 개발중.
next.js 13.0에서는 이름을 xxx.server.js로 짓는다고 servercomponent 안됨.
/app 폴더 안에 있는 컴포넌트만 server component임.
https://nextjs.org/blog/layouts-rfc#react-server-components

서버쪾에서 렌더링을 하니까, 유저쪽에서 처리해야 하는 일은 적어짐.
큰 javascript 들 import할일이 적게 됨.
즉 서버컴포넌트 사용하면 서버에서 렌더링이 이뤄지고 결과물만 프론트로 스트림 됨

코인 list를 주는  API를 콜하고, 불려진 코인의 가격을 알아오는 API를 또 각 코인마다 부를 경우를 예를 들어보자.

CoinsServer라는 서버컴포넌트는 그 안에서 List컴포넌트를 불러온다.
여기서 일단 1차 로딩이 되면
List 컴포넌트 안의 Coin 컴포넌트에서 각 코인의 id를 사용해 가격을 불러오는 수십번의 api콜을 한다.
그리고 각 코인들은 로딩이 되는 순서대로 `Coin ${Coin.name} is loading`에서 각자의 가격을 보여주게 된다.

Suspense는 코드에서 로딩 상태를 나타내는 부분을 제거할 수 있게 해주는 API다.
코드에서 로딩 상태에 대해 신경쓰지 않아도 유저가 로딩 상태 화면을 볼 수 있는것.

getStaticProps, getStaticPaths, getServerSideProps와는 사용 못함.
getStaticProps에는 로딩화면이 없으니까!

그러니 위 props나 nextjs를 사용하지 않는 곳에 사용하면 좋음.

<SWRConfig
      value={{
        suspense: true,
      }}
    >

suspense를 사용하면, SWR을 사용한 컴포넌트를 찾는다.그리고 그 컴포넌트는 로딩이 완료 될 때 까지 보이지 않는다.
그래서, header,footer같은 곳에 SWR을 쓰면 로딩 할 때 전체 화면안보이게 됨.
그래서 컴포넌트 추출해서 그곳에서 SWR써라.

<Layout hasTabBar title="나의 캐럿" seoTitle="Profile">
    <div className="px-4">
      <Suspense fallback="Loading Mini Profile">
        <MiniProfile />
      </Suspense>
	</div>
</Layout>

next.js에서 Suspense를 지원하니 저렇게 쓰는거고, 
다른 라이브러리에서는 다르게 써야 할 것이야.

+ Recent posts