프레임워크 없이 프로그레시브 웹 애플리케이션 설계 및 구축(1부)
게시 됨: 2022-03-10웹 애플리케이션은 실제로 어떻게 작동합니까? 최종 사용자의 관점에서 말하는 것이 아닙니다. 기술적인 의미에서 말입니다. 웹 애플리케이션은 실제로 어떻게 실행됩니까? 무엇이 시작되는가? 상용구 코드 없이 애플리케이션을 구성하는 올바른 방법은 무엇입니까? 특히 모든 논리가 최종 사용자 장치에서 실행되는 클라이언트 측 응용 프로그램입니다. 데이터는 어떻게 관리되고 조작됩니까? 인터페이스가 데이터 변경 사항에 어떻게 반응하도록 합니까?
이러한 질문은 프레임워크를 사용하여 건너뛰거나 완전히 무시할 수 있는 유형의 질문입니다. 개발자는 React, Vue, Ember 또는 Angular와 같은 것에 도달하고 문서를 따라 시작하여 실행하고 멀리 갑니다. 이러한 문제는 프레임워크의 트릭 상자에 의해 처리됩니다.
그것이 바로 당신이 원하는 방식일 수 있습니다. 틀림없이, 전문적인 표준에 맞게 무언가를 구축하려는 경우 수행하는 것이 현명한 일입니다. 그러나 마법이 추상화되면 트릭이 실제로 어떻게 수행되는지 배울 수 없습니다.
트릭이 어떻게 수행되는지 알고 싶지 않습니까?
나는 했다. 그래서 저는 이러한 문제를 스스로 이해하기 위해 기본 클라이언트 측 애플리케이션인 sans-framework를 구축하기로 결정했습니다.
그러나 나는 나보다 조금 앞서가고 있다. 먼저 약간의 배경.
이 여정을 시작하기 전에 나는 HTML과 CSS에 능숙하지만 JavaScript에는 능숙하지 않다고 생각했습니다. CSS에 대한 가장 큰 질문을 만족스럽게 풀었다고 느꼈을 때, 내가 스스로 설정한 다음 과제는 프로그래밍 언어를 이해하는 것이었습니다.
사실 저는 JavaScript에 대해 상대적으로 초심자 수준이었습니다. 그리고 Wordpress의 PHP를 해킹하는 것 외에는 다른 프로그래밍 언어에 대한 노출이나 훈련도 없었습니다.
그 '초보자 수준' 주장에 대해 자격을 부여하겠습니다. 물론 페이지에서 인터랙티브한 작업을 할 수 있습니다. 클래스 토글, DOM 노드 생성, 추가 및 이동 등. 그러나 그 이상의 코드를 구성하는 데 있어 나는 꽤 단서가 없었습니다. 나는 응용 프로그램에 접근하는 것을 구축하는 데 자신이 없었습니다. JavaScipt에서 데이터 세트를 정의하는 방법을 몰랐습니다. 함수로 조작하는 것은 고사하고 말이죠.
저는 JavaScript '디자인 패턴'에 대해 전혀 이해하지 못했습니다. 즉, 자주 발생하는 코드 문제를 해결하기 위한 확립된 접근 방식입니다. 나는 확실히 기본적인 애플리케이션 디자인 결정에 접근하는 방법에 대한 감각이 없었습니다.
'탑 트럼프'를 플레이해본 적이 있습니까? 글쎄, 웹 개발자 에디션에서 내 카드는 다음과 같이 보일 것입니다(100점 만점):
- CSS: 95
- 복사하여 붙여넣기: 90
- 헤어라인: 4
- HTML: 90
- 자바스크립트: 13
기술적인 면에서 도전하고 싶었을 뿐만 아니라 디자인적인 부분도 부족했습니다.
지난 10년 동안 거의 독점적으로 다른 사람들의 디자인을 코딩하면서 내 시각 디자인 기술은 20세기 후반 이후로 큰 어려움이 없었습니다. 그 사실과 나의 보잘것없는 JavaScript 기술을 반영하여 전문적인 부족함을 키웠습니다. 나의 부족한 점을 짚어보는 시간을 가졌습니다.
클라이언트 측 JavaScript 웹 응용 프로그램을 설계하고 구축하는 개인적인 도전이 마음속에 자리 잡았습니다.
학습에 대하여
컴퓨팅 언어를 배우는 데 이보다 더 좋은 리소스는 없었습니다. 특히 자바스크립트. 그러나 클릭 방식으로 사물을 설명하는 리소스를 찾는 데 시간이 걸렸습니다. 저에게는 Kyle Simpson의 'You Don't Know JS'와 Marijn Haverbeke의 'Eloquent JavaScript'가 큰 도움이 되었습니다.
JavaScript를 배우기 시작한다면 반드시 자신만의 전문가를 찾아야 합니다. 당신을 설명하는 방법이 효과가 있는 사람들.
내가 배운 첫 번째 핵심은 당신이 이해하는 방식으로 사물을 설명하지 않는 교사/자원으로부터 배우려고 하는 것은 무의미하다는 것입니다. 어떤 사람들은 foo
와 bar
가 있는 함수 예제를 보고 즉시 의미를 알아차립니다. 저는 그런 사람이 아닙니다. 당신도 그렇지 않다면 프로그래밍 언어가 당신에게 적합하지 않다고 가정하지 마십시오. 다른 리소스를 시도하고 배우고 있는 기술을 계속 적용하려고 노력하십시오.
모든 것이 갑자기 '딸깍'하는 어떤 종류의 유레카 순간도 즐길 수 있다는 것은 당연하지 않습니다. 첫눈에 반하는 것과 같은 코딩과 같습니다. 자신감을 느끼기 위해서는 많은 인내와 학습 내용을 상당한 수준으로 적용해야 할 가능성이 더 큽니다.
약간의 유능함을 느끼자마자 배운 내용을 적용하려고 하면 더 많은 것을 배울 수 있습니다.
다음은 그 과정에서 도움이 된 몇 가지 리소스입니다.
- Fun Fun Function 유튜브 채널
- Kyle Simpson Plural Sight 코스
- 웨스보스의 JavaScript30.com
- Marijn Haverbeke의 Eloquent JavaScript
맞습니다. 제가 이 시점에 온 이유에 대해 알아야 할 거의 모든 것입니다. 지금 방에 있는 코끼리는 프레임워크를 사용하지 않는 이유는 무엇입니까?
React, Ember, Angular, Vue 등
대답은 처음에 암시되었지만 프레임워크가 사용되지 않은 이유에 대한 주제는 확장되어야 한다고 생각합니다.
고품질의 잘 지원되는 JavaScript 프레임워크가 많이 있습니다. 각각은 클라이언트 측 웹 애플리케이션 구축을 위해 특별히 설계되었습니다. 내가 만들고자 했던 바로 그 종류의 것. 뻔한 질문에 대해 사과드립니다.
이에 대한 제 입장은 다음과 같습니다. 추상화를 사용하는 방법을 배울 때 주로 배우는 것은 추상화입니다. 나는 사물의 추상화가 아니라 사물을 배우고 싶었다.
예전에 jQuery를 배웠던 기억이 납니다. 사랑스러운 API를 사용하면 DOM 조작을 그 어느 때보다 쉽게 만들 수 있지만 그것 없이는 무력해집니다. jQuery 없이는 요소의 클래스를 토글할 수도 없었습니다. 기댈 jQuery가 없는 페이지에서 몇 가지 기본적인 상호 작용을 하도록 하고 나는 편집자에서 shorn Samson처럼 우연히 발견했습니다.
더 최근에는 JavaScript에 대한 이해를 높이려고 시도하면서 Vue와 React에 대해 머리를 싸매고 있었습니다. 그러나 궁극적으로 표준 JavaScript가 어디에서 끝나고 React 또는 Vue가 시작되었는지 확신할 수 없었습니다. 제 생각에는 이러한 추상화가 여러분을 위해 무엇을 하는지 이해할 때 훨씬 더 가치가 있다는 것입니다.
따라서 무언가를 배우려면 언어의 핵심 부분을 이해하고 싶었습니다. 그런 식으로 나는 약간의 양도 가능한 기술을 가지고있었습니다. 다음 '뜨거운 새로운 것'을 위해 현재의 이달 프레임워크를 제쳐 놓았을 때 무언가를 유지하고 싶었습니다.
괜찮아. 이제 우리는 이 앱이 왜 만들어졌는지, 좋든 싫든 어떻게 만들어지는지 알아봤습니다.
이 일이 무엇인지 계속 진행해 보겠습니다.
응용 아이디어
앱 아이디어가 필요했습니다. 너무 야심 찬 것은 없습니다. 저는 창업을 하거나 Dragon's Den에 출연하는 것에 대한 환상이 없었습니다. JavaScript와 응용 프로그램 기초를 배우는 것이 저의 주요 목표였습니다.
응용 프로그램은 기술적으로 성공하고 부팅을 위해 절반 정도의 디자인 작업을 수행할 수 있는 싸움 기회가 있는 것이어야 했습니다.
탄젠트 시간.
직장을 떠나 가능한 한 실내 축구를 조직하고 즐깁니다. 주최자로서 누가 나에게 그들이 게임을 하고 있고 누가 그렇지 않다는 메시지를 보냈는지 정신적으로 고통스럽습니다. 일반적으로 한 게임에 10명이 필요하며 푸시에는 8명이 필요합니다. 각 게임을 플레이할 수도 있고 할 수 없을 수도 있는 약 20명의 명단이 있습니다.
내가 결정한 앱 아이디어는 명단에서 선수를 선택할 수 있게 하여 몇 명의 선수가 플레이할 수 있다고 확인했는지 계산할 수 있는 것이었습니다.
생각을 하면 할수록 범위를 좀 더 넓혀서 간단한 팀 활동을 구성하는 데 사용할 수 있을 것 같았습니다.
사실, 저는 Google 어스를 거의 꿈꾸지 않았습니다. 그러나 설계, 데이터 관리, 상호 작용, 데이터 저장, 코드 구성과 같은 모든 필수 과제가 있었습니다.
디자인 면에서 나는 폰 뷰포트에서 잘 실행되고 작동할 수 있는 버전 외에는 관심을 두지 않을 것입니다. 작은 화면에서만 문제를 해결하는 것으로 디자인 문제를 제한하고 싶습니다.
핵심 아이디어는 확실히 '해야 할 일' 스타일 응용 프로그램에 의존했습니다. 이 응용 프로그램에는 고유한 디자인 및 코딩 문제를 제공하기에 충분한 차이가 있는 동시에 영감을 얻을 수 있는 기존 예제가 많이 있었습니다.
의도한 기능
내가 디자인하고 코딩하려는 기능의 초기 글머리 기호 목록은 다음과 같았습니다.
- 명단에 사람을 추가하기 위한 입력 상자.
- 각 사람을 'in' 또는 'out'으로 설정하는 기능;
- 사람들을 팀으로 나누는 도구로 기본적으로 2팀으로 설정됩니다.
- 명단에서 사람을 삭제하는 기능
- '도구'에 대한 일부 인터페이스. 분할 외에도 사용 가능한 도구에는 입력된 데이터를 파일로 다운로드하고, 이전에 저장한 데이터를 업로드하고, 한 번에 모든 플레이어를 삭제할 수 있는 기능이 포함되어야 합니다.
- 앱은 현재 'In'에 있는 사람 수를 표시해야 합니다.
- 게임에 선택된 사람이 없으면 팀 스플리터를 숨겨야 합니다.
- 지불 모드. 'in' 사용자가 지불했는지 여부를 표시하는 추가 토글을 가질 수 있는 설정의 토글입니다.
처음에는 이것이 최소한의 실행 가능한 제품의 기능을 고려한 것입니다.

