Next.js에서 Qwik로 전환한 나의 이야기

Next.js에서 Qwik 및 Qwik City로 마이그레이션하는 두 주간의 여정

시작하기 전에: 결론부터 말하자면

전체 이야기를 건너뛰고 결과만 보고 싶다면 여기 있습니다:

  • flaming.codes는 처음부터 다시 작성되었으며(이제부터 v2로 불리게 됩니다), 기존에는 Next.js를 사용했지만 현재는 QwikQwik City를 기반 프레임워크로 사용하고 있습니다.
  • 관련 없는 3자 CMS 및 캐싱 계층의 모든 의존성을 제거하고, 모든 컨텐츠(포스트, 카테고리, 에셋 등)를 Github 레파지토리에서 직접 호스팅합니다.
  • v1 버전의 flaming.codes를 유지하는 일이 많은 작업이었기 때문에 이런 변화가 이루어졌습니다 - CMS(Sanity)를 업데이트 할 때 여러 가지를 다시 써야 했을 때 마지막 한계에 도달했습니다.
  • 구글 번역을 통한 번역 작업 등을 포함한 v1 번역 컴포넌트는 순수 마크다운 콘텐츠와 OpenAI의 GPT-4로 대체되었습니다.
  • 아직 TTS(Text-to-Speech) 기능을 구현하지는 않았지만, 조만간 OpenAI의 Whisper 모델을 사용하여 구현할 계획입니다.
  • flaming.codes는 여전히 Vercel에서 호스팅되지만, 이제 Edge Functions을 사용하여 사이트를 제공하며, Qwik City에서 현재 제공하는 배포 어댑터가 없기 때문에 Build Output API 대신 사용합니다.
  • 디자인 역시 업데이트되어 이제 Windy Radix Colors를 사용하여 Tailwind 클래스로 Radix Colors를 사용할 수 있습니다.

flaming.codes version 2 start page

CMS의 종말, CMS 만세

v2 flaming.codes를 작성한 주된 이유는 서비스 의존성을 줄이기 위함이었습니다:

  • CMS(및 CDN)를 제거하고 모든 컨텐츠(포스트, 카테고리, 에셋 등)를 직접 레파지토리에서 관리 및 호스팅하며 오픈 소스화합니다.
  • 이러한 전환의 일환으로, 더 이상 필요하지 않은 CMS 컨텐츠의 캐싱 계층을 제거합니다.
  • 구글 번역 및 마이크로소프트 텍스트-to-스피치를 OpenAI의 API로 대체합니다.

강력한 CMS처럼 Sanity와 그 동적 쿼리 빌더로부터 벗어나는 것은 (가벼운) 콘텐츠 관리를 직접 구현해야 한다는 비용이 발생합니다. 저는 프로젝트의 핵심 부분을 업데이트하고 유지하는 것에 신경 쓰고 싶지 않습니다. 저의 목표는 한 해 동안 포스트를 작성하지 않더라도 이 솔루션이 작동하는 것입니다. 왜냐하면 유일한 요구 사항은 레포를 열어 글을 쓰고 메인에 변경 사항을 푸시하여 새로운 배포를 트리거하는 것이어야 하기 때문입니다.

GitHub 프로젝트 루트의 /cms 디렉토리에서 소스 코드를 직접 확인할 수 있습니다. 이것은 상당히 잘 작동하며, 단순하고 완전히 독립적이며, 추가 계정 및 CMS 로그인이 필요하지 않습니다. 이제 마크다운을 모든 콘텐츠에 사용할 수 있어 Sanity의 맞춤형 편집기보다 더 쉽게 작성하고 관리할 수 있습니다. 에디터 스크립트를 실행할 때 실시간으로 변경 사항을 볼 수 있는 라이브 리로드 옵션을 추가했으며, 필요한 경우 한 번에 여러 언어로도 볼 수 있습니다.

CMS에 대한 자세한 내용은 별도의 포스트에서 다루겠습니다.

Next.js 대신 Qwik 및 Qwik City를 선택한 이유

Qwik와 그 풀스택 프레임워크인 "Qwik City"는 처음부터 나에게 매우 흥미로워 보였습니다: 실제로 필요할 때까지 모든 JS를 자동으로 느리게 로드하며, 하이드레이션 없이도 로딩됩니다. flaming.codes의 컨텍스트에서, 이러한 아키텍처로 인한 이득은 점차 감소하고 있습니다. 왜냐하면 내 사이트는 기본적으로 블로그이기 때문입니다. 웹 앱의 구성 요소와 상호 작용이 더 많을수록 Qwik을 사용함으로써 얻게 되는 개선 사항은 상당히 클 겁니다. 그럼에도 불구하고, 저는 호기심이 많았고 직접 경험해보고 싶었습니다.

Next.js와 비교한 Qwik의 i18n

flaming.codes는 영어를 포함한 14개 언어로 번역됩니다. 2023년 초 Qwik을 처음 본 후 (실제 v2 리라이트를 하기 약 10개월 전), i18n을 위한 실질적인 해결책이 없다고 느꼈으며, 초기 테스트를 넘어 실제 작업이 소강상태에 접어들었습니다.

