블로그

코드캠프

Github Copoilot vs 주니어 개발자 (feat. 뭐야 내 직업 돌려줘요)

Github Copilot에 대한 의견이 분분하다는 걸 목격한 코캠, 지난 블로깅에서는 토론에 참여해 의견을 끼워넣어봤습니다.코캠 내부의 토론 결과, '주니어는 대체될 수도 있을 것 같다.' 라는 의견이 많았습니다.이 토론 결과에 동공이 흔들리는 주니어 바로 나야나... (내 직업 못잃어...)코드캠프 선배님들은 거침없이 왜 주니어가 대체 될 수 있는지에 대해 말씀을 시작하고,(그만..그만 말해..)주니어 막냉이는 오랜만에 심장에 떨림이 느껴지기 시작하고. 나 떨고있니..직업이 한순간 백수가 될까 불안에 떨던 저는 마음 먹었습니다.copilot을 직접 사용해보고 정말 날 대체할 수 있나 판단하기로.비교대상인 저는 코드캠프 2년차 주니어 개발자이며 언어는 javascript를 사용하고 있습니다.스택은 코드캠프 스택 + a 정도의 스택을 가지고 있습니다. 자, 그럼 [ 코파일럿 vs 주니어 개발자 ] 비교 가 보 자 구 💡주니어의 Copoilot 사용기1️⃣ 코파일럿 사용 세팅하기 [ Docs ]1 ) 깃허브 settings에 들어갑니다.2) 왼쪽의 사이드 바 'code,planning, and automation' 섹션에서 copilot을 클릭합니다.3) copilot 설정을 해줍니다.* 60일동안은 무료지만, 이후부터는 유료 서비스로 전환됩니다.그 전에 구독 취소하시면 비용을 지불하지 않아도 됩니다.모두 입력 후 설정값을 저장해주시면 됩니다!4) vsCode에 Github Copilot이라는 extension을 설치합니다.5) 설치하고 나면 깃허브 로그인,권한부여 등을 묻는 창이 작게 뜰텐데 로그인과 권한부여에 모두 동의해주시면 됩니다.6) 다 했는데 안될때는?설정 버튼을 눌러 [ 확장 설정 ]을 눌러주세요.위의 버튼을 눌러 setting.json 파일에 들어가 copilot 사용설정을 해주세요! 2️⃣ copilot VS 주니어 개발자⛔️ 본격적으로 주니어 개발자와 copilot의 비교에 앞서, 이 견해는 코드캠프의 주니어 개발자의 의견일 뿐 모두를 대표하지 않습니다. 비교를 위해 주니어 개발자인 저와 코파일럿이 같은 기능을 만들어 보기로 했습니다.기능 : unix 시간을 자바스크립트 Date객체로 변환해 화면에 예쁘게 출력하기[ 주니어 개발자 ]만드는 데 걸린 시간 : 30분직접 코딩시 장단점장점 : 구조를 내 마음대로 그때 그때 바꾸면서 사용할 수 있다.단점 : 모르는 파트가 나오면 구글링 + 구현시간이 꽤나 걸린다.[ 코파일럿 ]위 사진은 코파일럿이 만들어준 기능입니다.너무 신기하게도 제가 직접 작성했던 코드를 러닝해서 비슷하게 진행되면 제가 적었던 코드를 추천 합니다.위의 주석처리 된 함수는 제가 함수 이름만 만들어도 전에 적었던 함수를 추천해줬습니다.그럼 주석으로 한줄씩 만드는 데는 차이가 있을까하여 주석묘사로도 만들어봤는데, 주석도 추천해줍니다.(너무 신기)만드는데 걸린시간 : 5분신기하게도 내가 적은 코드도 러닝을 해서 내 코드를 추천해줌..한글 주석도 된다코파일럿으로 코딩시 장단점장점 : 누구보다 빠르게 코딩이 가능함단점 : 본인 실력이 아니기때문에 코드수정이 필요할 때 난감할 수 있음.기본 틀 자체를 추천하기 때문에 수정에 불리함.그 기능 만들거 아닌데 설레발로 자동완성 해주려고 하니까 불편함. 주니어 개발자의 전반적인 평가평가는 개인적인 견해이기 때문에 주니어 By 주니어지만, 제가 사용해본 코파일럿은 생각보다 똑똑했습니다.언어를 선택할 수 있다고 하길래 당연히 JS 에서만 자동완성이 되는 줄 알았는데, HTML 코드에서도 자동완성을 추천해줍니다.HTML 코드 추천은 제가 위에 적어놓은 코드+내용 바탕으로 추천하는 것 같은데 생각보다 정확합니다.사용하면서 계속 들었던 생각은 '어..이게 되네?' 와 '어..생각보다 똑똑한데...?' 입니다.물론 제가 복잡한 프로젝트내에서 적용하게 아니고, 간단한 기능을 만들었기 때문에 그럴 수 있지만 간단한 함수들을 만드는데는 전혀 무리가 없어보입니다.또한 깃허브에서 만든거라 주석묘사시 영문으로만 입력해야하나 걱정했는데, 한글로도 작성이 가능합니다.코파일럿을 이용해서 회사 내부 템플릿을 만들수도 있겠다는 생각이 드는게, 주석을 자세히 달고 해당 주석을 그대로 입력하면 템플릿을 복사해오지 않을까 싶습니다.이렇게 되면 공통 컴포넌트를 작업하는 시니어는 코파일럿을 만지고, 주니어는 크게 할 일이 없어질 수도 있을 것 같습니다. 결론은 아주 훗날, 라이선스 문제도 해결되고 회사에서 상용화 된다면 정말 주니어 개발자의 입지가 좁아질 수 있을 것 같다는 생각이 들 정도로 잘 됩니다. 그럼, 주니어 개발자는 어떤 걸 더 공부하고 성장해야 코파일럿에게 밀리지 않고 개발자 수명을 연명해 나갈 수 있을까요?(직업을 잃을 순 없잖아요)주니어 개발자가 공부하면 너~무 좋은 기술! 다음 블로그에서 만나보도록 하시죠!모두 코캠과 함께 공부하고 성장하는 개발자가 되어 직업을 잃지 않기로해요. 약속~👍🏻 

웹 개발코파일럿주니어대체GithubCopliot개발자대체프론트엔드백엔드코드캠프

이정환 Winterlood

[마감되었습니다] 한 입 크기로 잘라먹는 타입스크립트 사전 등록 이벤트

안녕하세요 이정환입니다 😃강의 출시와 함께 이벤트가 마감되었습니다.관심가져주시고 신청해주신 800여분의 여러분께 진심으로 감사드립니다.강의는 아래 링크로 보러가실 수 있습니다(현재 얼리버드 30% 할인 중입니다)https://inf.run/9ZRN 강의 소개유튜브 영상으로 보기한 입 크기로 잘라먹는 시리즈의 2번째 강의 한 입 크기로 잘라먹는 타입스크립트는배워도 배워도 자꾸만 헷갈리는 타입스크립트를 개념 이해와 함께 제대로 배워보는 강의입니다.복습을 위한 핸드북 제공강의를 들으면서 함께 보시거나, 강의 수강 이후 복습하시기 용이하도록강의 내용과 100% 일치하는 핸드북을 제공합니다.커리큘럼 소개🌱 Section 1. 타입스크립트 개론기술을 잘 이해하려면 그것이 어떤 배경에서 탄생했는지 알 필요가 있습니다.1섹션 에서는 타입스크립트의 탄생 배경을 살펴보며 타입스크립트가 해결하고자 했던 문제가 무엇이고 타입스크립트가 어떤 특징을 가지고 있는지 자세히 살펴봅니다.🌱 Section 2 ~ 3. 타입스크립트 기초 다지기가장 기본적인 타입스크립트의 문법을 살펴봅니다.동시에 타입스크립트가 말하는 타입이란 정확히 무엇인지그리고 타입들이 서로 어떤 관계를 맺고 어떻게 상호작용하는지 살펴봅니다.🌱 Section 4 ~ 6. 다양한 타입스크립트 문법 살펴보기함수 타입 정의, 함수 오버로딩, 인터페이스, 클래스 등타입스크립트의 다양한 기능과 문법을 살펴봅니다.🌱 Section 7 ~ 9. 마법사 처럼 타입을 직접 조작하기타입스크립트의 가장 독특하면서도 강력한 기능인 타입 조작 기능에 대해 살펴봅니다.제네릭, 인덱스드 엑세스 타입, 맵드 타입, Keyof 연산자, 조건부 타입 등아주 다양한 타입스크립트의 타입 조작 문법을 살펴봅니다.🌱 Section 10. 유틸리티 타입 이용하기타입스크립트가 기본적으로 제공하는 여러가지 유틸리티 타입들에 대해 살펴봅니다.유틸리티 타입을 지금까지 배운 지식을 이용해 직접 구현 해봅니다.🌱 Section 11. 리액트에서 타입스크립트 사용하기(보너스)이대로 끝나면 아쉽죠? 그래서 보너스 섹션으로 준비했습니다.아주 간단한 투두 리스트를 함께 만들어보며리액트 프로젝트에 타입스크립트를 적용하는 방법에 대해 살펴봅니다.닫는 말마지막으로 신규 강의를 끝까지 마무리할 수 있도록 계속해서 응원해주신기존 수강생 분들과 독자 분들 그리고 주변 지인 분들께 모두 감사드립니다.또 이 글을 보고 관심을 가져주신 모든 인프런 유저 여러분께도 감사드립니다.

프론트엔드타입스크립트프론트엔드자바스크립트typescriptjavascript

코드캠프

입문자도 가넝한 8주만에 개발자 되는 법

안녕하세요! 실무 코딩부트캠프, 코드캠프입니다 :)날씨가 조금씩 따뜻해지면서 식곤증이 부쩍 늘어나고 있지 않나요?(전지적 컴퓨터 시점)그래서 코드캠프가 눈이 번쩍! 뜨이는(👀) 강의 업데이트 소식을 준비해왔어요!특히 비전공이지만 개발 커리어에 관심이 있는 분들이라면, 주목해주셔도 좋아요 :)코딩을 몰라도(NEW!) 2개월만에 개발자가 되는 '관리형' 코딩 부트캠프인프런에 입성한지 얼마 되지 않았지만 뜨거운 관심과 애정 어린 피드백을 받으며, 더 나은 컨텐츠를 제공하기 위해 코드캠프도 열심히 성장 중인데요. (정말 감사합니다)그 중 사전 기초 지식 없이는 부트캠프 합류가 어려워 신청을 망설였던 분들을 많이 보았어요.그래서 상담 후 등록을 완료해주신 모든 분들께,[시작은 프리캠프], [강력한 CSS], [훈훈한 Javascript] 기초 강의를 무료로 제공합니다!사전 지식을 필요로 하시는 분들은 웹 개발의 기초를 습득하시고사전 지식이 이미 있으신 분들은 기초 내용을 복습하면서 튼튼하게 다져보세요 :)⚠️ 단, 기초 강의 수강 기간은 부트캠프 기간(8주)에 포함되지 않으므로 등록하신 기수의 개강 일정에 맞춰 수강해 주셔야 합니다!(MBTI가 P인 분들)개강 전 기초 강의 수강 계획을 짜기 힘드신 분들은 언제든 코드캠프에 문의해주세요!개강일에 맞춰 수강할 수 있도록 체계적인 시간표를 제공해드리겠습니다 😊👉 2기 일정 : 03.06 - 04.28 (선착순 모집) ▶ 20% 할인 중!👉 3기 일정 : 04.03 - 05.29 (선착순 모집) ▶ 20% 할인 중!

웹 개발웹개발프론트엔드백엔드부트캠프비전공자JavascriptNode.jsReactNext.jsNest.js

코드캠프

Github Copilot, 진짜 개발자 대체가 가능할까?

요즘 Github Copilot에 관해 여러가지 의견들이 충돌하며 의견이 분분하다는 것을 본 코캠.어떤분들은 '미래에 개발자는 Copilot이 대체할 거다' 라는 의견이 있는가 하는 반면, '치와와랑 머핀도 구분 못하는 AI가 어떻게 대체하냐,아직 미흡하다.' 라는 의견도 있었습니다.이런 토론은 개발자로서 굉장히 참을 수 없는 의견대립이죠.그래서 코캠측에서도 슬그머니 의견을 끼워 넣어보기 위해 Github Copilot에 대해 알아보았습니다. 🛠 Github Copoilot?깃허브 코파일럿은 내가 원하는 기능을 주석으로 묘사하면, 묘사에 맞는 기능을 자동으로 완성시켜주는 자동 코딩 시스템입니다.Copilot 빠르게 시작하기1️⃣ 작동방식1. 내가 원하는 기능을 주석으로 묘사합니다.2. 코파일럿 AI가 딥러닝 한 내용을 바탕으로 '대부분 이렇게 쓰던데?' 하는 코드들을 완성합니다. 2️⃣ Github Copoilot의 장단점[ 장점 ]웬만큼 연차가 쌓인 개발자가 아니고서야 라이브 코딩을 하는 개발자는 생각 보다 많이 없습니다.주니어 개발자의 대부분은 다른 사람들이 쓴 코드를 참고하고 긁어와 사용하는 경우가 더 많죠.이런 부분에 있어서는 코파일럿이 도움이 될 수 있습니다.[ 단점 ]코파일럿의 학습이 완벽하지 않기 때문에 개발자의 의도가 정확하게 컴퓨팅 사고를 기반으로 제시되지 않으면, AI는 갈 길을 잃고 의도와 다른 코드를 제시할 수 있습니다.개발자의 의도와 다른 코드는 결국 불필요한 코드를 늘리는 것과 같기 때문에 비효율적일 수 있습니다. 3️⃣ Copoilot의 궁극적인 문제?copoilot의 궁극적 문제는 라이선스 문제가 되지 않을까 싶습니다.코파일럿의 AI가 어떤 라이선스인가를 따지지 않고 학습하기 때문에 뱉어낸 결과물에 제한된 라이선스 코드가 있다면 해당 코파일럿 코드 또한 제한되어야 하는지, 적용한다면 어느 범주까지 적용해야 하는지 애매한 부분이 있다고 합니다.  ❓ 그래서 진짜 개발자 대체가 가능해?여기부터는 코드캠프 일부 개발자들의 의견으로 반박시 여러분들 의견이 맞습니다.😁코드캠프에게 여러분들의 의견을 알려주세요! 코캠측 개발자들의 의견을 정리해보았는데요, 생각보다 코캠 내부에서도 파가 나뉘었습니다!🧑🏻‍💻 백엔드 개발자들Captain( 팀 내 그저 빛을 맡고 계신 9년차 풀스택 개발자 )- 설계를 하는 시니어들은 대체 불가능, 단순 업무를 하는 주니어는 대체 가능.틀을 설계하는 건 인공지능이 발전해도 인간의 창의성까지 가지고 올 수 없는 부분이 있기 때문에 무리라고 생각.Quokka- 비슷한 거 써봤는데 대체 안됨.( 일단 돈을 안냈음. - 무료판 유저 )Otter- 회사의 도입이 대중화 되느냐에 따라 다를 것 같은데, 주니어는 대체 가능하지만 로직의 틀을 짜야 하는 시니어는 대체가 불가하다.Bommy- 상용화 시기가 중요하다고 생각, 과도기동안은 주니어도 대체가 안되지만 상용화 된 이후에는 주니어는 대체가 가능하다고 생각.🧑🏻‍💻 프론트엔드 개발자들Eunny- 주니어, 시니어 모두 대체가 불가하다.공부는 가능하겠지만, 모든 코드는 각자 코드 상황에 따라 다르게 적용되기 때문에 대체 불가.Hoony( 공상과학에 빠져있는 디지털노마드 선두주자 )- 주니어, 시니어 모두 대체가 가능하다. ( 터미네이터와 아이언맨 자비스를 너무 감명 깊게 봄. - AI가 인류를 대체할 수 있다 주의 )시간이 흐를 수록 데이터는 누적될 것이고 대부분의 코드 설계가 가능한 수준까지 올라 갈 수 있을 것, 이를 통해 인건비 절감을 위해 개발자 보다 AI를 선호하는 상황이 생길 수 있다.Jenny- 주니어 정도는 코파일럿으로 대체가 가능하다. 하지만 코파일럿 설계를 해야 하는 엔지니어나 서비스의 큰 틀을 짜야하는 시니어는 대체가 불가능하다. 큰 틀은 언제나 상황에 따라 짜야 하는데 통상적인 부분으로는 커버 불가능함.Gee- 코파일럿이 상용화되어서 많은 사람이 사용하게 된다면 나중에는 코파일럿이 작성한 코드가 트렌드를 반영한 정석 로직으로 여겨지는 날이 올 것 같음. 하지만 상황에 맞게 배치하고 개선하는 작업을 하는 개발자는 반드시 필요하다고 생각. ( 근데 코파일럿 되게 좋은데? ) 코드캠프에서도 총 3가지 의견으로 나뉘었는데요,1. 주니어만 대체가 가능하다.2. 주니어, 시니어 둘 다 대체 가능하다.3. 주니어, 시니어 둘 다 대체 불가능하다.이렇게 총 세가지 의견 중 가장 우세한 의견은 [ 주니어는 대체가 가능하나, 시니어는 불가능하다! ] 입니다. 코드 캠프의 개발자들(일부)은 위와 같이 생각하는데, 여러분들은 어떻게 생각하시나요?여러분들의 의견도 들려주세요!

