Quickstarters
How to Build a Qwik Frontend and Connect It to a Backend?
31 분
이 튜토리얼에서는 qwik을 사용하여 할 일 목록 애플리케이션을 구축하고 이를 back4app에서 제공하는 강력한 백엔드에 연결합니다 이 가이드는 qwik의 재개 가능성과 지연 로딩 기능을 활용하면서 관리되는 백엔드와 필수 crud(생성, 읽기, 업데이트, 삭제) 작업을 통합하고자 하는 개발자를 위해 맞춤 제작되었습니다 마지막에는 현대적인 qwik 프론트엔드와 back4app의 신뢰할 수 있는 백엔드 서비스를 결합하는 방법을 보여주는 완전한 기능의 애플리케이션을 갖게 됩니다 풀스택 애플리케이션을 구축하는 것은 백엔드 설정, 데이터베이스 관리, 인증 및 배포가 포함되기 때문에 도전적일 수 있습니다 이러한 작업을 간소화하기 위해 우리는 back4app을 사용합니다— 확장 가능한 백엔드 서비스(baas) 솔루션—그래서 호스팅, 데이터베이스 및 api를 관리하는 동안 qwik 앱 구축에 집중할 수 있습니다 back4app은 즉시 사용할 수 있는 nosql 데이터베이스, 인증, 서버 측 로직을 위한 cloud code 및 원활한 sdk 통합을 포함한 포괄적인 백엔드 서비스 모음을 제공합니다 컨테이너화된 배포 지원 덕분에 현대적인 풀스택 애플리케이션에 탁월한 선택이 됩니다 이 도구들을 손쉽게 사용할 수 있으므로 서버 인프라를 관리하는 부담 없이 애플리케이션을 신속하게 개발하고 배포할 수 있습니다 주요 내용 이 튜토리얼을 따라하면 다음을 배울 수 있습니다 최신 qwik 프로젝트 초기화 애플리케이션의 데이터를 관리하기 위해 백엔드 서비스를 통합 인터랙티브 사용자 인터페이스를 위한 필수 crud 작업 구현 배포 완전 기능을 갖춘 할 일 목록 애플리케이션 을 컨테이너화된 워크플로우를 사용하여 back4app에 전제 조건 시작하기 전에 다음을 확인하세요 node js 및 npm nodejs org https //nodejs org/ 에서 최신 lts 버전을 설치하고 node v 및 npm v 로 확인하세요 기본 qwik 지식 qwik의 구성 요소, 신호( usesignal ) 및 재개 가능성 개념에 대한 친숙함이 권장됩니다 qwik이 처음이라면 먼저 문서를 검토하세요 back4app 계정 back4app https //www back4app com/ 에 가입하여 백엔드 서비스를 설정하고 관리하세요 이러한 전제 조건이 갖춰지면 프로젝트를 설정하고 빌드를 시작할 준비가 된 것입니다 프로젝트 설정 로컬 개발 환경을 설정하고 qwik 프로젝트를 초기화하는 것으로 시작하세요 다음이 설치되어 있는지 확인하세요 node js (lts 버전) node v npm v qwik cli를 사용하여 새로운 qwik 프로젝트를 생성하세요 다음 명령어를 실행하세요 npm create qwik\@latest cli가 제공하는 프롬프트에 답하세요 프로젝트 이름을 todo app으로 지정하거나 원하는 이름으로 변경하세요 프로젝트 디렉토리로 이동하세요 cd todo app 설정을 확인하기 위해 개발 서버를 시작하세요 npm start 이제 qwik 앱이 로컬에서 실행되고 있어야 합니다 제공된 url을 브라우저에서 열어 확인하세요 다음으로, 데이터 저장 및 api 상호작용을 관리하기 위해 back4app에서 백엔드를 구성할 것입니다 할 일 백엔드 만들기 back4app은 parse 로 구동되는 완전 관리형 백엔드 서비스를 제공합니다 이 서비스는 기본적으로 nosql 데이터베이스, 인증, 클라우드 코드 및 자동 생성된 api를 제공합니다 이 섹션은 할 일 항목을 저장하기 위한 task 데이터 모델을 생성하고 이를 qwik 프론트엔드와 연결하는 방법을 안내합니다 백엔드 애플리케이션 설정하기 로그인 하여 back4app 대시보드 https //www back4app com/ 를 클릭하고 "새 앱 만들기" 애플리케이션 이름 지정하기 (예 todoqwikapp ) 및 nodejs/parse 를 백엔드 유형으로 선택합니다 생성 후, "데이터베이스" > "브라우저" 클릭하여 "클래스 만들기" 를 선택하고 "사용자 정의" 클래스를 task 로 이름 짓고 클래스 수준 권한 을 설정하여 공개 읽기 및 쓰기를 허용합니다 (이 설정은 나중에 수정할 수 있습니다) task 클래스에 다음 필드를 추가합니다 제목 (문자열) – 작업의 제목 설명 (문자열) – 작업에 대한 세부정보 완료됨 (부울) – 작업이 완료되었는지 여부를 나타냅니다 마감일 (날짜) – 작업의 마감일 클릭하여 "저장" 하여 스키마를 완료합니다 qwik과 back4app 통합하기 qwik 프로젝트에 back4app을 통합하려면 parse javascript sdk sdk를 npm을 통해 설치하세요 npm install parse sdk를 구성하려면 application id 와 javascript key 로 초기화하십시오 이러한 자격 증명은 app settings > security & keys 에서 back4app 대시보드에서 가져옵니다 구성 파일을 생성하십시오 (예 src/lib/parse js ) 및 다음을 추가하십시오 import parse from "parse/dist/parse min js"; const parse app id = 'your application id'; const parse js key = 'your javascript key'; const parse server url = 'https //parseapi back4app com/'; parse initialize(parse app id, parse js key); parse serverurl = parse server url; export default parse; 이제 이 구성을 qwik 구성 요소 및 경로에서 가져와 백엔드와 상호 작용할 수 있습니다 qwik으로 프론트엔드 개발하기 이제 백엔드가 연결되었으므로 qwik을 사용하여 할 일 목록 애플리케이션의 사용자 인터페이스를 구축하세요 qwik 신호를 사용하여 상태를 관리하면서 작업을 추가, 표시, 업데이트 및 삭제하는 구성 요소를 생성할 것입니다 구성 요소 정리하기 애플리케이션에는 다음과 같은 주요 구성 요소가 포함됩니다 taskform tsx – 새로운 작업을 추가하는 구성 요소입니다 tasklist tsx – 모든 작업을 표시하고 작업을 완료로 표시하거나 삭제하는 제어를 제공하는 구성 요소입니다 taskitem tsx – 개별 작업을 나타내며 완료 전환 또는 제거 작업을 수행하는 구성 요소입니다 src 안에 components 폴더를 만들고 다음 파일을 추가하세요 mkdir src/components touch src/components/taskform tsx src/components/tasklist tsx src/components/taskitem tsx qwik 신호로 상태 관리하기 qwik의 usesignal 을(를) 사용하여 반응형 상태 관리를 수행하십시오 기본 페이지(예 src/routes/index tsx 에서 상태 및 데이터 가져오기를 다음과 같이 설정하십시오 import { component$, usesignal, usevisibletask$, $ } from '@builder io/qwik'; import parse from ' /lib/parse js'; import taskform from ' /components/taskform'; import tasklist from ' /components/tasklist'; export default component$(() => { const tasks = usesignal< { id string; createdat string; updatedat string; title string; description string; completed boolean; }\[] \>(\[]); const fetchtasks = $ ( async () => { try { const task = parse object extend("task"); const query = new parse query(task); const results = await query find(); tasks value = results map(task => ({ id task id ?? '', createdat task createdat ? task createdat toisostring() '', updatedat task updatedat ? task updatedat toisostring() '', title task get('title') ?? '', description task get('description') ?? '', completed task get('completed') ?? false, })); } catch (error) { console error("error fetching tasks ", error); } }); usevisibletask$(async () => { await fetchtasks(); }); return ( \<div class="container"> \<h1>to do list\</h1> \<taskform ontaskadded$={fetchtasks} /> \<tasklist tasks={tasks value} ontaskschange$={fetchtasks} /> \</div> ); }); 작업 양식 구성 요소 만들기 에서 src/components/taskform tsx , 작업을 추가하기 위한 폼 컴포넌트를 만듭니다 폼 입력을 위해 qwik의 반응형 신호를 사용하세요 import { component$, usesignal, $, qrl } from '@builder io/qwik'; import parse from ' /lib/parse js'; interface taskformprops { ontaskadded$ qrl<() => void>; } export default component$((props taskformprops) => { const title = usesignal(''); const description = usesignal(''); const handlesubmit$ = $(async (e event) => { e preventdefault(); try { const task = parse object extend("task"); const task = new task(); task set("title", title value); task set("description", description value); task set("completed", false); await task save(); title value = ''; description value = ''; return true; } catch (error) { console error("error adding task ", error); return false; } }); return ( \<form preventdefault\ submit onsubmit$={async (event) => { const success = await handlesubmit$(event); if (success) { await props ontaskadded$(); } }} \> \<input type="text" placeholder="task title" value={title value} oninput$={(e) => title value = (e target as htmlinputelement) value} required /> \<input type="text" placeholder="description" value={description value} oninput$={(e) => description value = (e target as htmlinputelement) value} required /> \<button type="submit">add task\</button> \</form> ); }); 작업 목록 및 항목 컴포넌트 구축 에서 src/components/tasklist tsx , 작업 목록을 렌더링합니다 import { component$ } from '@builder io/qwik'; import taskitem from ' /taskitem'; interface task { id string; title string; description string; completed boolean; } interface tasklistprops { tasks task\[]; ontaskschange$ () => void; } export default component$((props tasklistprops) => { return ( \<div> {props tasks length === 0 ? ( \<p>no tasks available\</p> ) ( props tasks map(task => ( \<taskitem key={task id} task={task} ontaskschange$={props ontaskschange$} /> )) )} \</div> ); }); 에서 src/components/taskitem tsx , 개별 작업을 위한 구성 요소를 생성하고 완료 전환 또는 작업 삭제 작업을 추가합니다 import { component$, $ } from '@builder io/qwik'; import parse from ' /lib/parse js'; interface task { id string; title string; description string; completed boolean; } interface taskitemprops { task task; ontaskschange$ () => void; } export default component$((props taskitemprops) => { const handletoggle = $(async () => { try { const query = new parse query("task"); const tasktoupdate = await query get(props task id); tasktoupdate set("completed", !props task completed); await tasktoupdate save(); props ontaskschange$(); } catch (error) { console error("error updating task ", error); } }); const handledelete = $(async () => { try { const query = new parse query("task"); const tasktodelete = await query get(props task id); await tasktodelete destroy(); props ontaskschange$(); } catch (error) { console error("error deleting task ", error); } }); return ( \<div class={`task item ${props task completed ? "completed" ""}`}> \<h3>{props task title}\</h3> \<p>{props task description}\</p> \<button onclick$={handletoggle}> {props task completed ? "undo" "complete"} \</button> \<button onclick$={handledelete}>delete\</button> \</div> ); }); 애플리케이션 스타일링 기본 스타일링을 추가하기 위해 src/global css 파일을 생성하세요 / src/global css / container { max width 600px; margin 40px auto; padding 0 20px; text align center; font family sans serif; } container h1 { margin bottom 20px; } form { display flex; flex direction column; align items center; gap 10px; margin bottom 20px; } form input\[type="text"] { width 80%; max width 400px; padding 8px; box sizing border box; font size 1rem; } form button { padding 8px 16px; cursor pointer; font size 1rem; border none; background color #eaeaea; transition background color 0 2s ease; } form button\ hover { background color #ccc; } container p { font size 1rem; } task item { display flex; flex direction column; align items center; justify content center; gap 12px; border 1px solid #ccc; border radius 6px; padding 15px; margin 10px 0; background color #fafafa; text align center; transition background color 0 2s ease; } task item completed h3, task item completed p { text decoration line through; color #888; } task item h3 { margin 0; font size 1 1rem; } task item p { margin 0; font size 1rem; } task item button { padding 6px 12px; border none; background color #eaeaea; cursor pointer; font size 0 9rem; } task item button\ hover { background color #ccc; } @media (min width 600px) { task item { flex direction row; } } 루트 파일에 전역 스타일을 가져옵니다 (예 src/root tsx ) import " /global css"; ui 마무리 당신의 qwik 할 일 목록 애플리케이션은 이제 back4app과 통합된 동적 프론트엔드와 사용자 정의 스타일을 갖추고 있습니다 이 앱은 작업을 추가, 표시, 업데이트 및 삭제할 수 있으며 프론트엔드와 백엔드 간의 원활한 통신을 보장합니다 다음으로, back4app의 웹 배포 플랫폼을 사용하여 qwik 애플리케이션을 배포합니다 back4app 웹 배포에서 프론트엔드 배포하기 back4app 웹 배포는 애플리케이션 호스팅을 위한 완전 관리형 컨테이너화된 환경을 제공합니다 docker 기반 배포를 통해 qwik 앱을 패키징하고 원활하게 배포할 수 있습니다 express 서버 어댑터 추가하기 qwik은 특정 대상을 위한 배포 어댑터를 구성할 수 있게 해줍니다 우리는 프로덕션에서 프로젝트를 제공하기 위해 express 어댑터를 추가할 것입니다 어댑터 설치 npm run qwik add 그런 다음 어댑터 node js express 서버 를 선택하고 설치를 확인합니다 이렇게 하면 readme가 업데이트되고 package json에 새로운 배포 스크립트가 추가됩니다 시작 스크립트 업데이트 package json 을 열고 시작 스크립트를 다음과 같이 변경합니다 "start" "node server/entry express" 필요한 경우 별도의 개발 스크립트를 유지할 수 있습니다 이렇게 하면 프로젝트가 프로덕션 빌드를 제공하기 위해 express를 사용하도록 보장합니다 프로덕션을 위한 qwik 구성하기 다음과 같이 프로덕션 준비가 완료된 qwik 사이트를 빌드합니다 npm run build 앱을 위한 dockerfile 만들기 프로젝트 루트에 dockerfile 을 생성하여 qwik 애플리케이션을 컨테이너화하세요 # build stage from node\ lts alpine as builder user node workdir /home/node copy package json run npm ci copy chown=node\ node run npm run build \# final run stage from node\ lts alpine as runner env node env=production user node workdir /home/node copy from=builder chown=node\ node /home/node/package json copy from=builder chown=node\ node /home/node/node modules /node modules copy from=builder chown=node\ node /home/node/dist /dist copy from=builder chown=node\ node /home/node/server /server arg port expose ${port 3000} cmd \["node", "server/entry express"] github에 푸시하고 back4app을 통해 배포하기 프로젝트를 github에 푸시하세요 git init git add git commit m "initial commit for back4app deployment" git branch m main git remote add origin \<your github repository url> git push u origin main 그런 다음, back4app 웹 배포를 사용하여 배포하세요 로그인 하세요 back4app 웹 배포 https //www back4app com/containers 클릭하세요 "새 앱 만들기" , 이름을 제공하고 github 리포지토리 를 선택하세요 back4app이 귀하의 리포지토리에 접근할 수 있도록 승인하고 qwik 프로젝트 리포지토리를 선택하세요 선택하세요 dockerfile 배포 하고 빌드 설정을 확인하세요 클릭하세요 "배포" 하여 빌드 프로세스를 시작하세요 배포 모니터링 및 관리 배포 후, back4app 대시보드를 사용하여 문제 해결을 위한 로그 보기 컨테이너 성능 및 자원 사용 모니터링 새 커밋이 푸시될 때 재배포 트리거 필요한 경우 사용자 정의 도메인 구성 애플리케이션 테스트 및 디버깅 배포 후, qwik 앱을 철저히 테스트하세요 api 연결 확인 브라우저의 개발자 콘솔(f12 → 네트워크)을 열어 작업 중 api 호출을 확인하세요 작업 추가 및 검색 ui를 사용하여 작업을 추가한 후, back4app 데이터베이스 브라우저에서 데이터 지속성을 확인하기 위해 새로 고침하세요 crud 작업 테스트 작업을 완료로 표시하고 삭제할 때 백엔드에 올바르게 반영되는지 확인하세요 엣지 케이스 처리 양식 입력을 검증하고 개발자 도구를 사용하여 느린 네트워크 조건을 시뮬레이션하세요 문제가 발생하면 back4app 로그를 검토하거나 api 구성을 다시 확인하세요 back4app 서비스 사용을 위한 모범 사례 응용 프로그램의 성능과 보안을 향상시키기 위해 api 호출 최적화 여러 작업에 대해 배치 요청을 사용하고 필요한 필드만 쿼리하세요 민감한 데이터 보호 application id 및 javascript key와 같은 자격 증명을 환경 변수에 저장하세요 qwik에서는 env 파일을 생성하세요 vite parse app id=your app id vite parse js key=your js key 자동 확장 활성화 back4app 웹 배포에서 자동 확장을 활성화하여 높은 트래픽을 관리합니다 보안 강화 데이터 수정을 제어하기 위해 클래스 수준 권한(clps)을 제한하고 필요에 따라 acl을 설정합니다 클라우드 코드 활용 성능 향상 및 api 노출 감소를 위해 복잡한 로직을 클라우드 코드로 오프로드합니다 결론 이제 qwik을 프론트엔드로 사용하고 back4app의 강력한 백엔드 서비스를 이용하여 전체 스택 할 일 목록 애플리케이션을 구축했습니다 이 튜토리얼은 qwik 프로젝트 설정, parse sdk 통합 및 back4app에서 컨테이너화된 워크플로우를 사용하여 사이트를 배포하는 과정을 안내했습니다 개발을 계속하면서 고급 사용자 인증, 실시간 업데이트 및 타사 통합과 같은 기능을 추가하는 것을 고려하세요 추가 정보 및 지원을 원하시면 back4app 문서 https //www back4app com/docs 를 참조하세요