설계
디자인은 종이 조각에서 시작되었습니다. 연필 드로잉으로 얻을 수 있는 빈약한 조사에도 불구하고 내 머리 속에서 얼마나 많은 아이디어가 터무니없는 것으로 판명되었는지 알아내는 것은 빛을 발했습니다(읽기: 부수기).
따라서 많은 아이디어가 빠르게 배제되었지만 이면은 일부 아이디어를 스케치함으로써 항상 다른 생각으로 이어졌습니다.
이제 이 글을 읽는 디자이너들은 "물론이죠"라고 생각할 것입니다. 하지만 이것은 저에게 진정한 계시였습니다. 개발자는 나중 단계 디자인을 보는 데 익숙하며 그 시점 이전에 포기한 모든 단계를 거의 보지 않습니다.
연필 드로잉과 같은 것에 만족하면 디자인 패키지인 Sketch에서 다시 만들려고 합니다. 종이와 연필 단계에서 아이디어가 떨어져 나간 것처럼 스케치의 다음 충실도 단계에서도 같은 수의 아이디어가 나오지 않았습니다. 그런 다음 Sketch에서 아트보드로 유지되는 것처럼 보이는 항목이 코딩할 후보로 선택되었습니다.
나는 그 후보자들이 내장 코드일 때 다양한 이유로 백분율이 작동하지 않는다는 것을 차례로 발견했습니다. 각 충실도 단계는 통과하거나 실패하는 설계에 대한 새로운 과제를 노출했습니다. 그리고 실패는 문자 그대로 그리고 비유적으로 나를 드로잉 보드로 이끌 것입니다.
따라서 궁극적으로 내가 만든 디자인은 원래 Sketch에서 가지고 있던 디자인과 상당히 다릅니다. 다음은 첫 번째 스케치 모형입니다.