웹 개발개발자개발자대체GithubCopilotAI기술토론프론트엔드백엔드웹개발시니어개발자주니어개발자

솔 (Sol)

프론트엔드? 프런트엔드? 어떻게 쓰는 게 맞을까요? 🤔

웹 개발에서 클라이언트 측(Client Side)에서의 개발을 의미하는 Front-End! 웹 브라우저처럼, 사용자가 접속하는 맨 앞단(frontend)을 맡기 때문에 이런 이름이 붙었는데요. 그런데... Front-End, 한글로는 어떻게 쓰고 계신가요? [프론트엔드]로 써야 할지, [프런트엔드]라고 써야 할지 고민이 되진 않으셨나요?  그래서 한 번 알아봤습니다. 🧐 1) 국립국어원 - 온라인가나다 답변 국립국어원에 따르면 ‘프런트엔드’로 쓰는 것이 적절하다고 합니다.영어의 ‘front’를 ‘프런트’로 옮겨 적어야 하기 때문입니다. 궁금해서 직접 물어봤습니다. (국립국어원 온라인가나다) 2) 사람들은 어떻게 많이 쓸까 - 한국어 위키백과 한국어 위키백과에 프론트엔드와 백엔드라는 이름의 문서가 있습니다. (영어 위키백과의 Frontend and backend 문서와 거의 동일한 내용입니다.) 3) 사람들은 어떻게 많이 쓸까 - 검색량 구글 트렌드로 프론트엔드와 프런트엔드를 비교한 결과, 프론트엔드에 대한 검색어 관심도가 더 높았습니다. 구글 트렌드(Google Trend)로 검색어에 대한 관심도를 비교할 수 있어요. 키자드 키워드 마법사에 따르면 구글, 네이버 모두 ‘프론트엔드’ 키워드에 대한 검색량 및 콘텐츠 수가 더 많았습니다. 키자드(Keyzard)로 웹페이지 상위 노출에 도움이 되는 키워드 월간 검색량을 비교할 수 있어요. 4) 결론... 한국어 어문 규범에 따라 적절한 표기는 ‘프런트엔드’ 입니다. 다만 인터넷 키워드 검색량 등으로 미루어볼 때 ‘프론트엔드’가 ‘프런트엔드’보다 널리, 자주 쓰이고 있습니다. (보편적으로)  의도에 따라 프런트엔드, 프론트엔드 키워드를 구분하여 활용할 수 있을 듯합니다. 프론트엔드? 프런트엔드? 여러분의 선택은 어느 쪽인가요?

프론트엔드프론트엔드프런트엔드

코딩웍스(Coding Works)

REM 단위와 EM 단위 이해하기

안녕하세요. 코딩웍스입니다.여러분들이 PX에 대한 개념은 너무 잘 알고 있으시니 이건 넘어가고 REM 단위와 EM 단위를 이해하는 시간을 가져볼게요.■ 일단 알고 가셔야 할 것 2가지EM은 상대적인 단위 곧, 부모요소의 폰트 사이즈에 의해 자식요소의 폰트 사이즈가 결정되는 방식REM은 Root + em = rem도 상대적인 단위 단, 부모요소의 폰트 사이즈에 의해 자식요소의 폰트 사이즈가 결정되는 방식이 아니라 Root의 폰트 사이즈에 의해 결정되는 방식(Root란 html이라는 선택자 또는 body 선택자를 말함, body를 Root로 잡아도 되지만 일반적으로 body 보다는 더 상위 선택자인 html 선택자를 Root로 사용합니다.)■ 아래 html과 css를 예시로 설명해볼게요.1) CSS에 폰트사이즈에 대한 아무것도 설정하지 않은 상태그럼 현재 상태에서 h1, h2, h3, p 태그의 폰트사이즈는 얼마일까요?.....정답) 개발자 도구를 통해서 확인하면 알수 있습니다만...p는 16px이라고 하시면 맞지만 정답은 아닙니다. 정답은 p의 폰트사이즈는 1em입니다. 그럼 1em은 어디서 나온 것이냐면 p의 부모요소인 body가 16픽셀(폰트 사이즈를 따로 정해주지 않으면 기본이 16px)이기 때문에 위에서 설명했든 em은 부모요소의 폰트사이즈에 상대적으로 변하는 결정되는 방식이라고 했듯이 p은 1em, p의 부모요소 body는 16px 곧, 16px* 1 = 16px이 되어 p의 폰트사이즈는 16px이 됩니다.그래서 아래처럼 body에 fontt-size: 15px라고 정해준다면 p태그는 1em * 15 = 15px이 됩니다.body의 폰트가 16픽셀이라면 정답은 아래와 같습니다.p => 16pxh1 => 32px (h1은 부모요소를 기준으로 2em입니다. 곧, 2em * 16)h2 => 24px (h2은 부모요소를 기준으로 1.5em입니다. 곧, 1.5em * 16)h3 => 18.72px (h3은 부모요소를 기준으로 1.17em입니다. 곧, 1.17em * 16)h태그와 p태그는 자신에 폰트사이즈가 정해져 있는 것이 아니라 부모요소인 body에 의해 상대적으로(em) 결정됩니다.그럼 body의 폰트가 15픽셀이라면 위에 있는 방식으로 정확한 픽셀을 구할 수 있습니다.body에 fontt-size: 15px라고 주고 h1을 개발자 도구에서 보면 폰트사이즈가 30px인 것을 확인할 수 있습니다.여기까지가 em에 대한 이해도 입니다.여기서부터 rem에 대한 이해도 입니다. 1) CSS에 폰트사이즈에 대한 아무것도 설정하지 않은 상태현재 상태에서 h1, p 태그의 폰트사이즈는 위에 설명한 것과 동일합니다..em-wrap에 있는 p => 16px, h1 => 16*2 = 32px.rem-wrap에 있는 p => 16px, h1 => 16*2 = 32px 2) 아래처럼 rem 단위를 선언하면 어떻게 될까요?이제 결론~!!em 단위로 설정된 아래의 선택자는 body의 16픽셀을 기준으로 상대적으로 변합니다.물론, .em-wrap { font-size: 20px; } 로 있다면 h1, p는 body가 상위요소가 아니라 .em-wrap 이므로 .em-wrap의 폰트사이즈를 기준으로 상대적으로 변합니다.( 곧, h1은 40픽셀, p는 20픽셀이 됩니다.).em-wrap h1 { font-size: 2em; } .em-wrap p { font-size: 1em; }rem 단위로 설정된 아래의 선택자는 html의 15픽셀을 기준으로 상대적으로 변합니다. (h1, p의 부모요소인 .em-wrap 또는 .rem-wrap 그리고 그 위의 body을 기준으로 변하지 않음).rem-wrap h1 { font-size: 2rem; } .rem-wrap p { font-size: 1rem; } 

프론트엔드폰트단위pxemrem

코드캠프

코플소 |코캠러의 프로젝트를 소개합니다!

안녕하세요! 실무 코딩 부트캠프, 코드캠프입니다 :)어쩐지 요즘은 퇴근 시간에도 해가 안 진다 싶더니 오늘이 바로 낮🌞과 밤🌚의 길이가 같다는 ‘춘분’이래요!새 학기가 시작하는 계절이기도 한 지금, 여러분은 어떻게 커리어를 준비하고 계신가요?오늘은 코드캠프의 '코플소:코캠러의 프로젝트를 소개합니다'를 처음 소개하는 날이에요.코플소 시리즈는 코드캠프 코캠러의 다양한 프로젝트를 직접 볼 수 있는 유익한 소식지입니다😊자! 그럼 지금부터 첫번째 프로젝트를 확인해볼까요? 코캠러가 만든 세상에 단 하나뿐인 플랫폼!바로 '댕더(Danger)' 입니다!혹시... 댕더세요? 야나두!🙌기획 의도860만 반려동물 시대를 맞이해 반려견의 Play-Mate를 찾아 '멍라밸'의 질을 높이고 싶었어요!플랫폼을 통해 산책, 간식, 애견카페 탐방 등을 함께 할 친구를 찾는 애견인과 댕댕이를 위한 프로젝트입니다 :) 💫구현 기능✔️ 회원가입 & 초기 프로필 설정웹앱 개발의 기본인 회원가입에서 이메일로 가입할 수 있도록 구현했어요. 본인인증을 위해 가입할 이메일 계정으로 인증 이메일이 전송되어요. 또 동물보호관리시스템을 연동 시켜 반려동물을 등록하고 정보를 검증, 조회할 수 있어요!✔️로그인 페이지 & 비회원 페이지로그인 페이지에서는 회원가입. 비밀번호 재설정, 비회원으로 둘러보기를 차례로 넣어 직관적으로 보이게 만들었어요. 또한, 꼭 회원가입을 하지 않아도 비회원으로 입장해서 등록된 회원들의 강아지를 메인페이지에서 확인할 수 있답니다.(하지만 회원가입 유도를 위해 좋아요 스와이프, 상세 페이지, 댕더패스, 채팅 기능은 비활성화로 설정했답니다!)✔️오늘의 댕댕이 & 상세 페이지좋아요 기능을 적극 활용하여 '오늘의 댕댕이' 페이지를 기획해보았어요! 하루 동안 받은 좋아요 수를 기준으로 12마리까지 나타날 수 있게 구현해 놓고 강아지를 누르면, 댕댕이 상세 정보를 직접 확인할 수 있어요👀추가적인 강아지 사진들과 강아지 이름, 나이, 거리 정보, 설명, 성격, 관심사, 기피 견종까지! 모두 확인할 수 있고 상세페이지에서도 skip, 좋아요 스와이프가 가능하답니다 :)✔️채팅 목록 & 채팅방 페이지.채팅 목록에서는 매칭된 채팅방들을 확인할 수 있고 가장 최근 대화를 나눈 채팅방이 가장 위로 정렬될 수 있게 구현했어요. 또 채팅을 종료하고 싶을 경우 스와이프를 통해 나가기 버튼을 통해 퇴장이 가능해요. 상대 강아지와 채팅이 가능해서 장소와 약속 시간을 공유할 수 있는 기능을 부여해서 유저들이 편리하게 서비스를 이용할 수 있도록 구현했어요 :)🗣️팀 프로젝트 소감(View Point 팀)각자의 과정에서 공부만 하다 처음으로 프론트엔드와 백엔드가 만나는 시간이었던 만큼 긴장도 많이 됐고 서로가 배운 기술로 어떻게 협업을 해야 하는지 감도 잘 오지 않았어요. 하지만 팀원들이 정해지고 팀의 전반적인 룰을 정하기 위해 회의를 진행하거나 기획에 대해 논의를 계속 하면서 하나부터 열까지 협력이 필요하다는 것을 알게 되었습니다!코드캠프는 소수정예로 수강생을 받기 때문에 그만큼 집중 관리를 받을 수 있어서 프로젝트의 퀄리티가 좋은 것 같아요!바쁘고 힘들었던 만큼 가장 뿌듯한 과정이었기도 했습니다! View Point 팀 파이팅!!👊

웹 개발코드캠프팀프로젝트코드캠프후기부트캠프프론트엔드백엔드협업프로젝트플랫폼비전공자개발자

turborepo는 가지치기가 필요해