12월 다시 살펴보았을 때, qwik-speak은 flaming.codes의 번역을 가능하게 하는 데 필요한 솔루션이었으므로, 오래된 코드베이스를 다시 먼지 털고 리라이트를 시작했습니다.

새로운 번역기

이전 스택은 Google Translate API를 사용했습니다. 이는 저에게 꽤 잘 맞았지만, 전체 컴포넌트에는 다소 복잡성이 있었습니다:

  • 원문의 콘텐츠가 Sanity CMS에서 가져와져 문서로 파싱되었고 중간 조각으로 나뉘었습니다.
  • 각 조각이 번역 가능한 대상 언어로 번역되었습니다.
  • 번역된 조각은 원래의 콘텐츠를 포함하여 포맷팅에 대한 복원이 가능하도록 다시 구성되어 프론트엔드에서 사용할 수 있었습니다.

꽤 잘 작동했지만, 코드를 읽고 유지하는 것은 상대적으로 어려웠습니다.

flaming.codes는 이제 모든 콘텐츠를 번역하기 위해 OpenAI를 사용합니다. 전체 설정은 훨씬 더 간단합니다:

  • 새로운 기사는 순수한 마크다운으로 작성됩니다.
  • 기사는 OpenAI에 전송되어 전체적으로 번역됩니다.
  • LLM은 충분히 지능적이어서 중요한 부분만 번역되지만, 전체 frontmatter와 같은 부분은 번역되지 않습니다(어떤 필드가 절차의 대상이 되어서는 안된다는 점을 LLM에게 안내하는 프롬프트를 제공합니다).

Vercel에서의 배포

Qwik City는 정적 사이트(SSG)로 내보낼 수 있지만, 이는 동적 엔드포인트를 사용할 수 없다는 것을 의미하므로 flaming.codes는 계속해서 Vercel을 통해 배포 및 호스팅하기 위해 "Vercel Edge" 어댑터를 사용하고 있습니다. 나는 Vercel의 "Build Output API"도 어댑터로 사용할 수 있기를 바랍니다, 하지만 지금으로써는 충분합니다.

flaming.codes는 이전에 Build Output API를 사용했는데, 이는 서버 측 코드가 Node.js-API를 사용했다는 것을 의미합니다 - Vercel Edge에서는 더 이상 가능하지 않습니다. 왜냐하면 이것은 웹과 Node.js API의 조금 이상하고 혼란스러운 혼합이기 때문입니다. 이로 인해 호환성을 위해 일부 구성 요소를 다시 작성해야 했습니다.

AI와 투명성

v2의 초기 릴리스 준비가 되어있지 않지만, 나는 새로운 기사의 메타데이터 속성을 업데이트하여 AI를 사용하여 만든 기사의 어떤 측면이 있는지에 대한 정보를 더 많이 포함시킬 것입니다.

동일한 조치로, 더 많은 투명성을 확보하기 위해 사이트의 분석을 공개할 것입니다. flaming.codes는 기본 사용 집계를 위해 프라이버시를 존중하는 분석 서비스인 Plausible.io를 사용합니다.

새로운 디자인

flaming.codes version 2 article hero

전면적인 리라이트의 일부로 디자인도 조금 업데이트했습니다. 대부분의 페이지는 비슷하지만, 신선한 느낌의 새 옷을 입었습니다.

flaming.codes version 2 article metadata fields

새로운 색상 + 라이트 및 다크 모드

Windy Radix Colors 덕분에, 라이브러리가 모든 색상 변형을 빛과 어둠의 모드 모두에 제공하기 때문에 라이트 및 다크 모드 지원을 쉽게 구현할 수 있었습니다.

flaming.codes version 2 all posts page in dark mode

flaming.codes version 2 all posts page in light mode

이제 저는 Radix Color 팔레트를 Tailwind 플러그인으로 사용하고 있으며, 이것은 신중하게 선택된 색상 변형뿐만 아니라 라이트/다크 모드를 쉽게 지원합니다. 또한, Qwik에서 사용할 수 있는 라이브러리로 Lucide Icons를 전환했습니다. 참고를 위해, 여기 옛 디자인의 몇 가지 스크린샷입니다:

flaming.codes version 1 start page

flaming.codes version 1 article hero

결론 및 다음 단계

처음 출시된 이후로 v1 flaming.codes가 저에게 매우 잘 맞았지만, 다른 서비스에 대한 의존도를 간소화해야 할 필요성을 느꼈습니다.

리라이트를 완료하는 데 약 2주가 걸렸습니다. 콘텐츠 관리가 훨씬 더 단순해지고, 나에게 과도한 비용을 부담시키지 않도록 도와줄 것입니다.

flaming.codes v2는 출시 시 v1과 동등한 기능을 갖추지 못했지만, 향후 몇 주 안에 좋아요/싫어요 버튼이나 TTS(Text-to-Speech) 기능과 같은 누락된 기능을 추가할 것입니다.