그때도 나는 망상이 없었습니다. 기본적인 디자인이었다. 그러나 이 시점에서 나는 상대적으로 작동할 수 있다고 확신하는 것이 있었고 그것을 시도하고 구축하기 위해 조금 씹고 있었습니다.
기술 요구 사항
몇 가지 초기 기능 요구 사항과 기본적인 시각적 방향을 통해 코드로 달성해야 할 사항을 고려할 때였습니다.
iOS 또는 Android 장치용 애플리케이션을 만드는 방법은 기본 코드를 사용하는 것이 현명한 방법이라는 것이 받아들여지지만, 우리는 이미 내 의도가 JavaScript로 애플리케이션을 빌드하는 것임을 확인했습니다.
나는 또한 응용 프로그램이 프로그레시브 웹 응용 프로그램 또는 더 일반적으로 알려진 PWA 자격을 갖추는 데 필요한 모든 확인란을 선택했는지 확인하고 싶었습니다.
프로그레시브 웹 애플리케이션이 무엇인지 모를 기회가 있을 때 여기 '엘리베이터 피치'가 있습니다. 개념적으로, 표준 웹 응용 프로그램을 상상해보십시오. 그러나 특정 기준을 충족하는 응용 프로그램이 있습니다. 이 일련의 특정 요구 사항을 준수한다는 것은 지원 장치(휴대폰을 생각하면)가 웹 앱에 특별한 권한을 부여하여 웹 애플리케이션을 해당 부분의 합보다 더 크게 만든다는 것을 의미합니다.
특히 Android에서는 HTML, CSS 및 JavaScript만으로 빌드된 PWA와 네이티브 코드로 빌드된 애플리케이션을 구별하는 것이 거의 불가능할 수 있습니다.
다음은 애플리케이션이 프로그레시브 웹 애플리케이션으로 간주되기 위한 요구사항에 대한 Google 체크리스트입니다.
- 사이트는 HTTPS를 통해 제공됩니다.
- 페이지는 태블릿 및 모바일 장치에서 반응합니다.
- 모든 앱 URL은 오프라인 상태에서 로드됩니다.
- 홈 화면에 추가를 위해 제공된 메타데이터,
- 3G에서도 첫 번째 로드가 빠릅니다.
- 사이트는 브라우저 간 작동합니다.
- 페이지 전환은 네트워크에서 차단되는 것처럼 느껴지지 않습니다.
- 각 페이지에는 URL이 있습니다.
또한 이제 교사의 애완 동물이 되고 애플리케이션이 '모범적인 프로그레시브 웹 앱'으로 간주되도록 하려면 다음 요구 사항도 충족해야 합니다.
- 사이트 콘텐츠는 Google에서 색인을 생성합니다.
- 적절한 경우 Schema.org 메타데이터가 제공됩니다.
- 적절한 경우 소셜 메타데이터가 제공됩니다.
- 필요한 경우 표준 URL이 제공됩니다.
- 페이지는 History API를 사용합니다.
- 페이지가 로드될 때 콘텐츠가 점프하지 않습니다.
- 세부 정보 페이지에서 뒤로 누르면 이전 목록 페이지의 스크롤 위치가 유지됩니다.
- 탭하면 입력이 화면 키보드에 가려지지 않습니다.
- 콘텐츠는 독립 실행형 또는 전체 화면 모드에서 쉽게 공유할 수 있습니다.
- 사이트는 휴대전화, 태블릿 및 데스크톱 화면 크기에서 반응합니다.
- 앱 설치 프롬프트는 과도하게 사용되지 않습니다.
- 홈 화면에 추가 프롬프트가 차단됩니다.
- 첫 번째 로드는 3G에서도 매우 빠릅니다.
- 사이트는 캐시 우선 네트워킹을 사용합니다.
- 사이트는 사용자가 오프라인일 때 적절하게 알립니다.
- 알림이 사용되는 방식에 대한 컨텍스트를 사용자에게 제공합니다.
- 사용자가 푸시 알림을 켜도록 권장하는 UI는 지나치게 공격적이지 않아야 합니다.
- 사이트는 권한 요청이 표시될 때 화면을 어둡게 합니다.
- 푸시 알림은 시기 적절하고 정확하며 관련성이 있어야 합니다.
- 알림을 활성화 및 비활성화하는 컨트롤을 제공합니다.
- 사용자는 Credential Management API를 통해 여러 장치에 로그인되어 있습니다.
- 사용자는 Payment Request API에서 기본 UI를 통해 쉽게 결제할 수 있습니다.
크리키! 나는 당신에 대해 모르지만 그 두 번째 묶음은 기본 응용 프로그램에 대해 완전히 많은 작업처럼 보입니다! 어쨌든 내가 계획한 것과 관련이 없는 항목이 많이 있습니다. 그럼에도 불구하고 1차 시험에 합격하기 위해 시선을 낮추었다고 말하는 것이 부끄럽지 않다.
애플리케이션 유형의 전체 섹션에 대해 PWA가 기본 애플리케이션보다 적용 가능한 솔루션이라고 생각합니다. 게임과 SaaS가 앱 스토어에서 더 합리적이라고 주장할 수 있는 곳에서 더 작은 유틸리티는 웹에서 프로그레시브 웹 애플리케이션으로 훨씬 더 행복하고 성공적으로 살 수 있습니다.
나는 힘든 일을 피한다는 주제로 초기에 선택한 또 다른 선택은 응용 프로그램의 모든 데이터를 사용자 자신의 장치에 저장하는 것이었습니다. 그렇게 하면 데이터 서비스 및 서버에 연결하고 로그인 및 인증을 처리할 필요가 없습니다. 내 기술이 있는 곳에서 인증을 알아내고 사용자 데이터를 저장하는 것은 응용 프로그램 송금을 위해 내가 씹고 과도하게 사용할 수 있는 것보다 거의 확실히 더 많은 것을 물어뜯는 것처럼 보였습니다!
기술 선택
목표가 무엇인지에 대한 명확한 아이디어와 함께 이를 구축하는 데 사용할 수 있는 도구에 관심이 집중되었습니다.
나는 일찍부터 TypeScript를 사용하기로 결정했습니다. TypeScript는 웹사이트에 "... 일반 JavaScript로 컴파일되는 JavaScript의 유형이 지정된 상위 집합"으로 설명되어 있습니다. 내가 좋아하는 언어, 특히 정적 분석에 대해 스스로 잘 배운다는 사실을 보고 읽었습니다.
정적 분석은 단순히 프로그램이 실행하기 전에(예: 정적일 때) 코드를 보고 문제를 강조 표시할 수 있음을 의미합니다. 반드시 논리적인 문제를 지적할 수는 없지만 일련의 규칙에 대해 부적합한 코드를 지적할 수 있습니다.
내가 진행하면서 내 (확실히 많은) 오류를 지적할 수 있는 모든 것은 좋은 것이어야만 했습니까?
TypeScript에 익숙하지 않은 경우 바닐라 JavaScript에서 다음 코드를 고려하십시오.
console.log(`${count} players`); let count = 0;
이 코드를 실행하면 다음과 같은 오류가 발생합니다.
ReferenceError: Cannot access uninitialized variable.
JavaScript 능력이 조금이라도 있는 사람들을 위해, 이 기본 예제에서는 상황이 좋지 않을 것이라고 알려주는 도구가 필요하지 않습니다.
그러나 TypeScript에서 동일한 코드를 작성하면 편집기에서 다음과 같은 일이 발생합니다.