서론요즘 핫하고 핫한 모노레포 빌드 시스템이 있습니다. 이름하야 터보레포(turborepo), 무려 Nextjs를 만들고 있는 Vercel에서 제작했습니다.Nextjs를 무진장 사랑하는 저는 반드시 찍어 먹어봐야 되겠다고 생각을 했습니다. 그래서 간단한 앱을 만들어 빌드까지 해보기로 했죠!오늘의 주제는 바로 그 빌드와 관련 있습니다. 재밌는 부분을 찾았거든요!간단하게 말씀드리자면, 터보레포는 가지치기가 필요합니다. 엥?도커는 빠른 최적화를 원해요갑자기 가지치기라니, 이게 무슨 말일까요? 터보레포가 드디어 그 사악한 속을 드러내고 우리의 소중한 코드를 잘라내 버리겠다는 의미일까요? 다행히도 그건 아닙니다.터보레포의 가지치기에 대해 말하기에 앞서 우리는 도커가 어떻게 nodejs 환경에서 이미지를 만들어 내는지 살펴봐야 합니다. => [separator 2/4] RUN pnpm add turbo 17.1s => [installer 2/5] COPY .gitignore .gitignore 0.0s => [separator 3/4] COPY . . 0.4s => [separator 4/4] RUN pnpm turbo prune --scope=api --docker 1.0s => [installer 3/5] COPY --from=separator /app/out/json/ . 0.0s => [installer 4/5] COPY --from=separator /app/out/pnpm-lock.yaml ./pnpm-lock.yaml 0.0s => [installer 5/5] RUN pnpm install 16.1s => [builder 2/4] COPY --from=installer /app . 6.5s => [builder 3/4] COPY --from=separator /app/out/full . 0.0s => [builder 4/4] RUN pnpm turbo run build --filter=api 7.2s => [runner 2/2] COPY --from=builder /app . 7.5s => CACHED [separator 2/4] RUN pnpm add turbo 0.0s => CACHED [separator 3/4] COPY . . 0.0s => CACHED [separator 4/4] RUN pnpm turbo prune --scope=api --docker 0.0s => CACHED [installer 3/5] COPY --from=separator /app/out/json/ . 0.0s => CACHED [installer 4/5] COPY --from=separator /app/out/pnpm-lock.yaml ./pnpm-lock.yaml 0.0s => CACHED [installer 5/5] RUN pnpm install 0.0s => CACHED [builder 2/4] COPY --from=installer /app . 0.0s => CACHED [builder 3/4] COPY --from=separator /app/out/full . 0.0s => CACHED [builder 4/4] RUN pnpm turbo run build --filter=api 0.0s => CACHED [runner 2/2] COPY --from=builder /app . 0.0s도커는 package.json와 락파일(lockfile)을 전의 빌드와 비교해 변화가 있을 때 비로소 패키지를 설치합니다. 변화가 없다면 이전의 캐시된 결과를 그대로 가져다 쓰는 것이죠. 위의 로그가 그 예시 중 하나입니다.첫번째는 package.json이 변경된 후 빌드된 이미지의 로그입니다. 옆의 시간을 확인해 보세요. 두번째는 첫번째 빌드 이후 package.json을 변경하지 않고 빌드한 이미지의 로그입니다. CACHED라고 나와 있는 것이 보이나요? 다시 한 번 시간을 확인해 보세요. 0.0s, 압도적 시간! 바로 도커가 이 전에 캐시된 것을 그대로 가져와 사용했기 때문에 가능했던 일입니다.천방지축 어리둥절 빙글빙글 돌아가는 터포레포 디펜던시이 좋은 방법을 터포레포에서도 사용해야 되겠죠. 그런데요, 문제가 하나 있습니다. 터보레포는 바로 모노레포 빌드 시스템이라는 겁니다!모노레포, 즉 터보레포는 락파일을 전역으로 관리합니다. A, B 워크스페이스가 있을 때 B 워크스페이스에서 디펜던시가 변경된다면 그 사항이 그대로 락파일에 반영되는 것이죠. 이 때 디펜던시가 변경되지 않은 A 워크스페이스를 도커로 빌드한다면요? 아차차, 도커는 락파일이 변경된 것을 보고 새로 디펜던시들을 설치하기 시작합니다. 락파일! 락파일이 도커를 완벽하게 속여 먹인 겁니다!대체 이 문제를 어떻게 해결해야 할까요, 맞습니다. 가지치기가 등장할 시간입니다.가지치기된 모노레포터포레포도 진작에 이 문제를 파악하고 있었습니다:a. 터포레포는 락파일을 전역으로 관리하기 때문에 효율적인 도커 빌드가 불가능하다b. 그럼 빌드할 워크스페이스만 똑때서 락파일을 만든다음 도커에게 주면 되는 거 아닌가a. 헐b. ?이렇게 turbo prune가 탄생합니다. 그 이름에서도 보여지듯이 이 명령어의 기능은 간단합니다. 바로 특정 워크스페이스의 가지치기된 모노레포를 만들어 주는 것이죠!. ├── apps/ │ ├── a-workspace/ // example-package-1만 사용 │ │ ├── package.json │ │ └── src/ │ └── b-workspace/ // example-package-1, 2 둘 다 사용 │ ├── package.json │ └── src/ ├── packages/ │ ├── example-package-1/ │ │ ├── index.ts │ │ └── package.json │ └── example-package-2/ │ ├── index.ts │ └── package.json └── pnpm-lock.yaml예제 앱의 디렉토리 구조입니다. a-workspace는 example-package-1 패키지만 사용하고 있고 a-workspace는 1, 2 둘 다 사용하고 있네요. 그렇다면 turbo prune을 사용해 a-workspace만 빼내봅시다.turbo prune --scope="a-workspace"이 명령어를 실행한다면:. ├── apps/ │ └── a-workspaces/ // example-package-1만 사용 │ ├── package.json │ └── src/ ├── packages/ │ └── example-package-1/ │ ├── index.ts │ └── package.json └── pnpm-lock.yamlA 워크스페이스의 가지치기된 모노레포를 만들어 줍니다. 물론 가지치기된 락파일도 같이요! 이 락파일은 오직 A 워크스페이스의 디펜던시만을 담고 있어 B 워크스페이스의 디펜던시가 변경된다고 하더라도 영향을 받지 않습니다.이 가지치기된 모노레포를 도커로 빌드하게 된다면 더 이상 락파일에 머리를 감싸매지 않아도 됩니다!TMI도움이 됐나요?다행입니다! 오늘도 좋은 하루 보내세요!References[Best practices for writing Dockerfiles | Docker Docs](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#use-multi-stage-builds)[\`turbo prune\` – Turborepo](https://turbo.build/repo/docs/reference/command-line-reference/prune)[Deploying with Docker – Turborepo](https://turbo.build/repo/docs/handbook/deploying-with-docker)

프론트엔드turborepodocker

vscode는 tw.macro 자동 완성의 꿈을 꾸는가?

서론emotion과 tw.macro로 즐거운 시간을 보내고 있던 어느 날, 여러분은 이상한 점을 발견하게 됩니다.자동 완성에 아무 것도 나타나지 않습니다! 당황한 나머지 익스텐션을 다시 깔아봐도 자동 완성은 꿈쩍도 않습니다.기존의 방식대로 입력을 하니 비로소 제대로 작동합니다.이게 무슨 일인가요? 혹시 얼어 죽어도 class단이 마침내 그 사악한 손길을 자동 완성으로까지 뻗은 건 아닐까요?! 꽤 흥미롭지만, 아닙니다. 해결 방법이 있으니까요.자동 완성을 돌려줘!모든 문제는 공식 tailwindcss 익스텐션이 attributes를 사용하지 않는 상황을 염두하지 않고 만들어져 발생했습니다.tailwindCSS.classAttributes The HTML attributes for which to provide class completions, hover previews, linting etc. Default: class, className, ngClass tailwindCss.classAttribute에 tailwindcss 익스텐션은 HTML attributes에만 자동 완성을 제공합니다. 즉, class=""와 같은 형식에 자동 완성을 제공합니다. 아, 그럼 저기에 tw를 집어넣으면 되지 않겠나고요? 좋은 시도지만 일부분만 해결해 줄 뿐입니다. tw=""은 자동 완성이 되겠지만 emotion을 사용하는 경우는 해결되지 않으니까요.그래서 익스텐션 개발자는 여러 상황에도 자동 완성을 가능하게 만들기 위해서 experimental 설정을 제공했습니다. 이름하야, tailwindCSS.experimental.classRegex입니다.{ ..., "tailwindCSS.experimental.classRegex": [ "tw`([^`]*)", // tw`...` "tw=\"([^\"]*)", // <div tw="..." /> "tw={\"([^\"}]*)", // <div tw={"..."} /> "tw\\.\\w+`([^`]*)", // tw.xxx`...` "tw\\(.*?\\)`([^`]*)" // tw(Component)`...` ] }이 설정은 간단합니다. Regex로 자동 완성의 적용을 원하는 경우를 싹 다 적어서 넣으렴! 이라는거죠.해당 설정을 입맛에 맞게 수정한 다음, vscode의 settings.json에 적어주세요. 이렇게 한다면...우리의 친구 자동 완성이 돌아왔습니다!우리 오래 가자......!TMI도움이 됐나요?그렇다구요? 다행입니다!!오늘도 즐거운 개발이 되셨음 합니다!Reference[Custom class name completion contexts · Issue #7553 · tailwindlabs/tailwindcss · GitHub](https://github.com/tailwindlabs/tailwindcss/issues/7553)      

프론트엔드tailwindcsstwin.macrocompletionsautocompletevscode

nextjs 12에서 emotion과 함께하는 tailwindcss

Nextjs 12 is coming...nextjs 12에서 놀라운 소식이 전해졌습니다. 컴파일러로 swc를 채택했다는 것을요! 여러가지 이유가 있겠지만 가장 중요한 건 기존에 사용하던 babel보다 빌드가 최대 5배나 빨라졌다는 겁니다. 참고로 fast refresh는 최대 3배나 빨라졌다네요!좋은 소식입니다. 하지만 변화에는 언제나 문제가 발생하기 마련입니다. swc를 활성화하기 위해서는 .babelrc와 같은 바벨 설정 파일을 완전히 제거해야 합니다. 이런, 그럼 무조건 바벨을 설정해야 하는 경우는요?그렇습니다. 문제의 발생입니다! 특히 twin.macro을 아끼는 저는 그만 눈물을 닦아낼 수 밖에 없었습니다. 어떤 분께서 이를 대체하는 stailwc를 만들었지만 아직은 이르다는 느낌이 어렴풋이 들고 맙니다. 그렇다면, twin.macro를 포기할 수 밖에 없는 걸까요? 아닙니다!emotionyarn add @emotion/react @emotion/styled or npm install @emotion/react @emotaion/styledemotion을 설치합니다.tailwindcssyarn add tailwindcss or npm install tailwindcss tailwindcss만 설치하면 됩니다.twin.macropackagesyarn add twin.macro babel-loader babel-plugin-macros @babel/plugin-syntax-typescript @babel/preset-react or npm install twin.macro babel-loader babel-plugin-macros @babel/plugin-syntax-typescript @babel/preset-reacttwin.macro와 함께 설정에 필요한 babel 관련 패키지를 설치합니다. 상황에 따라 더 늘어날 수도 있습니다.configurationwithTwin.jsconst path = require("path"); const includedDirs = [ path.resolve(__dirname, "components"), path.resolve(__dirname, "pages"), path.resolve(__dirname, "styles"), ]; module.exports = function withTwin(nextConfig) { return { ...nextConfig, webpack(config, options) { const { dev, isServer } = options; config.module = config.module || {}; config.module.rules = config.module.rules || []; config.module.rules.push({ test: /\.(tsx|ts)$/, include: includedDirs, use: [ options.defaultLoaders.babel, { loader: "babel-loader", options: { sourceMaps: dev, presets: [ [ "@babel/preset-react", { runtime: "automatic", importSource: "@emotion/react" }, ], ], plugins: [ require.resolve("babel-plugin-macros"), require.resolve("@emotion/babel-plugin"), [ require.resolve("@babel/plugin-syntax-typescript"), { isTSX: true }, ], ], }, }, ], }); if (!isServer) { config.resolve.fallback = { ...(config.resolve.fallback || {}), fs: false, module: false, path: false, os: false, crypto: false, }; } if (typeof nextConfig.webpack === "function") { return nextConfig.webpack(config, options); } else { return config; } }, }; };babel 설정 파일을 대신해 babel을 설정합니다.next.config.jsconst withTwin = require("./withTwin"); const nextConfig = withTwin({ // <<- `withTwin` 함수 적용 reactStrictMode: true, swcMinify: true, }); module.exports = nextConfig;작성한 withTwin 함수를 적용해 nextjs를 설정합니다.typestsconfig.json{ ..., "types": [ "@types" ] }타입을 인식할 디렉토리를 설정합니다.@types/twin.d.tsimport "twin.macro"; import { css as cssImport } from "@emotion/react"; import styledImport from "@emotion/styled"; import { CSSInterpolation } from "@emotion/serialize"; // `twin.macro`에 다음 타입을 넣음 declare module "twin.macro" { const styled: typeof styledImport; const css: typeof cssImport; } // DOM의 attribute에 다음 타입을 넣음 declare module "react" { interface DOMAttributes<T> { tw?: string; css?: CSSInterpolation; } }twin.macro와 관련된 타입을 설정합니다.TMI사용하고 있는 tailwindcss에 적용할 수 있나요?네, class로 tailwindcss를 사용하고 있더라도 설치, 설정을 통해 twin.macro를 사용할 수 있습니다.왜 css 관련 설정을 하지 않나요?twin.macro는 입력받은 클래스들을 독립적으로 사용 가능한 css로 변환합니다. 따로 정의된 css의 도움을 받지 않고서요.이 때 변환은 twin.macro로 이뤄집니다. class로도 tailwindcss를 사용해야 한다면 css 설정을 거쳐야 합니다.도움이 됐나요?됐다구요? 다행입니다!즐거운 개발이 되길 바랄게요!reference[GitHub - ben-rogerson/twin.macro: 🦹‍♂️ Twin blends the magic of Tailwind with the flexibility of css-in-js (emotion, styled-components, stitches and goober) at build time.](https://github.com/ben-rogerson/twin.macro)[Enable SWC on next examples · ben-rogerson/twin.examples@36ac8c6 · GitHub](https://github.com/ben-rogerson/twin.examples/commit/36ac8c6dcfa80fcf9cfd65b5c4835b8f3aa79c00#diff-8e7430aee7d110ee12e0366c43b2e8328e0eae8fe870a88eae4bbb7532ec26e1)[Support SWC · Discussion #516 · ben-rogerson/twin.macro · GitHub](https://github.com/ben-rogerson/twin.macro/discussions/516)[How to config Nextjs for Babel Plugin Macros like twin.macro without disabling swc complier](https://blog.mrcatdev.com/how-to-config-nextjs-for-babel-plugin-macros-like-twinmacro-without-disabling-swc-compiler)

프론트엔드nextjstailwindcssemotionswctwin.macro

자바스크립트 그리고 소프트웨어 개발

저는 "리액트 훅" 강의를 만든 아저씨입니다. 자바스크립트가 이렇게 강력해졌다는 사실에 감탄했습니다. 그리고 제 생각을 옮겨보려고 합니다. 어쩔 수 없이 제 나이와 인터넷 역사가 나옵니다. 꼰대로 보이기는 싫지만 변천사이니 옛날 얘기를 조금 하겠습니다. 김대중 정부는 전국 인터넷 망을 깔았습니다. 그 후 PC방이 생겼고 저는 이메일 주소라는 걸 만들었습니다. 이메일 주소 만들기가 한시간 수업 주제였습니다. 모든 기관과 기업은 홈페이지를 만들었습니다. 홈페이지는 단순했습니다. 그림 몇개 띄우고 정보글을 올렸습니다. 홈페이지와 소프트웨어는 다른 개념이었습니다. 소프트웨어는 사람들이 일을 할 때 쓰는 도구였습니다. 홈페이지는 홍보나 검색할 때 잠깐 보는 매체였습니다. 그런데 지금은 홈페이지가 곧 소프트웨어가 되었습니다. 스프링 프레임워크에서는 "클라우드 네이티브 소프트웨어" 라는 용어를 만들었습니다. 진정 클라우드에서 작동하는 소프트웨어입니다. 그냥 정보를 보던 웹 페이지가 일을 하는 도구인 소프트웨어를 완전히 대체했다는 이야기로 이해됩니다. 아직 저도 이런 얘기가 익숙하지 않습니다. 그래도 웹페이지에서 도는 게 로컬 컴퓨팅으로 돌리는 것 보다 뭔가 약하거나 느릴거라는 의심이 듭니다. 하지만 유명 데이터 분석 도구를 만드는 Palantir 가 만든 모든 소프트웨어는 웹에서 동작합니다. 이런 변화가 가능했던 이유는 자바스크립트의 발전 때문입니다.  리액트 강의를 만들면서 자바스크립트가 ui 프로그래밍을 엄청 쉽게 만들었다는 것에 감탄했습니다. 회사들은 소프트웨어를 점점 클라우드화 시키고 있습니다. 유지보수, 배포, 과금 처리가 쉽기 때문입니다. 앞으로 자바스크립트 발전이 더 기대됩니다.  

프론트엔드jsreactjavascript

이양구

[인프런 워밍업클럽 스터디 FE 0기] 후기

0.반년을 일하면서 어떻게든 잘 버티고 있다고 생각했다."간단하게 인풋에 키랑 아이디 넣고 버튼 누르면 삭제되는 html이면 될 것 같아요."새폴더 > index.htmlvs code의 빈 공간이 이렇게나 낯설고 막막하게 느껴질 줄은 몰랐다. 1.나도 나를 잘 모르지만, 얼마나 게으른 사람인지는 잘 안다.어떻게든 날 밀어붙일 계기가 필요하다 생각하고 이것저것 알아보다가 인프런에서 진행하는 스터디를 알게 됐다.무작정 신청하고 들어온 스터디엔 생각보다 많은 사람이 있었고 그만큼이나 열심히 노력하시는 러너님들이 가득했다. 2.사실 스터디 초반엔 이미 다 알고 있는 부분이라 생각해 적당히 강의를 봤던 적도 있었다.그리고 첫 과제를 진행하는 순간 내가 왜 이 스터디를 신청했던 건지 몸소 느낄 수 있었다.생각보다 과제는 하루이틀만에 끝낼 수 없었고 남은 기간 동안 얼마나 할 수 있을지 계산적으로 생각하기도 했지만, 이게 무슨 의미인가 싶어 반쯤은 체념하고 대신 열심히만 하자고 마음을 먹었다.그런데 적당히 포기하고 마음을 놓으니 오히려 오기가 생겼던 것 같다.그 뒤로부터 출근하면서 강의 보고, 퇴근하면서 강의 보고, 집에 와서 과제하고, 주말에는 더 몰아서 강의 보고 과제하고...며칠, 몇 주를 그렇게 지냈다. 3.퇴근하고 디스코드에 들어가면 늦은 시간에도 늘 접속해 계셨던 몇몇 러너님들이 계셨는데 하루쯤 쉴까 싶은 날에는 그런 러너님들을 보며 나를 바로잡곤 했다.그중 한 러너님께서 사이드 프로젝트 인원을 모집한다는 글을 올리셨고, 또다시 나를 밀어붙이기 위해 과감하게 연락을 드려 좋은 기회를 가지게 됐다.이번 워밍업 스터디를 신청하길 잘했다고 가장 크게 느꼈던 점은 정말 많은 분들이 개발에 대해 공부하고 있고 실천하고 있다는 걸 눈으로 확인하고 몸소 느꼈던 부분이 아닐까 싶다.게다가 생각지도 못 했던 우수 러너가 되었다..!나를 선정해주신 코치님에게 감사한 마음과 그만큼 앞으로 더 잘해야겠다는 다짐을 다시 한번 하게 됐다.우연한 기회에 만난 인프런, 그리고 스터디가 내게 많은 전환점이 될 수 있을 것 같아 감사하다는 말씀을 전하고 싶다. 4.사실 원동력의 팔할은 나보다 더 노력하는 러너님들을 향한 시샘과 존경이었다.

프론트엔드인프런인프런워밍업클럽스터디0기

최경희

[인프런 워밍업 클럽 0기] FE 2주차

2주차 학습 요약(8일차는 중간 점검으로 학습할 강의가 없었습니다.)7일차 - 프로젝트 만들기자바스크립트만으로 Stop Watch 앱과 할 일을 추가하고 삭제하는 Todo 앱, SpeadSheet(엑셀) 앱의 기능을 구현하고, 꾸미는 방법을 배웠습니다. 앱을 만들면서 localStorage를 사용하는 방법을 새로 알 수 있었습니다. 9일차 - 리액트 기본 및 Todo 앱 만들기리액트란 강의에서 리액트에 대한 개념과 리액트에서 사용하는 컴포넌트에 대한 개념 및 종류를 알 수 있었고, 리액트의 가장 중요한 특징인 가상돔을 알기 위해 브라우저가 렌더링하는 과정을 함께 배웠습니다. 그 외 리액트를 사용하기 위한 여러가지 환경 설정을 하는 방법을 알 수 있었습니다. Todo 앱을 만들면서 리액트의 주요 기능인 JSX와 State, Props, Hooks를 배울 수 있었고, 그 외 CSS 프레임워크 중 하나인 TailWind CSS에 대해서도 배울 수 있었습니다. 10일차 - 리액트로 Netflix 만들기Netfilx 클론 앱을 만들면서 API를 사용하는 방법과 axios를 사용하는 방법, 커스텀 Hooks을 작성하는 방법에 대해 배울 수 있었고, Styled Component 라는 CSS 관련 라이브러리를 사용하여 꾸미는 방법과 react-router-dom을 사용하여 페이지 전환을 하는 방법을 새로 알 수 있었습니다. 미션 해결 과정► 과제 총 합본 : https://www.inflearn.com/blogs/6988Day2 미션 : 음식 메뉴 앱각 메뉴를 클릭할 때, 메뉴에 맞는 음식 리스트를 보여주는 앱 입니다.음식 메뉴가 아닌 투썸 플레이스 카페 메뉴로 변경했고, 메뉴 부분의 스타일과 전체적인 색상을 변경했습니다.이미지는 투썸 플레이스 카페의 홈페이지에서 이미지 주소 복사를 통해 가져왔는데, 저작권 문제 때문에 저작권 문제가 없는 다른 이미지를 구해야하나 고민하고 있습니다. 스타일을 수정할 때 가장 시간이 오래 걸렸는데, 간격 조절이 가장 어려웠던 것 같습니다. 저번주에 막혔던 화면 크기로 인한 넘침 문제를 조금이나마 고칠 수 있게 되어, 현재 화면 크기에 따라 한줄에 나열되는 음식 아이템들의 개수가 동적으로 변경되게 했습니다. 처음에는 맥에서 진행해서 몰랐는데, 윈도우에서는 스크롤 바로 인한 밀림 현상이 있는 것을 알게 되어 스크롤 바를 항상 보이게 하는 것으로 수정했습니다. Day3 미션 : 가위 바위 보 앱컴퓨터와 진행하는 가위 바위 보 게임으로 총 10번을 진행하여 승부를 내는 앱 입니다.전체적인 디자인과 색상을 변경했고, 가위, 바위, 보 대신에 아이콘을 사용하여 표현했습니다.저번 주에 진행했던 것과 다르게 전체적으로 다시 꾸몄습니다. 태그 마다 간격을 설정하는 것이 가장 어려웠는데, 사용하는 맥과 윈도우의 화면 크기 차이로 인해 서로 다르게 보이는 문제가 있었고, 최대한 화면 크기와 상관없이 동일한 위치에서 보일 수 있게 개발 했습니다. Day4 미션 : 퀴즈 앱수학 연산 관련 질문이 나오고, 2~3개의 답변 중 맞는 답변을 선택하면 배경이 초록색이 되고 틀린 답변을 선택하면 배경이 빨간 색이 되는 앱 입니다.맞춤법 관련 퀴즈 앱을 만들었습니다. 전체적인 디자인을 변경했고, 배경이 아닌 선택한 답변의 버튼 색이 바뀌게 했습니다. 또한 마지막에 맞은 답변의 개수를 알 수 있게 했습니다.네이버의 한글날 맞춤법 테스트 사이트를 참고하여 만들었습니다. 질문 개수를 많이 만들어서 질문이 랜덤으로 나오게 하고 싶었지만 시간이 없어서 못한 것이 아쉬웠습니다. 다음에 시간이 생기면 변경해보고 싶고, 이것을 바탕으로 심리 사이트 앱을 만들어도 괜찮겠다는 생각을 하게 되었습니다. Day5 미션 : 책 리스트 나열 앱 책 이름과 저자를 입력하여 제출하면 책 리스트에 추가가 되며, 삭제할 수도 있고 추가 및 삭제가 발생할 때마다 알림이 나오는 앱 입니다.전체적인 색상만 변경하고, 구조는 과제 영상과 비슷하게 만들었습니다. 또한 제출 버튼을 클릭했을 때 이름과 저자를 모두 입력하지 않으면 제출되지 않게 만들었습니다.다른 과제처럼 저만의 디자인으로 변경하고 싶었지만, 시간도 부족하고 생각나는 디자인이 없어 과제 영상과 비슷하게 만든 것이 아쉬웠습니다. 다른 과제를 진행하면서 간격 조절하는 것이 익숙해진 것인지 태그들의 간격을 정하는 것이 다른 과제에 비해 수월하게 진행됐습니다. Day9 미션 : 예산 계산기 앱 지출 항목과 비용을 입력하여 제출하면 리스트에 추가되고 리스트에 있는 모든 항목의 총 지출 값을 확인할 수 있으며, 수정 및 삭제가 가능하고 추가,수정,삭제가 발생할 때마다 알림이 나오는 앱 입니다.전체적인 색상만 변경하고, 과제 영상과 비슷하게 만들었습니다. 또한 지출 항목을 입력하지 않으면 제출이 되지 않게 만들었습니다.처음 만드는 리액트 앱이라 만드는데 시간이 오래 걸렸습니다. 알림이 나오고 일정 시간이 지나면 사라지는 기능을 구현할 때 문제가 생겼었습니다. 알림이 연속적으로 추가됐을 때, 각 알림을 기준으로 3초 후에 사라져야 하는데 마지막으로 추가된 알림을 기준으로 3초 후에 첫 알림이 사라지기 시작하는 오류였습니다. 리액트라서 어려울 거라 생각하고 복잡하게 생각해서 생긴 문제로, 현재는 오류가 해결되어 잘 작동됩니다. Day10 미션 : 디즈니 플러스 앱API를 사용하여, 구글 연동 로그인을 진행하고 영화 리스트와 상세 정보를 확인하고 검색도 가능한 앱 입니다.현재 개발 중으로 아직 완성되지 않았습니다. 회고스터디 이전에 리액트 기초에 대해 조금은 공부하고 와서 개념은 알고 있는 상태였습니다.하지만 리액트를 사용하여 프로젝트를 진행한 적은 한번도 없어서 리액트 강의가 좀 어려웠습니다. 특히, API를 사용하여 개발을 해본 적이 없어 이해하기가 어려웠습니다. 그래서 과제인 디즈니 플러스 앱을 만들어 보면서 API를 사용하는 방법에 대해 자세히 알아보려고 합니다.결국 시간이 없어서 자바스크립트 관련 과제는 4개만 완성할 수 있었습니다. 그리고 지금 제 상태를 봐서는 리액트 관련 과제도 전부 완성할 수는 없을 것 같아 아쉽습니다. 과제를 진행하면서 직접 생각하고 알아보는 과정을 통해 제 실력이 늘고 있다는 것이 느껴져 스터디가 끝나고 난 후에라도 남은 과제를 만들려고 합니다.다음주 동안 최대한 리액트 과제를 열심히 만들어서 적어도 4개의 과제를 완성하고 싶습니다.

프론트엔드

Dream

[ 인프런 워밍업 클럽 Study FE 0기 ] Week 2 발자국

발자국워밍업 스터디 클럽이 2주 차에 접어들었습니다. 해당 발자국은 따라 하며 배우는 리액트 A-Z (섹션 0-5) 중심으로 작성되었습니다.요약React를 사용하려면 Node.js가 필요하다. Node.js를 설치하면 NPM도 같이 설치되니 꼭 Node.js를 설치하자. Node.js 공식 홈페이지에 접속하면 2개의 Node 버전이 있는데, 그중에서 안정적인 버전인 LTS를 설치하면 된다. Section 01. React[ React란? ]리액트는 사용자 인터페이스(user interface, UI)를 만들기 위해서 사용되는 자바스크립트의 라이브러리다. 리액트는 인터렉션이 많은 웹 앱을 개발하기 위해서 주로 사용된다. 이렇게 사용자 인터페이스를 만들기 위해 도움을 주는 TOOL로는 리액트 말고도 Vue.js와 Angular.js가 있다.React: 라이브러리Angular, Vue: 프레임워크[ Framework vs Library ]프레임워크와 라이브러리를 대략 설명하자면 다음과 같다.Framework : 어떠한 앱을 만들기 위해 필요한 대부분의 것을 가지고 있다.Library : 어떠한 특정 기능을 모듈화 해 놓은 것이다.프레임워크는 앱을 만드는데 필요한 대부분의 라이브러리를 가지고 있으며, 라이브러리들은 특정 기능을 위해 모듈화 되어있다.리액트는 라이브러리이다. 왜냐? 리액트는 전적으로 UI를 렌더링 하는 데 관여하기 때문이다. 리액트는 여러 모듈을 사용하며 앱을 관리한다.라우팅: react-router-dom …상태관리: redux, mobx …빌드: webpack, npm …테스팅: Eslint, Mocha …[ React Component ]리액트를 공부하다보면 무조건 마주치는 단어가 있다. 바로 컴포넌트이다. 리액트는 컴포넌트 기반이라고 하는데, 이 컴포넌트는 무엇을 말하는 것일까?컴포넌트(Component): React로 만들어진 웹/앱을 이루는 최소한의 단위리액트는 이 컴포넌트를 통해서 웹/앱을 개발하게 된다.리액트는 여러 컴포넌트 조각으로 되어있다. 이것은 블록같다고 생각하면 된다. 여러 블록 조각을 맞추고 쌓아 올려 하나의 블록 작품을 완성하는 것. 리액트도 마찬가지로 컴포넌트를 이리저리 조합하고 쌓아올려 하나의 웹 페이지를 구성하게 된다.리액트 컴포넌트에는 2가지가 있다.클래스형 컴포넌트함수형 컴포넌트React는 여러 컴포넌트 조각으로 구성된다.개인적인 설명을 덧 붙이자면 리액트는 레고 블럭과 같다고 생각한다. 레고 블럭들을 하나 둘 씩 쌓아 올려 하나의 완성된 레고 작품을 만드는 것이다.[ Component 종류 ]React는 2개의 컴포넌트 종류가 있다.클래스형 컴포넌트(Class Components)class App extends Component { render() { return <h1>Hello, ReactJS!</h1>; } }함수형 컴포넌트(Functioanl Components)function App() { return <h1>Hello, ReactJS!</h1>; }💡 현재 함수형 컴포넌트를 HOOK이랑 해서 많이 사용한다.💡 참고로 컴포넌트를 작성할 때 반드시 대문자 시작을 해야 한다. 소문자 시작 시 body, h1, p 같은 DOM 태그로 인식해 버린다.[ 브라우저가 그려지는 원리와 가상 돔 ]React의 가장 큰 특징은 가상 돔(Virtual DOM)이다. 이것을 사용하는 이유는 인터렉션 때문이다. 이 인터렉션에 의해 DOM에 변화가 발생하면 다시 DOM을 재구성하기 시작한다.JS 발자국에도 남겼었지만 웹 브라우저의 경우 다음과 같은 과정을 겪고 이 과정은 비용이 꽤 든다.Critical Render Path (웹 페이지 렌더링 과정): 데이터 파싱(HTML) ➔ DOM Tree 생성 ➔ CSSOM Tree 생성 ➔ JS 실행 ➔ Render Tree 생성 ➔ Layout 생성 ➔ PaintDOM을 재구성 한다는 것은 위 렌더링 과정을 다시 반복한다는 것이다. 즉, 인터렉션이 일어날때마다 위 과정을 다시 한다. 이것을 보완하기 위해서 나온 것이 가상 돔이다.가상돔 과정을 살펴보자..!데이터가 바뀌면 가상 돔에 렌더링 되고, 이전에 생긴 가상 돔과 비교를 해서 바뀐 부분만 실제 돔에 적용 시킨다.바뀐 부분을 찾는 과정을 Diffing이라고 부른다.바뀐 부분만 실제 돔에 적용 시키는 것을 Reconciliation(재 조정)이라고 부른다.[ Create React App 을 이용해서 리액트 설치하기 ]create-react-app 을 통해서 원하는 위치에 리액트를 설치할 수 있다. 이 때, Webpack과 Babel이 함께 설치가 된다. 따라서 React 앱 생성 전에 Webpack과 Babel에 대해서 간단히 알고 가자.Webpack정의: Webpack: 웹팩은 오픈 소스 자바스크립트 모듈 번들러써 여러 개로 나누어져 있는 파일들을 하나의 자바스크립트 코드로 압축고 최적화하는 라이브러리이다.장점여러 파일의 자바스크립트 코드를 압축하여 최적화할 수 있기 때문에 로딩 줄일 수 있. (네트워크 비용 줄음)모듈 단위로 개발이 가능하여 가독성과 유지 보수가 쉽다.Babel정의: 최신 자바스크립트 문법을 지원하지 않는 브라우저들을 위해서 최신 자바스크립트 문법을 구형 브라우저에서도 돌 수 있도록 변환 시켜주는 라이브러리이다.⇒ 이러한 Webpack과 Babel은 개발자가 React 개발 시 알아서 설정 해야 하지만 Create-React-App을 사용해서 React 앱을 생성하면 Babel이나 Webpack 설정이 이미 되어있기 때문에 준비 시간이 단축된다.[ Create-React-App ]프로젝트를 진행할 폴더 생성VSC에서 해당 프로젝트 폴더 열기Termial에 npx create-react-app 생성할파일명 입력강의에서는 npx create-react-app ./을 입력하였다../는 현재 위치를 뜻한다.[ npx create-react-app 에 대하여 ]npx: 노드 패키지 실행을 도와주는 도구이다.npx create-react-app이란 npm 레지스트리에 잇는 패키지를 ./에 실행시켜서 React를 설치해 주는 것이다.실행하는 방법실행하고자 하는 리액트 파일 위치에서 npm run start 입력(강의에서는 npm run start방법만 소개시켜 주셧는데 npm start도 가능하다.)🤔 개인적으로 요즘 vite에 관한 이야기가 보이는데 이도 조사해 보아야겠다… Section 2. 간단한 To-Do 앱 만들며 리액트 익히기[ create react app ]create-react-app으로 리액트를 설치하면 여러 파일이 등장하는데, 이 중에서 절대로 이름을 수정해서는 안되는 파일이 존재한다.public/index.html: 페이지 템플릿src/index.js: 자바스크립트 시작 점조심하자!💡그리고 우리가 새로 js, jsx, css 등 직접 생성할 파일들은 src 폴더에서 하면 된다. Webpack이 src/ 부분에만 작동하기 때문이라고 한다.[ package.json ]해당 프로젝트에 대한 정보들이 들어있다. 프로젝트 이름, 버전, 필요한 라이브러리와 라이브러리들의 버전이 명시되어 잇다.[ 싱글 페이지 애플리케이션(single-page application, SPA) ]싱글 페이지 애플리케이션(single-page application, SPA)은 서버로부터 완전한 새로운 페이지를 불러오지 않고 현재의 페이지를 동적으로 다시 작성함으로써 사용자와 소통하는 웹 애플리케이션이나 웹사이트를 말한다.위키백과React.js는 SPA이다. 즉, 어떠한 데이터에 관한 교체 이벤트가 발생했을 때, 서버로부터 페이지를 새롭게(html 파) 받아와 구성하는 것이 아니라 content를 바꿔치기 한다. 이는 HTML 5의 History API를사용해서 가능하게 만든다.[ History API ]전통적인 웹 사이트는 a page에서 b page로 이동할 때 a.html을 보여주다가 b.html을 보여주면 되었지만 SPA의 경우 오직 1개의 HTML(index.html)이 존재한다. 따라서 페이징 전환을 하기 위해서 HTML 5 History API를 이용한다.History.back(): 세션 기록의 바로 뒤 페이지로 이동하는 비동기 메서드History.forward(): 세션 기록의 바로 앞 페이지로 이동하는 비동기 메서드History.go(): 특정한 세션 기록으로 이동하게 해 주는 비동기 메서드History.pushState(): 주어진 데이터를 세션 기록 스택에 넣어준다.History.replaceState(): 최근 세션 기록 스택의 내용을 주어진 데이터로 교체한다.생성했던 React 프로젝트에서 public/index.js를 살펴보면 <div id="rood"></div>가 있다.그리고 src/index.js 코드에는 document.getElementById('root')라는 코드가 있다.자바스크립트 파일의 시작 점인 src/index.js에서 id값이 rood인 요소를 찾아 그곳에 해당 요소들을 렌더링하는 것이다. 즉, div라는 최상위 루트 노드 아래에 직접 정의한 요소를 더해 화면을 꾸며나가는 것이다!![ JSX ]JSX는 Javascript Syntax Extension의 약자로 자바스크립트의 확장 문법이다.리액트에서는 이 JSX를 이용해서 화면에서 UI가 보이는 모습을 나타내준다.JSX 사용이 필수는 아니나 사용하면 가독성이 너무 좋아서 필수 아닌 필수이다. (애초에 리액트 개발자들 대부분이 JSX를 사용한다고 한다.)JSX는 createElement를 쉽게 사용하기 위해서 사용한다.모든 UI를 만들때 마다 createElement를 사용해서 컴포넌트를 만들 수 없다.Ract는 React.crateElemnt API를 사용해서 엘리먼트를 생성한 후에 이 엘리먼트를 In-Memory에 저장한다. 그리고 RaectDOM.render 함수를 통해 웹 브라우저에 그린다.JSX를 사용하면 Babel이 사용한 문법을 crateElemnt로 자동 변환해준다. 따라서 그냥 개발자는 자유롭게 JSX 사용하면 된다.단, JSX는 컴포넌트에 여러 요소가 있다면 반드시 부모 요소 하나로 감싸줘야 한다.// 안된다. // 자식 요소가 여러 개 라면 부모 요소로 감싸줘라. function hello() { return ( <div>Hello, Raect!</div> <div>Hello, Wrold!</div> ); } // 이렇게 말이다. function hello() { return <div> <div>Hello, Raect!</div> <div>Hello, Wrold!</div> </div>; }💡 만약 JSX에서 JS 코드를 사용하고 싶다면 { } 내부에 작성해주면 된다.[ React와 Key ]map()을 사용한다면 언제나 명심해야 하는 것. KEY. 이것을 넣지 않는다면 에러가 발생한다.React에서 요소의 리스트를 나열할 때는 Key를 넣어줘야 한다. Key는 React가 변경, 추가 또는 제거된 항목을 식별하는 데 도움이 된다.추가적으로, 이 Key에 지정하는 값은 순회하고자 하는 목록의 아이템에 대한 ID 값이면 된다. 즉, 고유한 값이여야 한다. 정 없으면 index 넣어도 되지만 index 값은 권장하지 않는다.리액트는 가상 돔을 이용해서 바뀐 부분만 실제 돔에 적용한다. 그렇다면 리스트를 나열할 때 바뀐 부분만 어떻게 찾을까? 바로 이 key를 이용해서 어떠한 부분이 바뀌었는 인식하는 것이다.[ state ]정말 정말 중요한 개념!!!리액트에서 데이터가 변할 때 화면을 다시 렌더링 해주기 위해서 React State를 사용한다. State란 무엇일까?간단히 말해서 변수이다.단, 이 변수의 값이 변경되면 컴포넌트들이 재렌더링 된다.state에는 리액트의 흐름에 관한 데이터와 관련이 있다. Section 3. To-Do 앱 최적화 하기[ React HOOK ]엄청나게 중요하다. 이 HOOK은 클래스형 컴포넌트처럼 함수형 컴포넌트에서도 state와 생명주기 메서드를 사용할 수 있도록 해주는 메서드이다.클래스 형 컴포넌트에서는 Mounting, Updating, Unmounting 3단계 따라서 생명주기 메서드를 제공한다.Mounting: componentDidMount()Updating: componentDidUpdateUnmounting: componentWillUnmount()함수형 컴포넌트에서는 이를 위해 HOOK을 사용한다.[ HOC(Higher Order Component) ]화면에서 재사용 가능한 로직만을 분리해서 component로 만들고, 재사용 불가능한 UI와 같은 다른 부분들은 parameter로 받아서 처리하는 방법이다.HOC는 HOOK이 나오기 전에 사용했던 부분이다.Wrapper가 많아지면 흐름 파악이 어려워서 이제 잘 안 쓴다.HOC를 만들고 싶으면 Custom HOOK을 사용하자.[ HOOK ]기본적으로 알고 있어야 할 HOOK은 다음과 같다.useState()리액트의 유동적인 데이터들은 state에 담아 사용하기 위해 이용하는 HOOK클래스형 컴포넌트의 setState와 같이 state 객체에 대한 업데이트 실행단!!! state 변경 시 재 렌더링이 일어남useEffect()사이드 이팩트 처리 HOOK클래스형 컴포넌트의 생명 주기 함수 역할 수행useMemo()최적화 용 HOOK, 의존성 배열에 따라 작동의존성 배열에 있는 값이 변하면 지정한 함수를 실행하여 해당 반환 값을 반환useCallback()최적화 용 HOOK, 의존성 배열에 따라 작동의존성 배열에 있는 값이 변하면 함수를 반환useRef()요소의 참조를 위해 사용하는 HOOK[ Props ]Props는 Properties의 줄임말상위 컴포넌트에서 하위 컴포넌트로 데이터를 전송하고 싶을 경우 사용읽기 전용으로 자녀 컴포넌트에서 강제로 이 값을 변경할 수 없다.전달 받은 props가 state고 이 값을 바꾸고 싶다면 props로 set함수를 넘기고 이것을 이[ TailWindCSS ]HTML 안에서 CSS 스타일을 할 수 있게 해주는 CSS 프레임워크빠른 스타일 작업 가능id 혹은 class 명을 작성하기 위해 머리를 혹사 시키지 않아도 된다.class에 특정 키워드를 넣어서 CSS 조작정해진 속성 키워드가 워낙 많으니 공식 홈페이지 검색 필수다[ 리액트 불변성 ]불변성을 지키며 개발을 하자!참조 타입에서 객체나 배열의 값이 변할 때 원본 데이터가 변경되면 예상치 못한 오류가 발생할 수 있다.불변성을 지킬 수 있는 참조 관련 메서드:spread operator, map, filter, slice, reduce불변성을 해치는 참조 관련 메서드:splice, push[ React.memo ]React.memo는 Higher-Order Components(HOC)이다. 불필요한 컴포넌트 렌더링을 방지할 수 있게해준다. (일종의 최적화 용 HOC) Section 4-5. Netflix 앱 만들기주로 실습 내용 이었다. 정리할 이론만 추려내 보겠다.[ Styled Component ]자바스크립트 파일 안에서 CSS를 처리할 수 있게 해주는 라이브러리[ React Router Dom ]React Router DOM을 이용하면 웹/앱에서 동적 라우팅을 구현할 수 있다. 라우팅이 실행 중인 앱 외부의 구성에서 처리되는 기존 라우팅 아키텍처와 달리 React Router DOM은 앱 및 플랫폼의 요구 사항에 따라 컴포넌트 기반 라우팅을 용이하게 한다.React Router DOM을 사용하기 위해서는 몇 가지 설정을 해야한다.index.js에서 BrowerRouter로 루트 컴폰너트를 감싸준다.BrowserRouter은 HTML 5 History API를 사용하여 UI를 URL과 동기화 된 상태로 유지해준다.import { BrowserRouter } from 'react-router-dom'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <BrowserRouter > <App /> </BrowserRouter> </React.StrictMode> ); 여러 컴포넌트 생성 및 라우트를 정의한다.Routes와 Route를 사용한다.Routes: 앱에서 생성될 모든 개별 경로에 대한 컨테이너 상위 역할을 한다.Route: 단일 경로를 만드는 데 사용된다.path 속성: 원하는 컴포넌트의 URL 경로를 지정한다.element 속성: 경로에 맞게 렌더링 되어야 하는 컴포넌트를 지정한다.import { Routes, Route } from "react-router-dom"; function App() { return ( <div className="app"> <Routes> <Route path="/" element={<Home />}> <Route path="about" element={<About />} /> <Route path="contact" element={<Contact />} /> </Route> </Routes> </div> ); } +) <Link />를 통해 경로 이동하기Link 구성 요소는 HTML의 a 태그와 유사하다.to 속성은 링크가 유저를 데려가는 경로를 지정한다.앱 구성 요소에 나열된 경로 이름을 생성했기 때문에 링크를 클릭하면 경로를 살펴보고 해당 경로 이름으로 구성 요소를 렌더링한다.import { Link } from "react-router-dom"; function Home() { return ( <div> <h1>홈페이지</h1> <Link to="about">About 페이지를 보여주기</Link> <Link to="contact">Contact 페이지를 보여주기</Link> </div> ); } [ 중첩 라우팅 ]라우팅은 중첩 처리가 가능하다.[ Outlet ]자식 경로 요소를 렌더링하려면 부모 경로 요소에서 Outlet를 사용해야한다.하위 경로가 렌더링될 때 중첩된 UI가 표시될 수 있다.부모 라우트가 정확히 일치하면 자식 인덱스 라우트를 덴더링하거나 인덱스 라우트가 없으면 아무것도 렌더링하지 않는다.[ useNavigate ]경로를 바꿔준다.naviate(”/home”) ⇒ localhost:3000[ useParams ]:style 문법을 path 경로에 사용했다면 useParams()로 읽을 수 있다.function test() { return ( <Routes> <Route path="invoices/:invoiceId" element={<Invoice />} /> </Routes> ); } function Invoice() { let params = useParams(); return <h1>Invoice {params.invoiceId}</h1>; } [ useLocation ]현재 위치의 객체를 반환현재 위치가 변경될 때마다 일부 side effect를 수행하려는 경우 유용하다.[ useRoutes ]<Routes>와 기능적으로 동일하나 <Route> 요소 대신 자바스크립트 객체를 사용하여 경로를 정의한다.일반 <Route> 요소와 동일한 속성을 갖지만 JSX가 필요하지 않는다.[ Custom HOOK ]개발자가 정의하는 HOOK이다.HOOK의 이름은 use로 시작해야 한다.참고로 HOOK은 함수형 컴포넌트 또는 커스텀 HOOK에서만 호출이 가능하다.따라서 커스텀 HOOK도, 함수용 컴포넌트 또는 HOOK 내부에서 호출되어야 한다.강의에서는 useDebounce과 useOnClickOutside HOOK을 만들었다.useDebounce: input 요소에서 데이터 입력이 발생하면 설정한 set함수 때문에 매번 state 값이 바뀌고 재 렌더링이 일어난다. 따라서 keyup 이벤트의 처리를 지연시키는 커스텀 HOOK이다. (코드는 강의를 참고하자!)useOnClickOutside HOOK: 모달 창 밖의 부분을 클릭하면 해당 모달 창이 꺼지는 기능을 수행하는 HOOK이다. (코드는 강의를 참고하자!)이런 식으로 HOOK을 만들고 활용하는구나 싶었다…미션과제 총 합본 https://www.inflearn.com/blogs/7021 JS 미션 03. 퀴즈 앱[ 구현 해야하는 기능 ]1. 퀴즈 문제, 문제에 해당 하는 선택지 (선택지의 갯수가 매번 다름)2. 답 선택 시, 정답 여부에 따라 배경의 색상이 변경되어야 함문제는 data.json을 직접 작성하여 동적 생성했습니다. JS 복습 겸으로 해당 주제로 퀴즈 앱을 간단하게 만들어 봤습니다. 미션을 진행하며 문제는 없었습니다. JS 미션 04. 책 나열 앱[ 구현 해야하는 기능 ]1. 책 이름 입력 란2. 책 저자 입력 란3. 제출 버튼을 누르면 입력한 정보를 저장 함3-1. 제출 시 제출 했다는 안내 문구 떠야 함4. 제출된 데이터는 책 리스트에 출력 됨아이템은 다음과 같은 기능을 가져야 함5-1. 표기 할 데이터: 책 이름, 저자5-2. 각 아이템에는 삭제 기능이 있어야 함 구현하는데 문제가 없었습니다. REACT 01. 예산 계산기[ 구현 해야하는 기능 ]1. 지출 항목 입력 란2. 지출 비용 입력 란3. 제출 버튼을 누르면 입력한 정보를 저장 함3-1. 제출 시 제출 했다는 안내 문구 떠야 함아이템은 다음과 같은 기능을 가져야 함5-1. 표기 할 데이터: 지출 항목, 지출 비용5-2. 각 아이템에는 수정 및 삭제 기능이 있어야 함수정 버튼 클릭 시 수정 모드로 변경전체 삭제 기능이 있어야 함정말 막힘 없이 진행되다 딱 한 군데에서 문제를 맞았습니다. 상황에 맞게 알림을 띄우는 기능이었는데, JS에서는 아무런 문제 없이 해결했던 이 기능을 React에서 구현 하려고 하니 이상한 문제가 발생하더군요. 여러 동작을 해서 메시지가 많이 발생할 경우, 메시지가 예시처럼 모두 생성되는 것이 아니라 같은 자리에서 텍스트만 바뀌어서 출력이 되었습니다. 물론 잘 해결해서 과제를 마쳤습니다.회고워밍업 스터디의 2주 차에 진입하며 자바스크립트 공부를 마치고 새롭게 React 공부를 진행하며 React의 다양한 기술을 접하게 되었습니다. 특히 state, props, hook, 그리고 라우팅 부분은 처음에는 이해하기가 어려웠습니다. 그러나 부족한 이해를 보완하기 위해서 강의 내용을 정리하고, 추가적인 학습 자료를 찾아가며 개념을 확실히 파악하려고 노력했습니다.React 학습을 마치고 시작한 미션도 초반에는 막막함을 느꼈지만 코드를 작성해 나가며 수업 때 배운 내용을 적용해 가며 문제를 해결해 나갔습니다.워밍업 스터디도 이제 끝을 향해 가네요. 마무리되는 날까지 열심히 학습에 참여하고 미션 해결을 위해 도전해 보겠습니다. 

프론트엔드워밍업클럽FE

학생

[2주차 발자국] 인프런 워밍업 클럽 스터디 0기 FE

회고벌써 과정의 2/3가 끝났다는 것이 믿기지 않는다.일주일 간의 회고를 해보자면, 아쉬움이 크다. 이번주는 시간 투자를 많이 하지 못했기 때문이다.저번주에 의욕 넘치게 미션을 진행하느라 밀려났던 다른 일을 처리하는데에 또 시간을 썼다.앞으로 일이든 취준이든 제대로 하려면 시간 분배하는 법을 익혀야 한다는 생각이 들었다.직장 등의 일과 병행하는 다른 분들이 존경스러울 뿐이다.하지만 모두 끝냈기 때문에 이제는 공부에 전념할 일밖에 남지 않았다.모든 미션을 반드시 갈아치워버리겠다. 강의를 들으며 그동안 키워드만 알고 이해하지는 못하고 있었던 개념들을 접하면서 굉장히 반가웠다.특히 프로젝트를 구하는 글에서 종종 SPA 할 줄 아시는 분이라는 글을 봤었는데, 정확히 무슨 뜻인지이해를 하지는 못했었다. 하지만 이번에 공부하면서 정확히 알게 되어 상당한 쾌감을 느꼈다. 그밖에도 평소 무료 사이트의클론 코딩을 무작정 따라하면서 접했던 개념들을 짚고 넘어가게 되어 재미있었다.모닥불에 종종 들어오시는 강사님으로부터 유익한 정보를 얻으려면 질문할 거리가 있어야 한다. 질문할 거리가 있으려면 스스로의 힘으로는 알아내지 못하는 부분이 뭔지 구별할 수 있을 정도로 공부가 되어있어야 한다. 따라서 마지막 주 만큼은 진도를 잘 따라가 질문을 생성할 수 있게끔 되었으면 좋겠다. 리액트 및 프로젝트 부분은 특히나 한 번 보고는 잊어버릴 것 같으므로 여러번 공부를 해야할 것 같다. 시간은 한정되어있으므로 다음주는 선택과 집중이 필요해질지도 모르겠다. 이번주 반성공부 및 미션에 시간투자를 얼마 못함다음주 목표미션 모두 보강 및 완료하기(시간 부족하면 CSS 제외하고서라도)필수지식: API 통신, RESTful API, CRUD, CI/CD CSS flexbox, CSS Grid 공부하기Github README에 GIF(혹은 이미지)도 올리기 강의 요약이번주는 JS프로젝트로 자바스크립트를 마무리하고, 리액트를 시작했다.(자바스크립트 섹션 9 & 리액트 섹션 1 ~ 5)강의 요약은 기억에 남는 부분 위주로, 최대한 개념 부분만 진행했다.ReactReact에 관해리액트 컴포넌트가상 돔create react appSPAJSXReact StateReact HooksTailwindCSSStyled ComponentREACTReact에 관해React는 프레임워크가 아닌 라이브러리다.프레임워크: 어떠한 앱을 만들기 필요한 대부분의 것을 가지고있는것. 라이브러리를 포함.라이브러리: 특정 기능을 모듈화해놓은 것.보통 리액트와 잘 맞는 라이브러리와 함께 리액트를 사용한다.React Component리액트로 만들어진 앱을 이루는 최소한의 단위하나의 페이지를 구성하는 각각의 기능을 위한 컴포넌트가 있다.검색 컴포넌트, 프로필 컴포넌트, ...하나의 컴포넌트를 여러 곳에서 사용할 수 있다.리액트 컴포넌트의 두 가지클래스형 컴포넌트함수형 컴포넌트Virtual DOM(가상 돔)실제 DOM을 메모리에 복사해준 것.리액트의 큰 특징 중 하나는 가상 돔을 사용한다는 것.복습: 웹 페이지 빌드 과정(Critical Rendering Path CRP)DOM tree 생성(html문서를 읽고 렌더링할것 결정)Render tree 생성: DOM과 CSSOM 결합. 화면에 표시되는 모든 콘텐츠 및 스타일 정보를 포함Layout: 브라우저가 페이지에 표시되는 각 요소의 크기와 위치 계산Paint: 실제 화면에 그리기어떤 인터랙션에 의해 DOM에 변화가 발생하면 그 때마다 Render Tree가 재생성됨. 즉 모든 스타일을 다시 계산. Layout과 Repaint과정까지 계속 거치게 됨. 인터랙션이 많을 경우 불필요하게 DOM을 조작하는 비용이 너무 커짐.위의 문제로 나오게 된 것이 가상 돔.가상 돔의 작동방식 가상 돔 생성데이터 바뀌면 새로운 가상 돔 생성이전에 생긴 가상 돔과 새로운 가상 돔 비교(diffing: 바뀐 부분을 찾는 과정)바뀐 부분만 실제 돔에 적용(재조정. reconciliation)시킴가상 돔 장점: 요소가 많이 바뀌어도 한 번에 묶어서 실제 돔에 처리하여 돔을 조작하는 비용 줄임 Create React App리액트 설치를 위해 필요한 것들 Node.jsVisual Studio Code 리액트 앱 설치 방법npx create-react-app <폴더이름>폴더 안에 react app이 설치됨webpack과 babel을 모두 설정해줌.Webpack: 여러 파일을 하나로 모아주는 번들러. 로딩에대한 네트워크 비용 줄임.Babel: 최신 자바스크립트 문법을 구형 브라우저에서도 쓸수있게 변환시켜주는 라이브러리.SPA(Single Page Application)하나의 페이지에 담아 동적으로 화면 바꿔가며 표현.단일 html 내의 div id=root를 자바스크립트로 잡음.페이지 전환(브라우징)은 html5의 history API를 이용.전통적: Multi Page ApplicationReact는 SPA를 사용한다.JSX(Javascript syntax extension)자바스크립트의 확장 문법.UI를 나타낼 때 자바스크립트(logic)와 HTML(markup)구조를 같이 사용.JSX를 이용하면이벤트 처리 등을 더 편하게 구현할 수 있음.의무는 아니지만 훨씬 편리하여 거의 모든 사람이 리액트에서 UI를 위해 사용.JSX로 작성 -> babel이 createElement로 바꿔줌JSX는 컴포넌트에 여러 요소가 있다면 반드시 부모 요소 하나로 감싸야 한다.JSX Key 속성리액트에서 요소의 리스트를 나열할 때 넣어주는 값.React가 변경, 추가, 제거된 항목을 식별하는 데 도움이 됨.요소의 안정적인 ID를 부여하려면 배열 내부의 요소에 키를 제공해야 함.key에는유니크한값을 넣어야한다. index는 비추천.key를 이용하면 새로 그리는게 아니라 기존의 리스트를 이용해준다.React State컴포넌트의 렌더링 결과물에 영향을 주는 데이터를 갖고 있는 객체.컴포넌트 안에서 관리한다.setState 이용React Hooksclass 없이 state를 사용할 수 있는 기능.함수형 컴포넌트를 사용한다.클래스형 컴포넌트: 많은 기능, 길고 복잡한 코드, 느림, *리액트의 생명주기 사용 가능함수형 컴포넌트: 적은 기능, 짧고 심플한 코드, 빠름, *리액트의 생명주기 사용 불가*리액트의 생명주기: 컴포넌트의 시작, 업뎃, 언마운트까지의 주기위처럼 함수형 컴포넌트에서는 리액트의 생명주기를 사용하지 못했었다.그러나 React Hooks로 인해 함수형 컴포넌트에서도 생명주기 사용 가능해짐.리액트 훅스에서는 리액트 생명주기를 useEffect 안에서 다 처리를 해줄 수 있다.클래스형 컴포넌트에서는 마운트, 업데이트, 언마운트 함수 따로 생성.리액트 훅스는 HOC 대신 Custom React Hooks를 사용해 Wrapper 과다를 방지.TailWindCSSHTML 안에서 CSS 스타일을 만들 수 있게 하는 CSS 프레임워크.부트스트랩처럼 미리 세팅된 Utility Class를 활용하는 방식으로, html에서 스타일링을 할 수 있다.클래스 이름 짓기 등으로 골머리를 썩지 않아도 됨.Styled ComponentJavascript 파일 안에서 CSS를 처리할 수 있게 해주는 라이브러리.``를 사용하여 그 안에 스타일 속성들을 넣고, 변수에 할당한다.미션미션7(Day7). 타이핑 테스트 앱자바스크립트 섹션 9에서 다루었던 stopwatch앱을 복습하면서 구현을 시작했다.아직 미완성이고, 구현한 부분은 아래 부분이다.시작 화면index.html<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Typing Test App!</title> <link rel="stylesheet" href="style.css" /> </head> <body> <div class="wrapper"> <h1>타이핑 스피드 측정</h1> <div class="data-container"> <div id="errors"> ERRORS <h2>0</h2> </div> <div id="time"> TIME <h2>20S</h2> </div> <div id="accuracy"> % ACCURACY <h2>100</h2> </div> </div> <div id="sentence">아래를 클릭해서 게임을 시작하세요.</div> <input id="input" type="text" /> </div> <script src="script.js"></script> </body> </html>이 시작화면에서는 텍스트 입력 부분을 클릭하면 게임이 시작되도록 해야 하기에, event listener를 이용했다.// 1. 입력 부분에 클릭했을 때 게임 시작 input.addEventListener("click", startGame);게임 화면(이상하게도 글씨가 왼쪽으로 밀린다.)이 게임화면에서는, 기존에 저장되어있는 등의 문장을 표시해야 하며 카운트다운 타이머를 실행시켜야 한다.(input과 sentence는 코드 맨 위에 document querySelector로 가져와 지정했으나 여기선 생략함. let i, err...도.)const startGame = () => { i = 0; err = 0; sec = 20; acc = 0; interval; input.removeEventListener("click", startGame); // 1-1. 문장 보여주기 sentence.textContent = sentences[i]; // 1-2. 시간초 카운트다운 시작 interval = setInterval(timer, 1000); ...const timer = () => { sec -= 1; timeH2.innerText = `${sec}S`; if (sec === 0) { gameEnd(); } };여기서 stopwatch 프로젝트에서 배웠던 setInterval를 사용하였다.끝 화면(배치가 좀 그렇다)시간 초과가 나거나 주어진 문장을 모두 입력할 경우 이 화면으로 온다. 여기서 clearInterval를 사용하였다.const gameEnd = () => { clearInterval(interval); // 3. 타임 오버 혹은 문장 전부 클리어 // 다시 시작 버튼 활성화이 아주 사소한 부분 해결 과정에서 하고자 하는 것은 setInterval과 clearInterval의 복습이다.결론setInterval()은 주어진 함수를 주어진 간격마다 실행하는 함수이다.clearInterval()은 주어진 interval의 반복을 중단하는 함수이다.예시: hello를 1초마다 콘솔에 반복 출력하는 함수const sayHello = () => { console.log("hello"); } let interval; setInterval(sayHello, 1000); clearInterval(interval); // 반복 중단

프론트엔드

Dream

[ 인프런 워밍업 클럽 Study FE 0기 ] Week 1 발자국

들어가기 앞서...2024년의 첫 해가 밝으며, 지금까지는 단순히 관심만 갖고 있었던 웹 개발에 대한 공부를 시작해보기로 결심했습니다. 먼저 HTML과 CSS의 공부를 마치니 운이 좋게 인프런에서 JS와 ReactJS 스터디를 진행한다는 소식을 듣게 되었습니다. 이런 좋은 기회를 놓치지 않겠다고 생각하고, 워밍업 클럽에 참여하게 되었습니다.발자국OT를 참가한지 엊그제 같은데 시간은 정말 순식간에 지나가는 것 같습니다. 벌써 스터디가 시작된 지 1주차가 되었습니다. 이제 그 동안의 강의 내용을 간단하게 요약하고, 회고를 남겨 보려고 합니다. 이번 주 강의는 따라하며 배우는 자바스크립트 A-Z (섹션 0~8) 부분을 진행하였습니다.요약Section 01. 자바스크립트 기초[ Console 객체 ]자바스크립트의 console 객체는 코드를 작성하고 테스트를 할 때, 사용하기 좋은 함수를 제공해준다. 다음은 강의에서 소개한 주요 Console 객체의 함수들이다.console.log(): console에 메시지를 출력한다. console.table(): console에 배열이나 객체의 데이터를 테이블 형태로 출력한다. console.error(): console에 에러 메시지를 출력한다. console.warn(); console에 경고 메시지를 출력한다. console.time(), console.timeEnd(): 세트로 사용되며, 두 함수 사이의 코드 실행 시간을 측정한다. [ var, let, const과 스코프 ]변수/상수를 선언할 때 let, const 그리고 var 키워들 사용한다. let과 const는 ES6에 새롭게 추가된 키워드이다. var 키워드는 오래된 선언 키워드로 let과 const 사용을 권장하고 있다.let: 변수 키워드, 재선언 X, 재할당O const: 상수 키워드, 재선언 X, 재할당Xvar: 재선언 O, 재할당 O 그리고 사용한 let/const와 var 키워드에 따라 스코프가 다르게 처리된다. 스코프(scope, 유효/참조 범위)란 어떠한 변수를 참조하려고 할 때, 그 변수에 접근 가능한 유효 범위이다.let/const: 모든 코드 블록 { } 내부에서 선언된 변수는 코드 블록 내에서만 유효. var: 함수 내에서 선언된 var 변수는 함수 내에서만 유효하며, 함수 내에서 블록 내·외부에 관계없이 접근 가능. [ 호이스팅 ]코드가 실행되기 전에 변수 및 함수 선언을 로컬 범위(유효 범위)의 맨 위로 끌어 올려지는 경우를 말한다.[ 자바스크립트 타입과 타입 변환 ]자바스크립트의 데이터 타입(자료형)은 다음과 같다.원시 타입: Boolean, String, Number, null, undefined, Symbol고정된 크기로 Call Stack 메모리에 저장실제 데이터가 변수에 할당참조 타입: Object, Array데이터 크기가 정해지지 않고 Call Stack 메모리에 저장데이터의 값이 Heap에 저장되며 메모리의 주소 값이 할당 자바스크립트 변수에 저장된 값은 다른 데이터 유형으로 변환될 수 있다.명시적 데이터 변환(개발자가 직접 함수를 사용해서 변환)자동 데이터 변환(자바스크립트 자체에 의해 자동으로 변환) [ 연산 및 Math ]자바스크립트에서는 기본적인 산술 연산자, 논리 연산자, 비교 연산자를 제공한다.Math를 통해 더 많은 연산을 이용할 수 있다. [ Template Literals]Backtick(`)을 사용하여 문자열을 표현한 것을 템플릿 리터럴이라고 한다. 템플릿 리터럴을 이용하면 다음과 같은 이점이 있다.줄 바꿈이 쉽다.${}을 사용하여 내부에 표현식을 포함할 수 있게 한다. [ Loops ]for: 초기식, 조건식, 증감식을 포함하는 반복문으로 주어진 조건이 참일 경우 블록 안의 코드를 반복 실행for/in: 객체의 열거 간으한 속성들을 반복하는데 사용.while: 주어진 조건이 true일 동안 코드 블록을 계속해서 실행.do/while: 먼저 코드 블록을 실행한 후, 조건을 확인한다. 그러고 나서 조건이 true일 동안 반복 실행한다. Section 02. Window 객체 및 DOM[ Window 객체 ]브라우저에 의해 자동으로 생성된다. (자바스크립트 객체 X, 브라우저에서 제공 O)이 window 객체는 다음과 같은 역할을 수행한다.브라우저에 접근 및 조작 가능자바스크립트 코드의 전역 객체 역할 [ DOM ]문서 객체 모델(Document Object Model, DOM)요소로 이루어진 HTML 파일을 Tree 구조로 표현한 객체 모델최상단에는 document 노드가 위치해 있으며, 이를 통해 DOM 접근 및 조작 가능Critical Render Path (웹 페이지 렌더링 콰정)데이터 파싱(HTML) ➔ DOM Tree 생성 ➔ CSSOM Tree 생성 ➔ JS 실행 ➔ Render Tree 생성 ➔ Layout 생성 ➔ Paint +) 강의에서 수 많은 Property 및 Method를 소개해 주셨지만 너무 많은 관계로 생략... Section 03. Event[ Event ]만약 인프런에서 로그인 버튼을 누르면 무엇이 일어날까? 당연히 로그인 페이지로 이동할 것이다. 이렇게 웹 페이지에서 발생하는 사용자의 행동에 대응하여 브라우저에서 일어나는 특정 사건을 "이벤트"라고 한다. 자바스크립트에서는 다음과 같은 이벤트가 존재한다.UI 이벤트load, change, resize, scroll, error 키보드 이벤트keydown, keyup, keypress마우스 이벤트click, dblclick, mousedown, mouseout, mouseover, mousemove, mouseup포커스 이벤트focus, blur폼 이벤트input, change, select, reset, submit, cut/copy/paste 이벤트를 등록하기 위해서는 addEventListener()를 사용하면 된다. 또한 이벤트 흐름에는 이벤트 bubbling과 Capturing라는 2가지의 기본 모델이 존재한다.[ Event Bubbling과 Event Capturing ]이벤트 bubbling은 가장 깊게 중첩된 요소에 이벤트가 발생했을 때, 이벤트가 위로 전달 되는 것을 의미한다. 이벤트 bubbling은 target 이벤트에서 시작해서 요소를 거쳐 document 객체를 만날 때까지 각 노드에서 모두 발생한다. 만약 bubbling 중단을 원한다면 event.stopPropagation()을 호출하면 된다.event.stopPropagation()DOM Tree를 통한 이벤트 흐름 중지 가능브라우저 기본 동작은 취소 X 이벤트 Capturing은 bubbling과 다르게 제일 상단에 있는 요소에서 아래로 이벤트가 내려오는 것을 말한다.[ Event Delegation ]이벤트 bubbling과 이벤트 Capturing을 통해서 이벤트 위임을 이해할 수 있다. 이 이벤트 위임은 '하위 요소의 이벤트를 상위 요소에 위임하는 것'이다. Section 04. 자바스크립트 중급[ this]Method의 this: 해당 객체를 가리킨다.함수에서 this: window 객체를 가리킨다.constructor의 this: 빈 객체를 가리킨다. [ bind, call, apply]call():함수를 호출하는 함수.첫 번째 인자 값으로 어떠한 것을 전달해 주면 호출되는 함수의 this가 인자 값으로 지정apply(): call()과 유사하나 인수 부분에 배열을 넣어줘야함.bind(): 해당 함수가 지정한 인자 값을 가리키도록 하지만 call(), apply()와 다르게 직접 함수 실행 X [ 삼항 연산자 ]다음과 같은 구문을 갖는다.조건 ? true이면 반환 : false이면 반환 [ Event Loop]자바스크립트는 동기 언어이다. 하지만 가끔 비동기로 작동하는 setTimeout()를 사용하는 예시를 볼 수 있다. 자바스크립트는 비동기 코드를 작성하기 위해서 자바스크립트 이외의 도움을 받는다.[ Closure ]다른 함수 내부에 정의된 함수가 있는 경우, 외부 함수가 실행을 완료하고 해당 변수가 해당 함수의 외부에서 더 이상 엑세스할 수 없는 경우에도, 해당 내부 함수는 외부 함수의 변수 및 액세스가 가능하다. 이 기능을 Closure라고 부른다.[ 구조 분해 할당 ]배열이나 객체의 속성을 해제하여 그 값을 개별 변수에 담을 수 있게 해주는 표현 식이다.[ Map, Filter, Reduce ]Map, Filter, Reduce은 배열 메서드의 대표적인 예시이다.map(): 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출하고 나온 결과를 모아 새로운 배열로 만들어 반환한다.filter(): 주어진 함수의 필터를 통과하는 모든 요소를 모아 새로운 배열로 반환한다.reduce(): 배열의 각 요소에 주어진 리듀서(reducer) 함수를 실행하고, 하나의 결괏값을 반환한다.[ 얕은 비교 VS 깊은 비교 ]숫자, 문자열 등 원시 자료형은 값을 비교하게 된다. 하지만 배열, 객체 등의 참조 자료형은 참조되는 위치를 비교하게 된다. 얕은 비교를 하게 되면 원시 값의 경우 문제가 없지만 참조 값의 경우 실제 값이 아닌 저장된 위치(참조 값)이 비교되기 때문에 문제가 된다.깊은 비교를 사용하게 되면 참조 자료형도 실제 값으로 비교할 수 있게 된댜ㅏ.객체 depth가 깊지 않은 경우: JSON.stringify() 사용객체 depth가 깊은 경우: lodash 라이브러리의 isEqual() 사용[ 얕은 복사 VS 깊은 복사 ]위에서 정리한 내용처럼 복사에도 문제가 발생하게 된다. 따라서 참조 자료형의 값의 경우 깊은 복사를 사용하면 된다.JSON.stringify()lodash 라이브러리의 deepCopy[ 함수 표현식, 함수 선언문 ]함수 선언문: 함수 선언은 함수를 만들고 이름을 지정하는 것이다.일반적인 함수 선언 방식으로 function 키워드와 식별자를 표기하여 사용한다.함수 표현식은 함수를 만들고; 변수에 할당하는 것이다.익명 함수(function 키워드는 사용했으나 식별자 X), 화살표 함수 사용 Section 05. OOP[ OOP ]OOP(Object-Oriented Programming, 객체 지향 프로그래밍)란 Java 및 C를 비롯한 많은 프로그래밍 언어의 기본이 되는 프로그래밍 패러다임이다. 완전 간단하게 말하자면 객체 지향 프로그래밍은 객체들의 모임이라고 할 수 있다.OOP 특징으로는 다음과 같다.추상화:불필요한 정보는 숨기고 중요한 정보 만을 표현함으로써 프로그램을 간단히 만드는 것.상속:새로운 클래스가 기존의 클래스의 자료와 연산을 이용할 수 있도록 해주는 것.기존 클래스: 부모 클래스, 상위 클래스새로운 클래스: 자식 클래스, 하위 클래스다형성: 하나의 틀을 가지고 여러 개의 다양한 형태를 만드는 것이다.overriding을 통하여 다형성 구현 일반적인 코드를 재사용하고 작성할 수 있다.캡슐화:클래스 안에 있는 Method, 변수 등을 하나로 묶어준다. [ class와 constructor ]class에서는 constructor라는 특별한 메서드를 제공한다. 이 constructor는 생성자로, 인스턴스화된 객체에서 다른 메서드를 호출하기 전에 수행해야 하는 사용자 지정 초기화를 할 수 있게 해준다.클래스를 new 키워드를 붙여 인스턴스 객체로 생성하면 넘겨 받은 인자 값과 함께 constructor가 가장 먼저 실행이 된다. 따라서 이 곳에 초기화를 해야 하는 작업을 수행한다.[ Super]자바스크립트에서 super는 다음과 같은 역할을 수행한다.자식 클래스 내에서 부모 클래스의 생성자를 호출할 때 사용한다.자식 클래스 내에서 부모 클래스의 메소드를 호출할 때 사용한다. Section 06. 비동기[ 동기와 비동기 ]동기(Synchronous)코드를 순차적으로 실행하는 것. 즉, 한 작업이 끝나기를 기다렸다가 끝나면 다음 작업을 수행한다.각 작업이 완료될 때까지 다음 작업이 실행되지 않는다.비동기(Asynchronous)작업이 종료되지 않아도 다음 작업을 진행할 수 있는 방식비동기적인 코드는 특정 작업을 기다리지 않고 다음 작업을 계속 수행한다. [ Callbacks, ES6 Promise, ES7 Async / Await ]callbacks콜백 함수는 특정 함수에 매개변수로 전달된 함수를 의미한다.콜백 함수는 함수를 전달 받은 함수 내부에서 호출된다.단, 콜백 지옥을 맛볼 수 있다.Promise자바스크립트 비동기 처리에 사용되는 객체이다.new 키워드와 생성자를 사용해서 만들며, 생성자의 매개변수로 실행 함수를 전달한다.new Promise(실행함수) 실행 함수의 1번째 매개변수 resolve는 비동기 작업 성공 값이다.실행 함수의 2번째 매개변수 reject는 작업 실패 값이다.Promise는 다음 중 하나의 대기 상태를 갖는다.대기, 이행, 거부단, 체인 지옥이 시작된다...Async / Await비동기 코드를 마치 동기 코드처럼 작성할 수 있도록 해준다.Promise에서 than 체인 형식으로 호출하는 것보다 가독성이 좋다.await는 async 함수에서만 사용 가능하다.동기식 코드에서 사용하는 try...catch 문을 사용할 수 있다. Section 07. Symbol, Iterator, Generator[ Symbol ]ES6에 새롭게 추가된 원시 타입으로, 유니크한 식별자를 만들기 위해서 사용.단, for...in과 getOwnPropertyNames에서 제외 된다.Symbol 사용 시 기본적으로 Property가 숨겨진다. (찾을 수 있는 방법 有)따라서 for...in과 getOwnPropertyNames에서 symbol로 만든 Property가 안보인다.[ Iterator, Generator ]Iterator대표적인 예시로 배열이 있다.반복 가능한 것을 Iterable하다고 한다. for…of를 이용할 수 있다.[Symbol.iterator()] 값을 가지고 있다.Generator사용자의 요구에 따라 일시적으로 정지할 수 있고, 다시 시작할 수 있는 특별한 기능을 가지고 있다.function다음에 Asterisk (애스터리스크)를 붙인 형태로 사용한다.function*yield 키워드를 이용한다: 제너레이터 함수의 실행을 일시적으로 정지시킴. Section 08. Design Pattern[ 디자인 패턴 ]디자인 패턴은 개발자가 응용 프로그래밍나 시스템을 디자인할 때 일반적인 문제를 히결하는 데 사용할 수 있는 공식화된 모범 사례이다.- 위키 피디아다음과 같은 장점이 있다.최고의 솔루션재사용성풍부한 표현력향상된 의사 소통필요없는 코드 리팩토링코드베이스 크기 감소[ 디자인 패턴 종류 ]Singleton Pattern: 클래스의 인스턴스화를 객체 1개로 제한하는 디자인 패턴Factory Pattern: 비슷한 객체를 반복적으로 쉽게 생성하게 해주는 디자인 패턴Mediator Pattern(중재자 패턴): 객체 그룹에 대한 중앙 권한을 제공해주는 디자인 패턴Observer Pattern: event-driven 시스템을 이용하는 디자인 패턴Module Pattern: 코드를 더 작고 재사용 가능한 조각으로 분할하게 해주는 디자인 패턴 미션완벽히 해결한 미션은 다음과 같습니다.음식 메뉴 앱음식 메뉴 앱 미션은 주어진 카테고리에 해당되는 메뉴를 출력하는 웹을 구현하는 것이었습니다. 저는 카페 메뉴를 주제로 해당 웹을 구현했습니다. 다만 출력할 아이템에 대한 DB가 없어서 직접 data.json을 작성하여 처리했습니다. 미션을 해결하면서 기능 구현에는 특별한 문제가 없었으나 기능 구현보다 데이터 파일 생성이 더 오래 걸린 미션이었습니다... (출력되는 메뉴 이미지는 스타벅스 이미지를 활용했습니다.) 가위 바위 보 앱플레이어와 컴퓨터가 가위 바위 보를 하는 게임을 구현하는 미션입니다. 총 10번의 기회가 주어지며 게임에 대한 스코어 제공 및 승패 결과를 제공해야 했습니다. UI를 어떻게 구현할까 고민하다가 이미지를 추가적으로 더 넣어 구성했습니다. 컴퓨터의 가위 바위 보 선택지는 Math.random()을 이용해 처리했으며, 기능 구현에는 특별한 문제는 없었습니다.회고자바스크립트 강의를 들으며 기초를 다지고 그 지식을 바탕으로 주어진 미션을 해결하는 한 주를 보냈습니다. 특히 웹 개발이 처음이라서 미션을 해결해 나가는 시간이 정말 흥미로웠습니다. 앞으로 워밍업 클럽 Study를 진행하며 제가 얼만큼 발전할 수 있는지 궁금해지기도 합니다. 남은 기간 최선을 다해서 임해보겠습니다!

프론트엔드워밍업클럽

Inje Lee (소플)

프론트엔드 지식 포털 소개 및 리덕스 문서 업데이트

안녕하세요, 소플입니다 😀여러분들에게 도움이 될 만한 몇가지 새소식을 전달드립니다!프론트엔드 지식 포털 소개최근에 제가 프론트엔드 지식 포털 사이트를 만들었습니다.사이트 이름은 FrontOverflow이고 주소는 아래와 같습니다.https://www.frontoverflow.com/사이트를 간단하게 소개하면 'Front-end 계의 StackOverflow' 라고 생각하시면 됩니다.한국어를 기본 언어로 하며, 프론트엔드와 관련된 질문과 답변을 자유롭게 할 수 있습니다.초반에 올라오는 모든 질문들에 대해서는 제가 직접 답변을 달아드릴 예정이니,개발하면서 막히거나 어려운 부분이 있다면 주저하지말고 편하게 질문 올려주세요!(프론트엔드 아키텍처, 컴포넌트 설계 등의 질문도 환영합니다 😀)리덕스 문서 업데이트그리고 최근에 출시한 처음 만난 리덕스 강의와 관련해서,실습 파트를 제외한 모든 강의 내용을 담은 문서를 FrontOverflow에 정리해두었습니다.강의를 수강한 분들은 복습하는 용도로 사용하시면 되고,수강하지 않으신 분들도 개인적으로 리덕스를 학습하는 용도로 사용하시면 분명 도움이 될 겁니다.강의 문서는 아래 링크에서 확인이 가능합니다.🔗 처음 만난 리덕스 강의 문서 보기 모든 수강생 분들의 성장을 응원합니다! 🎉감사합니다.

프론트엔드리액트리덕스프론트엔드ReactReduxFrontend

nextjs는 typescript가 무섭대요

서론어느 한 겨울의 이야기 입니다. 그는 nextjs와 함께 즐겁게 코드를 짜고 있었습니다. 어느 때와 같이 리덕스 스토어에 사용되는 union type을 수정하고 저장을 한 다음 정상적으로 컴파일된 걸 확인합니다.그 순간 그의 등줄기를 타고 소름이 돋습니다. 무언가 이상함을 느낍니다.그는 스크롤을 내립니다. 드르륵- 드드륵- 한 오브젝트가 보입니다. 그는 떨리는 눈으로 오브젝트의 타입을 봤습니다. mapped type, 그는 오래 전에 어느 타입을 이 오브젝트의 키로 사용할 수 있게 만든겁니다. 그렇습니다. 그가 방금 수정한 타입이었습니다. 그는 이윽고 오브젝트를 선명하게 가로지르는 구불구불한 빨간색 선을 보게 됩니다.그는 키보드에 툭 떨어진 식은땀을 볼 틈도 없이 모니터에 온 신경을 집중합니다. 이게 무슨, 타입 에러가 있다면.. 대체 어떻게 컴파일이 된거지? 으아악! ...... 이라는 괴담을 아시나요?대부분 타입을 등한시한 타입스크립트의 저주라고 웃고 넘기지만 사실 더 큰 비밀이 숨겨져 있습니다.사실 nextjs는.. 타입 체킹을 안합니다!!!! 으아아악!dev와 타입 체킹nextjs가 타입 체킹을 지원하지 않는다니 이게 무슨 소리인가요, 빌드에서 타입 에러가 뜨는 걸 이 두 눈으로 똑똑히 봤는데!여러분의 말이 맞습니다. 빌드 때 타입 에러가 잡힙니다. 그렇다면 dev는 어떨까요? 위의 오싹오싹한 괴담과 같은 상황을 만들고 저장을 해보겠습니다.new의 경우를 입력하지 않았습니다. 여러분은 someObject를 가로지르는 빨간 선을 보게 될 겁니다. 타입 에러가 발생했습니다!터미널에는 어떤 일이 일어났을까요?우리의 dev는 그런 건 상관하지 않습니다. 미동없이 고요한 터미널을 볼 수 있을 겁니다.맞습니다. dev는 타입 체킹을 하지 않습니다. 이럴수가...nextjs는 fast refresh가 필요해요모든 일은 nextjs 9.4에서 fast refresh가 정식으로 적용되며 일어났습니다. 기존의 핫 리로딩 방식은 변경이 생길 때마다 앱 전체를 리로드 했습니다. 이런 방식은 느리고 에러 해결에도 좋지 않았습니다. 그걸 극복하기 위해 등장한 것이 fast refresh 입니다.좋은 변화였습니다. 수정한 코드로 인한 변화를 즉각적으로 확인할 수 있음과 더불어 더 정확하게 런타임 에러를 확인할 수 있게 되었습니다. 그런데요, 문제가 발생합니다. 타입 체킹은 너무 시간이 오래 걸렸던 겁니다. 최대한 빠른 리로딩 경험을 제공하고 싶었던 nextjs는 타입 체킹을 빼 버립니다!이를 되돌리는 옵션도 제공하지 않았습니다. nextjs 개발자 분들의 의지는 확고했던 겁니다.우리는 타입 체킹이 필요해요그 확고함과는 달리 항상 typescript의 든든함에 기대고 있던 저는 수정한 즉시 진행되는 타입 체킹이 그리웠습니다. 하지만 nextjs의 버전이 13이 될 때까지도 타입 체킹 지원은 까마득히 멀기만 합니다. 방법을 찾아야만 합니다. 타입 체킹을 다시 불러낼 방법을요. 다행히 저와 같은 생각을 가지고 있는 분들이 꽤 있었습니다.여러분들에게 두가지 방법을 소개합니다.vscodetypescript.tsserver.experimental.enableProjectDiagnosticsvscode는 자체적으로 타입 체킹을 지원하지만 열려있는 파일만 가능합니다. 그렇다면 모든 파일을 체크하게 만든다면 어떨까요?typescript.tsserver.experimental.enableProjectDiagnostics가 가능하게 합니다. 프로젝트의 파일들을 열지 않아도 발생하는 에러를 확인할 수 있게 만들어 줍니다.다만 이 기능은 실험적입니다. 에러들이 발생할 가능성이 높으며 개선될 여지는 낮습니다.tasksvscode의 tasks를 사용하는 방법도 있습니다. tasks는 실행 중 발생한 에러를 Problems view에 띄워줄 수 있습니다. 이를 통해 tsc를 실행하면 어떻게 될까요?tsc로 변경된 파일들을 감시하고 발생한 오류를 Problems view에 표시되게 만들 수 있습니다.terminal잠시만요, 타입 체킹 후 발생한 에러를 vscode를 통해 확인하는 게 마음에 들지 않는 경우는요? 수상할 정도로 터미널을 사랑하는 분들은 오직 터미널에서 모든 걸 확인하고 처리하고 싶을 겁니다.그렇다면 이 방법을 사용하세요.concurrently 패키지는 명령어의 동시 실행과 함께 [TS]와 같은 접두사로 어떤 명령어에서 나온 로그인지 구별하기 쉽게 만들어 줍니다. 이를 사용해 nextjs dev 서버와 tsc를 동시에 실행시켜 로그를 확인할 수 있습니다.TMItsconfig.json을 확인하세요tsconfig.json가 다음처럼 설정되어 있는지 확인하세요.noEmit이 true가 되어야 출력 파일을 만들지 않습니다. tsc를 타입 체킹의 용도로만 사용할 것이기 때문입니다incremental이 true여야 incremental compilation이 됩니다. 속도가 더 빠릅니다타입 에러 발생 시 중단은 안됩니다 사실 타입 에러가 발생했을 때 앱의 실행을 막고 싶었습니다. 무심코 지나치는 일 없이 확실히 해결할 수 있게요!안타깝게도 그런 방법은 찾을 수 없었습니다. nextjs 자체에서 지원해야 될텐데 현재로서는 가망이 없다고 생각이 듭니다. 타입 체킹 자체가 굉장히x3 빨라지는 날이 온다면 가능할 수도 있지만요! 그 날이 오기까지는 마음 한 켠에 담아두는 걸로 했습니다. 흑흑...도움이 되었나요?되었다고요? 다행입니다!!날씨가 아직도 꽤 춥네요. 오늘도 따뜻하고 즐거운 개발이 되셨음 합니다.Referencetasks[Tasks in Visual Studio Code](https://code.visualstudio.com/Docs/editor/tasks#_examples-of-tasks-in-action)[Visual Studio Code Tasks Appendix](https://code.visualstudio.com/docs/editor/tasks-appendix)[Blog - Next.js 9.4 | Next.js](https://nextjs.org/blog/next-9-4)(https://github.com/microsoft/vscode/issues/13953)[TypeScript: Documentation - tsc CLI Options](https://www.typescriptlang.org/ko/docs/handbook/compiler-options.html)[enableProjectDiagnostics problem · Issue #168410 · microsoft/vscode](https://github.com/microsoft/vscode/issues/168410)[Feature Request: Show all errors and warnings in project for all JavaScript and TypeScript files, not just opened ones · Issue #13953 · microsoft/vscode](https://github.com/microsoft/vscode/issues/13953)[Typescript \`next dev\` error reporting · Discussion #33634 · vercel/next.js](https://github.com/vercel/next.js/discussions/33634) 

프론트엔드nextjstypescriptvscode

HTML 주요 태그 정리_2

HTML 주요 태그 정리 -2   이번에는 <form> 태그에 대해서 알아보겠습니다. form은 <body>안에 사용하는 태그로 사용자가 웹사이트로 정보를 보낼 수 있는 요소들은 모두 form이라고 할 수 있습니다.  속성을 이용해서 사용자가 입력한 데이터를 어떤 방식으로 서버에 넘길지 어떤 프로그램을 사용하여 처리하는 지를 정할 수 있습니다. 그럼 form과 같이 사용하는 속성에 대해 알아보겠습니다. action 속성 : form이 전송되는 서버 url 즉, 주소를 지정하는 속성입니다. name 속성 : form의 이름으로 서버로 제출된 form데이터를 참조하거나 form요소를 참조하기 위해서 사용됩니다. method 속성 : 말 그대로 전송방법을 설정하는 속성입니다.   다음으로 <form>태그 하위에 같이 사용되는 태그들을 알아보겠습니다. 내용을 입력하는 <textarea></textarea> 태그는 여러줄의 글을 입력할 때 사용한 태그입니다.  속성값으로 rows와 cols를 사용하여 너비를 조정할 수 있습니다.  이런식으로 글씨를 입력하는 입력창을 생성할 수 있습니다.   다음으로 가장 많이 사용되는 <input>태그에 대해 알아보겠습니다. <input>태그는 여러 속성을 사용하여 서버로 전송하는 형식과 이름을 지정하게됩니다. 사용되는 속성으로는 name, type등이 있습니다. name속성 : 서버로 전송되는 데이터의 이름을 정해줍니다. type속성 : 입력 형식을 지정합니다. 예를들어 <input>태그는 회원가입을 할 때 사용할 수 있습니다. 아이디 입력 : <input type="text" name="id" size = "10"> <br> 비밀번호 입력 : <input type="password" name="pw" size="10"> <br> 이런식으로 작성해주게 되면, 아이디  입력부터 살펴보게 되면,  type은 text형식이며 서버에 보낼 때 데이터의 이름은 id로 설정한 것을 알 수 있습니다. size는 위에 설명은 안했지만 말 그대로 크기를 지정해준다고 생각하면 됩니다. 비밀번호 입력을 살펴보면 type이 아이디입력과는 다르게 password로 되어있는 것을 알 수 있는데 password 형식은 입력했을때 ●이런 형식으로 나와 입력한 비밀번호를 문자그대로가 아닌 저렇게 암호화되어 나오는 것을 알 수 있습니다. 서버로 보낼 때 이름은 pw로 설정한 것을 알 수 있습니다.    다음으로는 더 다양한 type을 알아보겠습니다. 먼저 아래의 코드를 보겠습니다. <input type="submit" value="회원가입 완료"><br> <input type="reset" value="초기화버튼입니다 조심"> 위에 코드의 type은 submit으로 서버로 데이터를 전송하는 제출버튼입니다. 어떤 서버로 제출하는지에 대해서는 위에 설명한 form태그 속성인 action속성값으로 지정한 서버 주소로 보내게 됩니다. value는 버튼에 나타낼 텍스트를 입력해줍니다.  reset type은 입력한 모든 창을 초기화 해주는 속성을 가지고 있습니다.  이런식으로 버튼이 생기게 됩니다.    버튼에 대해 더 알아보도록 하겠습니다.  대표적으로 체크박스 버튼, 라디오 버튼, 드롭다운 버튼이 있습니다.  체크박스 버튼은 다중 선택이 가능하고 라디오버튼은 단일 선택입니다. 드롭다운 버튼은 선택형버튼이라고 생각하시면 됩니다. 그 전에  <label></label>태그를 소개해드리겠습니다. <label>태그는 for 속성을 사용하여 다른 요소와 결합이 가능하며 결한 요소와 id값이 같으면 입력창을 선택하지 않고 텍스트부분만 손택해도 입력창으로 커서를 이동할 수 있습니다. 말이 어려운데 쉽게 이야기 하면 <label>로 텍스트를 감싸고 for속성으로 속성값을 정해주고 <input>태그에 id속성을 이용해서 속성값을 정해줍니다. 그리고 for의 속성값과 id속성값을 같게 설정해주면 된다는 뜻인데 예시로 좀더 자세히 보겠습니다.  <label for="user_name">이름 입력 : </label> <input type="text" id="user_name" size="10"> 위 두 코드를 보면 for과 id속성값을 "user_name"으로 같게 설정해주었습니다.  그럼 위와같은 결과화면을 볼 수 있을텐데 그럼 옆의 입력창을 직접누르지 않고도 이름 입력이라는 텍스트를 눌러도 입력창에 커서가 깜빡이는 것을 확인할 수 있습니다. 이런 <label>태그는 버튼에서 사용하면 유용할꺼 같아서 이렇게 버튼설명 전에 정리했습니다. 그럼 먼제 체크박스 버튼에 대해서 알아보겠습니다 .   <input type="checkbox" name="code" value="java">Java <br> <input type="checkbox" name="code"  value="python">Python <br> <input type="checkbox" name="code"  value="react">React <br> <input type="submit" value="전송"> type의 속성으로 checkbox를 주게 되면 아래와 같은 결과화면을 얻을 수 있습니다.     버튼 이름은 value의 속성값으로 지정했으며, 다중 선택이 가능함을 확인할 수 있습니다. 다음으로는 라디오 버튼을 알아보겠습니다.  <input type="radio" name="code" value= "Java"> 자바 <br> <input type="radio" name="code" value= "Python"> 파이썬 <br> <input type="radio" name="code" value= "JSP"> jsp <br> 단일 선택이 되는것을 확인할 수 있습니다. 마지막으로 드롭다운 버튼을 확인하겠습니다. <select> <option value = "Java">자바</option> <option value = "Python">파이썬</option> <option value = "JSP">jsp</option> </select> 드롭다운 버튼은 <option></option>태그를 이용하여 사용할 수 있습니다.  이 처럼 작성하면 아래로 목록이 펼쳐지면서 목록을 선택할 수 있습니다. 단, 역기서의 value값은 서버로 넘길 값을 지정하는 것입니다.  또한 <option>태그 사용을 위해서는 상위 태그로 <select>태그를 사용하여 감싸줘야 합니다.   추가적으로 버튼이나 입력창 또는 input으로 값을 입력 받을때 사용하면 유용한 속성 placeholder에 대해 알아보겠습니다, placeholder은 처음에 어떤식으로 입력하라는 식의 가이드식으로 입력창에 표기하는 용도로 사용됩니다 . 하지만 어떤 값도 아니고 입력을 하면 지워지는 것을 확인할 수 있습니다. <input type="text" placeholder = "이름을 입력하세요." id="user_name" size="30" /> <br> 가이드를 위해 사용하면 사용자들이 편하게 이용할 수 있는 속성인거 같습니다.   이상으로 HTML에서 자주사용 태그들을 정리 해보았습니다. 다음에는 간단하게 CSS에 대해 배운것을 정리해보겠습니다.    ※제가 공부하면서 참고할려고 만든 블로그라 많이 미숙합니다. 혹시 제가 놓친부분이나 수정할 부분 댓글 남겨주시면 반영하겠습니다. 감사합니다.      

프론트엔드HTML태그