코드를 실행하기도 전에 내 어리석음에 대한 피드백을 받고 있습니다! 이것이 바로 정적 분석의 아름다움입니다. 이 피드백은 종종 경험이 더 많은 개발자가 나와 함께 앉아 오류를 잡는 것과 같았습니다.
TypeScript는 기본적으로 이름에서 알 수 있듯이 코드의 각 항목에 대해 예상되는 '유형'을 지정해 보겠습니다. 이렇게 하면 실수로 한 유형을 다른 유형으로 '강제 적용'하는 것을 방지할 수 있습니다. 또는 적용할 수 없는 데이터 조각에 대해 메서드를 실행하려고 시도하는 경우(예: 개체에 대한 배열 메서드). 이것은 코드가 실행될 때 반드시 오류를 발생시키는 종류는 아니지만 확실히 버그를 추적하기 어려울 수 있습니다. TypeScript 덕분에 코드를 실행하기 전에 편집기에서 피드백을 받을 수 있습니다.
TypeScript는 확실히 이 발견의 여정에서 필수적인 것은 아니었고 분명한 이점이 없는 한 누구에게도 이러한 성격의 도구를 사용하도록 권장하지 않을 것입니다. 처음에 도구를 설정하고 구성하는 것은 시간을 낭비할 수 있으므로 다이빙하기 전에 적용 가능성을 확실히 고려하십시오.
TypeScript가 제공하는 다른 이점도 이 시리즈의 다음 기사에서 다루게 될 것이지만 정적 분석 기능만으로도 TypeScript를 채택하고 싶을 만큼 충분했습니다.
내가 하고 있는 선택에 대한 노크온 고려 사항이 있었습니다. 응용 프로그램을 프로그레시브 웹 응용 프로그램으로 빌드하기로 선택한다는 것은 서비스 워커를 어느 정도 이해해야 한다는 것을 의미했습니다. TypeScript를 사용한다는 것은 일종의 빌드 도구를 도입하는 것을 의미합니다. 이러한 도구를 어떻게 관리해야 합니까? 역사적으로 NPM을 패키지 관리자로 사용했지만 Yarn은 어떻습니까? 대신 Yarn을 사용할 가치가 있었습니까? 성능 중심이라는 것은 일부 축소 또는 번들 도구를 고려한다는 것을 의미합니다. webpack과 같은 도구는 점점 더 대중화되고 있으며 평가가 필요할 것입니다.
요약
나는 이 탐구에 착수할 필요가 있다는 것을 깨달았다. 내 JavaScript 능력은 약했고 이론을 실행에 옮기는 것만큼 허리를 조이는 것도 없었습니다. 바닐라 JavaScript로 웹 애플리케이션을 구축하기로 결정한 것은 나의 불 세례였습니다.
나는 응용 프로그램을 만들기 위한 옵션을 조사하고 고려하는 데 시간을 보냈고 응용 프로그램을 Progressive Web App으로 만드는 것이 내 기술과 아이디어의 상대적 단순성에 가장 적합하다고 결정했습니다.
빌드 도구, 패키지 관리자, 그리고 엄청난 인내심이 필요합니다.
궁극적으로 이 시점에서 근본적인 질문이 남았습니다. 이것이 내가 실제로 관리할 수 있는 것입니까? 아니면 내 자신의 무능함 때문에 겸손해질 것인가?
빌드 도구, JavaScript 디자인 패턴 및 '앱과 유사한' 무언가를 만드는 방법에 대해 읽을 수 있을 때 2부에서 저와 함께 하시길 바랍니다.