Angular Material 애플리케이션을 만들고 배포하는 방법

게시 됨: 2022-03-10
빠른 요약 ↬ Netlify 에서 호스팅되는 동안 완전히 Angular를 기반으로 하는 Angular 8 웹 애플리케이션 및 QR 코드 생성기 앱을 만드는 과정입니다.

Angular는 새로운 웹 애플리케이션을 만들 때 인기 있는 선택 중 하나입니다. 또한 "재료 디자인" 사양은 오늘날 최소한의 매력적인 경험을 만들기 위한 선택이 되었습니다. 따라서 새로운 "Angular" 프로젝트는 대부분 "Angular Material Design Library"를 사용하여 머티리얼 디자인 사양을 따르는 구성 요소를 사용합니다. 부드러운 애니메이션에서 적절한 상호 작용 피드백에 이르기까지 이 모든 것이 angular용 공식 머티리얼 디자인 라이브러리의 일부로 이미 사용 가능합니다.

웹 애플리케이션이 개발되면 다음 단계는 이를 배포하는 것입니다. 바로 여기에서 "Netlify"가 등장합니다. 매우 사용하기 쉬운 인터페이스, 자동 배포, A/B 테스트를 위한 트래픽 분할 및 기타 다양한 기능을 갖춘 Netlify는 확실히 훌륭한 도구입니다.

이 기사는 공식 Angular Material Design 라이브러리를 사용하여 Angular 8 웹 애플리케이션을 만드는 방법을 설명합니다. Netlify에서 호스팅되는 동안 완전히 Angular를 기반으로 하는 QR 코드 생성기 웹 애플리케이션을 만들 것입니다.

이 튜토리얼의 파일은 GitHub에서 찾을 수 있으며 데모 버전은 여기에 배포됩니다.

시작하기

  1. Angular 8을 설치하고,
  2. GitHub 계정을 만들고,
  3. 컴퓨터에 Git을 설치하고,
  4. Netlify 계정을 만드십시오.

참고 : 저는 VSCode와 Microsoft Windows를 기본 IDE 및 OS로 사용할 것입니다. 단, 단계는 다른 OS의 다른 IDE와 비슷합니다.

위의 전제 조건이 완료되면 시작하겠습니다!

점프 후 더! 아래에서 계속 읽기 ↓

모의 및 계획

프로젝트 생성을 시작하기 전에 미리 계획하는 것이 도움이 될 것입니다. 애플리케이션에서 어떤 종류의 UI를 원할까요? 재사용 가능한 부품이 있습니까? 애플리케이션은 외부 서비스와 어떻게 상호 작용합니까?

먼저 UI 모의를 확인하십시오.

홈페이지(큰 미리보기)
QR 페이지 만들기(큰 미리보기)
기록 페이지(큰 미리보기)

이들은 응용 프로그램에 포함될 세 가지 다른 페이지입니다. 홈페이지는 우리 응용 프로그램의 시작점이 될 것입니다. QR 페이지 생성은 새로운 QR 코드 생성을 다루어야 합니다. 기록 페이지에는 저장된 모든 QR 코드가 표시됩니다.

목업은 응용 프로그램의 모양과 느낌에 대한 아이디어를 제공할 뿐만 아니라 각 페이지의 책임을 분리합니다.

한 가지 관찰(mocks에서)은 상단 탐색 모음이 모든 페이지에서 공통적으로 나타나는 것 같습니다. 따라서 탐색 모음을 재사용 가능한 구성 요소로 만들고 재사용할 수 있습니다.

이제 애플리케이션이 어떻게 보이고 무엇을 재사용할 수 있는지에 대한 상당한 아이디어를 얻었으므로 시작하겠습니다.

새 Angular 프로젝트 만들기

VSCode를 시작한 다음 VSCode에서 터미널 창을 열어 새 Angular 프로젝트를 생성합니다.

VSCode의 터미널(큰 미리보기)

프롬프트에 표시된 대로 터미널이 기본 경로로 열립니다. 계속하기 전에 선호하는 디렉토리로 변경할 수 있습니다. Windows의 경우 cd 명령을 사용합니다.

기본 경로 탐색(큰 미리보기)

앞으로 angular-cli에는 ng new <project-name> 새 프로젝트를 생성하는 명령이 있습니다. 원하는 멋진 프로젝트 이름을 사용하고 Enter 키를 누르십시오(예: ng new qr ).

이렇게 하면 angular-cli 마법이 트리거됩니다. 예를 들어 각도 라우팅 추가와 같이 프로젝트의 일부 측면을 구성하는 몇 가지 옵션을 제공합니다. 그런 다음 선택한 옵션을 기반으로 수정 없이 실행할 수 있는 전체 프로젝트 스켈레톤을 생성합니다.

이 자습서의 경우 라우팅에 를 입력하고 스타일 지정에 CSS 를 선택합니다. 그러면 새 Angular 프로젝트가 생성됩니다.

새 Angular 프로젝트 만들기(큰 미리보기)

이제 완전히 작동하는 Angular 프로젝트가 생겼습니다. 모든 것이 제대로 작동하는지 확인하기 위해 터미널에 다음 명령을 입력하여 프로젝트를 실행할 수 있습니다. ng serve . 어, 하지만 잠시만요. 오류가 발생합니다. 무슨 일이 일어날 수 있었습니까?

ng 제공 오류(큰 미리보기)

걱정하지 마세요. angular-cli를 사용하여 새 프로젝트를 생성할 때마다 ng new qr 명령에 지정된 프로젝트 이름을 따서 명명된 폴더 안에 전체 골격이 생성됩니다. 여기에서 현재 작업 디렉터리를 방금 만든 디렉터리로 변경해야 합니다. Windows에서 cd qr 명령을 사용하여 디렉토리를 변경합니다.

이제 ng serve 를 사용하여 프로젝트를 다시 실행해 보세요.

프로젝트 실행 중(큰 미리보기)

웹 브라우저를 열고 URL https://localhost:4200으로 이동하여 실행 중인 프로젝트를 확인합니다. ng serve 명령은 기본적으로 포트 4200에서 애플리케이션을 실행합니다.

: 다른 포트에서 실행하려면 ng serve --port <any-port> 명령을 사용합니다 (예: ng serve --port 3000 ).

이렇게 하면 기본 Angular 프로젝트가 실행되고 실행됩니다. 계속 진행합시다.

VSCode에 프로젝트 폴더를 추가해야 합니다. "파일" 메뉴로 이동하여 "폴더 열기"를 선택하고 프로젝트 폴더를 선택합니다. 이제 프로젝트 폴더가 왼쪽의 탐색기 보기에 표시됩니다.

각도 재료 라이브러리 추가

Angular 재질 라이브러리를 설치하려면 터미널 창에서 다음 명령을 사용하십시오. ng add @angular/material . 이것은 (다시) 어떤 테마를 원하는지, 기본 애니메이션을 원하는지, 터치 지원이 필요한지 여부와 같은 몇 가지 질문을 합니다. 기본 Indigo/Pink 테마를 선택하고 HammerJS 라이브러리 및 브라우저 애니메이션을 추가하려면 Yes 를 선택합니다.

Angular 재료 추가(큰 미리보기)

위의 명령은 또한 전체 프로젝트를 구성하여 재료 구성 요소를 지원할 수 있습니다.

  1. package.json 에 프로젝트 종속성을 추가합니다.
  2. index.html 파일에 Roboto 글꼴을 추가합니다.
  3. index.html 에 Material Design 아이콘 글꼴을 추가합니다.
  4. 또한 다음과 같은 몇 가지 전역 CSS 스타일을 추가합니다.
    • 몸의 여백을 제거하고,
    • height: 100% ,
    • Roboto를 기본 애플리케이션 글꼴로 설정하십시오.

모든 것이 정상인지 확인하기 위해 이 시점에서 프로젝트를 다시 실행할 수 있습니다. 하지만 새로운 내용은 확인하지 못할 것입니다.

홈페이지 추가

이제 프로젝트 골격이 준비되었습니다. 먼저 홈페이지를 추가해 보겠습니다.

(큰 미리보기)

위의 그림과 같이 홈페이지를 심플하게 유지하고 싶습니다. 이 홈 페이지는 몇 가지 각진 재료 구성요소를 사용합니다. 해부하자.

  1. 상단 표시줄은 이미지와 텍스트가 자식으로 있는 재질 스타일 버튼 mat-button 을 포함하는 간단한 HTML nav 요소입니다. 막대 색상은 Angular 재질 라이브러리를 추가할 때 선택한 기본 색상과 동일합니다.
  2. 중심 이미지;
  3. 또 다른 하나는 텍스트만 자식으로 포함하는 mat-button 입니다. 이 버튼을 사용하면 사용자가 기록 페이지로 이동할 수 있습니다.
  4. 위 버튼에 부착된 카운트 배지 matBadge 는 사용자가 저장한 QR 코드의 수를 보여줍니다.
  5. 선택한 테마의 강조 색상이 있는 오른쪽 하단 모서리의 플로팅 작업 버튼 mat-fab .

조금 벗어나서 다른 필수 구성 요소와 서비스를 먼저 추가해 보겠습니다.

헤더 추가

이전에 계획한 대로 탐색 모음을 재사용해야 하므로 별도의 각도 구성 요소로 만들어 보겠습니다. VSCode에서 터미널을 열고 ng gc header (ng generate component header의 약자)를 입력하고 Enter 키를 누릅니다. 이렇게 하면 4개의 파일이 포함된 "header"라는 새 폴더가 생성됩니다.

  • header.component.css : 이 구성 요소의 스타일을 제공하는 데 사용됩니다.
  • header.component.html : HTML 요소 추가용;
  • header.component.spec.ts : 테스트 케이스 작성용;
  • header.component.ts : Typescript 기반 로직을 추가합니다.
헤더 구성요소(큰 미리보기)

헤더를 목에 있는 것처럼 보이게 하려면 header.component.html 에 아래 HTML을 추가하세요.

 <nav class="navbar" [class.mat-elevation-z8]=true> <div> <button *ngIf="showBackButton" aria-hidden=false mat-icon-button routerLink="/"> <mat-icon> <i class="material-icons md-32">arrow_back</i> </mat-icon> </button> <span>{{currentTitle}}</span> </div> <button *ngIf="!showBackButton" aria-hidden=false mat-button class="button"> <img src="../../assets/qr-icon-white.png"> <span>QR Generator</span> </button> <button *ngIf="showHistoryNav" aria-hidden=false mat-button class="button" routerLink="/history"> <span>History</span> </button> </nav>

: 재료 구성요소에 대한 고도를 추가하려면 [class.mat-elevation-z8]=true 를 사용하여 z을 변경하여 고도 값을 변경할 수 있습니다 . 이 경우에는 z8 입니다. 예를 들어 고도를 16으로 변경하려면 [class.mat-elevation-z16]=true 를 사용하십시오.

위의 HTML 스니펫에는 mat-iconmat-button/mat-icon-button 이라는 두 가지 Angular 머티리얼 요소가 사용됩니다. 사용법은 매우 간단합니다. 먼저 아래와 같이 app.module.ts 에 이 두 가지를 모듈로 추가해야 합니다.

mat-iconmat-button 에 대한 모듈 가져오기(큰 미리보기)

이렇게 하면 구성 요소의 어느 곳에서나 이 두 개의 Angular 머티리얼 요소를 사용할 수 있습니다.

재료 버튼을 추가하기 위해 다음 HTML 스니펫이 사용됩니다.

 <button mat-button> Material Button </button>

mat-raised-button , mat-flat-button , mat-fab 등과 같은 Angular 재질 라이브러리에서 사용할 수 있는 다양한 유형의 재질 버튼 요소가 있습니다. 위 코드 스니펫의 mat-button 을 다른 유형으로 바꾸면 됩니다.

재질 버튼 유형(큰 미리보기)

다른 요소는 재질 아이콘 라이브러리에서 사용 가능한 아이콘을 표시하는 데 사용되는 mat-icon 입니다. Angular 재질 라이브러리가 처음에 추가되었을 때 재질 아이콘 라이브러리에 대한 참조도 추가되어 방대한 아이콘 배열의 아이콘을 사용할 수 있었습니다.

사용법은 다음과 같이 간단합니다.

 <mat-icon> <i class="material-icons md-32">arrow_back</i> </mat-icon>

중첩된 <i> 태그를 사용하여 아이콘 크기(여기서는 md-32 )를 변경하여 아이콘 크기를 높이와 너비가 32px로 만들 수 있습니다. 이 값은 md-24 , md-48 등이 될 수 있습니다. 중첩된 <i> 태그의 값은 아이콘의 이름입니다. (다른 아이콘의 이름은 여기에서 찾을 수 있습니다.)

접근성

아이콘이나 이미지가 사용될 때마다 접근성 목적이나 스크린 리더 사용자를 위해 충분한 정보를 제공하는 것이 필수적입니다. ARIA(Accessible Rich Internet Applications)는 장애가 있는 사람들이 웹 콘텐츠와 웹 응용 프로그램에 더 쉽게 액세스할 수 있도록 하는 방법을 정의합니다.

한 가지 주의할 점은 고유한 의미 체계(예: nav )가 있는 HTML 요소에는 ARIA 속성이 필요하지 않다는 것입니다. 스크린 리더는 nav 가 탐색 요소라는 것을 이미 알고 있으며 그렇게 읽습니다.

ARIA 사양은 역할, 상태 및 속성의 세 가지 범주로 나뉩니다. div 가 HTML 코드에서 진행률 표시줄을 만드는 데 사용된다고 가정해 보겠습니다. 기본 의미가 없습니다. ARIA 역할은 이 위젯을 진행 표시줄로 설명할 수 있으며 ARIA 속성은 드래그할 수 있는 것과 같은 특성을 나타낼 수 있습니다. ARIA 상태는 진행률 표시줄의 현재 값과 같은 현재 상태를 설명합니다. 아래 스니펫을 참조하세요.

 <div role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100"> </div>

유사하게, 매우 일반적으로 사용되는 aria 속성인 aria-hidden=true/false 가 사용됩니다. 값이 true이면 해당 요소가 화면 판독기에 표시되지 않습니다.

본 어플리케이션에서 사용되는 대부분의 UI 요소들은 고유의 의미론적 의미를 가지므로 사용되는 유일한 ARIA 속성은 ARIA 가시성 상태를 지정하는 것입니다. 자세한 내용은 이를 참조하십시오.

header.component.html 에는 현재 페이지에 따라 뒤로 버튼을 숨기고 표시하는 몇 가지 논리가 포함되어 있습니다. 또한 홈 버튼에는 /assets 폴더에 추가해야 하는 이미지/로고도 포함되어 있습니다. 여기에서 이미지를 다운로드하고 /assets 폴더에 저장합니다.

탐색 모음의 스타일을 지정하려면 header.component.css 에 아래 CSS를 추가하세요.

 .navbar { position: fixed; top: 0; left: 0; right: 0; z-index: 2; background: #3f51b5; display: flex; flex-wrap: wrap; align-items: center; padding: 12px 16px; } .button { color: white; margin: 0px 10px; }

헤더 구성 요소를 다른 구성 요소에서 재사용할 수 있도록 유지하고 표시해야 하는 항목을 결정하려면 다른 구성 요소의 매개 변수로 해당 구성 요소가 필요합니다. 이를 위해서는 header.component.html에서 사용한 변수에 바인딩할 @Input() 데코레이터를 사용해야 합니다.

header.component.ts 파일에 다음 줄을 추가합니다.

 // Add these three lines above the constructor entry. @Input() showBackButton: boolean; @Input() currentTitle: string; @Input() showHistoryNav: boolean; constructor() { }

위의 세 가지 바인딩은 헤더 구성 요소가 사용할 다른 구성 요소의 매개 변수로 전달됩니다. 우리가 앞으로 나아가면 그 사용법이 더 명확해질 것입니다.

계속해서 Angular 구성 요소로 나타낼 수 있는 홈페이지를 만들어야 합니다. 이제 다른 구성 요소를 만드는 것으로 시작하겠습니다. 홈 구성 요소를 자동 생성하려면 터미널에 ng gc home 을 입력합니다. 이전과 마찬가지로 4개의 다른 파일이 포함된 "home"이라는 새 폴더가 생성됩니다. 해당 파일을 수정하기 전에 Angular 라우팅 모듈에 라우팅 정보를 추가해 보겠습니다.

라우팅 추가

Angular는 URL을 특정 구성 요소에 매핑하는 방법을 제공합니다. 탐색이 발생할 때마다 Angular 프레임워크는 URL을 모니터링하고 app-routing.module.ts 파일에 있는 정보를 기반으로 합니다. 매핑된 구성 요소를 초기화합니다. 이렇게 하면 다른 구성 요소가 다른 구성 요소를 초기화하는 책임을 짊어질 필요가 없습니다. 우리의 경우 응용 프로그램에는 다른 버튼을 클릭하여 탐색할 수 있는 세 페이지가 있습니다. Angular 프레임워크에서 제공하는 라우팅 지원을 활용하여 이를 달성합니다.

홈 구성 요소는 응용 프로그램의 시작점이 되어야 합니다. 이 정보를 app-routing.module.ts 파일에 추가해 보겠습니다.

Routing Home 구성요소(큰 미리보기)

path 속성은 빈 문자열로 설정됩니다. 이를 통해 애플리케이션 URL을 Google 홈페이지를 표시하는 google.com 과 같은 홈페이지 구성요소에 매핑할 수 있습니다.

: 경로 값은 " / "로 시작하지 않으며, 경로가 search/coffee 와 같을 수 있지만 대신 빈 문자열을 사용합니다 .

홈페이지 구성 요소로 다시 이동하여 home.component.html 의 내용을 다음으로 바꿉니다.

 <app-header [showBackButton]="false" [currentTitle]=""></app-header> <app-profile></app-profile> <!-- FAB Fixed --> <button mat-fab class="fab-bottom-right" routerLink="/create"> <mat-icon> <i class="material-icons md-48">add</i> </mat-icon> </button>

홈 구성 요소에는 세 부분이 있습니다.

  1. 재사용 가능한 헤더 구성 요소 <app-header> ,
  2. 프로필 구성 요소 <app-profile> ,
  3. 오른쪽 하단의 플로팅 작업 버튼.

위의 HTML 스니펫은 재사용 가능한 헤더 구성요소가 다른 구성요소에서 어떻게 사용되는지 보여줍니다. 컴포넌트 선택기를 사용하고 필요한 매개변수를 전달하기만 하면 됩니다.

Profile 컴포넌트는 홈페이지의 Body로 사용하기 위해 생성되었습니다. 곧 생성하겠습니다.

+ 아이콘이 있는 플로팅 액션 버튼은 화면 오른쪽 하단에 매트 팹( mat-fab ) 유형의 일종의 Angular 재질 버튼입니다. 탐색을 위해 app-routing.module.ts 에 제공된 경로 정보를 사용하는 routerLink 속성 지시문이 있습니다. 이 경우 버튼의 경로 값은 /create 로 구성 요소를 생성하기 위해 매핑됩니다.

생성 버튼을 오른쪽 하단에 띄우려면 home.component.css 에 아래 CSS 코드를 추가하세요.

 .fab-bottom-right { position: fixed; left: auto; bottom: 5%; right: 10%; }

프로필 구성 요소는 홈페이지 본문을 관리해야 하므로 home.component.ts 는 그대로 둡니다.

프로필 구성 요소 추가

터미널을 열고 ng gc profile 을 입력하고 Enter 키를 눌러 프로필 구성 요소를 생성합니다. 앞서 계획한 대로 이 구성 요소는 홈 페이지의 본문을 처리합니다. profile.component.html 을 열고 내용을 다음으로 바꿉니다.

 <div class="center profile-child"> <img class="avatar" src="../../assets/avatar.png"> <div class="profile-actions"> <button mat-raised-button matBadge="{{historyCount}}" matBadgeOverlap="true" matBadgeSize="medium" matBadgeColor="accent" color="primary" routerLink="/history"> <span>History</span> </button> </div> </div>

위의 HTML 스니펫은 재료 라이브러리의 matBadge 요소를 사용하는 방법을 보여줍니다. 여기에서 사용하려면 MatBadgeModuleapp.module.ts 파일에 추가하는 일반적인 훈련을 따라야 합니다. 배지는 버튼, 아이콘 또는 텍스트와 같은 UI 요소에 대한 작은 그림 상태 설명자입니다. 이 경우 사용자가 저장한 QR의 개수를 보여주는 버튼과 함께 사용됩니다. Angular 재질 라이브러리 배지에는 matBadgePosition , matBadgeSize 로 크기 지정, matBadgeColor 로 배지 위치 설정과 같은 다양한 속성이 있으며 배지 색상을 설정합니다.

자산 폴더에 하나 이상의 이미지 자산을 추가해야 합니다. 다운로드. 프로젝트의 /assets 폴더에 동일하게 저장합니다.

profile.component.css 를 열고 다음을 추가하십시오.

 .center { top: 50%; left: 50%; position: absolute; transform: translate(-50%, -50%); } .profile-child { display: flex; flex-direction: column; align-items: center; } .profile-actions { padding-top: 20px; } .avatar { border-radius: 50%; width: 180px; height: 180px; }

위의 CSS는 계획대로 UI를 구현합니다.

계속해서 이전에 사용된 matBadge 에 반영되므로 기록 카운트 값을 업데이트하기 위한 일종의 논리가 필요합니다. profile.component.ts 를 열고 다음 스니펫을 적절하게 추가하십시오.

 export class ProfileComponent implements OnInit { historyCount = 0; constructor(private storageUtilService: StorageutilService) { } ngOnInit() { this.updateHistoryCount(); } updateHistoryCount() { this.historyCount = this.storageUtilService.getHistoryCount(); } }

StorageutilService 를 추가했지만 지금까지 이러한 서비스를 만들지 않았습니다. 오류를 무시하고 홈페이지 구성 요소를 마무리하는 프로필 구성 요소를 완성했습니다. 스토리지 유틸리티 서비스를 생성한 후 이 프로필 구성 요소를 다시 살펴보겠습니다. 좋아, 그럼 그렇게 하자.

로컬 스토리지

HTML5는 데이터를 로컬에 저장하는 데 사용할 수 있는 웹 저장 기능을 제공합니다. 이것은 쿠키에 비해 훨씬 더 많은 저장 공간을 제공합니다(최소 5MB 대 4KB). 범위와 수명이 다른 두 가지 유형의 웹 저장소가 있습니다. LocalSession . 전자는 데이터를 영구적으로 저장할 수 있지만 후자는 임시 및 단일 세션입니다. 유형 선택에 대한 결정은 사용 사례를 기반으로 할 수 있습니다. 이 시나리오에서는 세션 간에 저장하기를 원하므로 로컬 스토리지를 사용하겠습니다.

각 데이터 조각은 키/값 쌍에 저장됩니다. QR이 생성된 텍스트를 키로 사용하고 QR 이미지를 base64 문자열로 인코딩하여 값으로 사용합니다. 엔터티 폴더를 만들고 폴더 안에 새 qr-object.ts 파일을 만들고 다음과 같이 코드 조각을 추가합니다.

QR 엔티티 모델(큰 미리보기)

수업 내용:

 export class QR { text: string; imageBase64: string; constructor(text: string, imageBase64: string) { this.imageBase64 = imageBase64; this.text = text; } }

사용자가 생성된 QR을 저장할 때마다 위 클래스의 객체를 생성하고 스토리지 유틸리티 서비스를 사용하여 해당 객체를 저장합니다.

새 서비스 폴더를 만듭니다. 많은 서비스를 만들 것이므로 함께 그룹화하는 것이 좋습니다.

서비스 폴더(큰 미리보기)

현재 작업 디렉토리를 services, cd services 로 변경하여 ng gs <any name> 을 사용하여 새 서비스를 생성합니다. 이것은 ng generate service <any name> 의 줄임말이며 ng gs storageutil 을 입력하고 Enter 키를 누릅니다.

이렇게 하면 두 개의 파일이 생성됩니다.

  • storageutil.service.ts
  • storageutil.service.spec.ts

후자는 단위 테스트를 작성하기 위한 것입니다. storageutil.service.ts 를 열고 다음을 추가하십시오.

 private historyCount: number; constructor() { } saveHistory(key : string, item :string) { localStorage.setItem(key, item) this.historyCount = this.historyCount + 1; } readHistory(key : string) : string { return localStorage.getItem(key) } readAllHistory() : Array<QR> { const qrList = new Array<QR>(); for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); const value = localStorage.getItem(key); if (key && value) { const qr = new QR(key, value); qrList.push(qr); } } this.historyCount = qrList.length; return qrList; } getHistoryCount(): number { if (this.historyCount) { return this.historyCount; } this.readAllHistory(); return this.historyCount; } deleteHistory(key : string) { localStorage.removeItem(key) this.historyCount = this.historyCount - 1; }

오류를 수정하려면 qr-object 클래스를 가져오십시오. 로컬 스토리지 기능을 사용하기 위해 새로운 것을 가져올 필요가 없습니다. 키워드 localStorage 를 사용하여 키를 기반으로 값을 저장하거나 가져오기만 하면 됩니다.

이제 profile.component.ts 파일을 다시 열고 StorageutilService 클래스를 가져와서 프로필 구성 요소를 제대로 마무리합니다.

프로젝트를 실행하면 홈페이지가 계획대로 작동하는 것을 볼 수 있습니다.

QR 페이지 생성 추가

만들기/추가 버튼은 아무 작업도 하지 않지만 홈페이지는 준비되어 있습니다. 걱정하지 마세요. 실제 논리는 이미 작성되었습니다. routerLink 지시문을 사용하여 URL의 기본 경로를 /create 로 변경했지만 app-routing.module.ts 파일에 매핑이 추가되지 않았습니다.

새 QR 코드 생성을 처리할 구성 요소를 ng gc create-qr 을 입력하고 Enter 키를 눌러 새 구성 요소를 생성해 보겠습니다.

app-routing.module.ts 파일을 열고 다음 항목을 routes ​​배열에 추가합니다.

 { path: 'create', component: CreateQrComponent },

이렇게 하면 CreateQRComponent 가 URL /create 로 매핑됩니다.

create-qr.components.html 을 열고 내용을 다음으로 바꿉니다.

 <app-header [showBackButton]="showBackButton" [currentTitle]="title" [showHistoryNav]="showHistoryNav"></app-header> <mat-card class="qrCard" [class.mat-elevation-z12]=true> <div class="qrContent"> <!--Close button section--> <div class="closeBtn"> <button mat-icon-button color="accent" routerLink="/" matTooltip="Close"> <mat-icon> <i class="material-icons md-48">close</i> </mat-icon> </button> </div> <!--QR code image section--> <div class="qrImgDiv"> <img *ngIf="!showProgressSpinner" src={{qrCodeImage}} width="200px" height="200px"> <mat-spinner *ngIf="showProgressSpinner"></mat-spinner> <div class="actionButtons" *ngIf="!showProgressSpinner"> <button mat-icon-button color="accent" matTooltip="Share this QR"> <mat-icon> <i class="material-icons md-48">share</i> </mat-icon> </button> <button mat-icon-button color="accent" (click)="saveQR()" matTooltip="Save this QR"> <mat-icon> <i class="material-icons md-48">save</i> </mat-icon> </button> </div> </div> <!--Textarea to write any text or link--> <div class="qrTextAreaDiv"> <mat-form-field> <textarea matInput [(ngModel)]="qrText" cdkTextareaAutosize cdkAutosizeMinRows="4" cdkAutosizeMaxRows="4" placeholder="Enter a website link or any text..."></textarea> </mat-form-field> </div> <!--Create Button--> <div class="createBtnDiv"> <button class="createBtn" mat-raised-button color="accent" matTooltip="Create new QR code" matTooltipPosition="above" (click)="createQrCode()">Create</button> </div> </div> </mat-card>

위의 스니펫은 Angular 재질 라이브러리 요소를 많이 사용합니다. 계획대로 필요한 매개변수가 전달되는 하나의 헤더 구성요소 참조가 있습니다. 다음은 만들기 페이지의 본문입니다. [class.mat-elevation-z12]=true 를 사용하므로 중앙에 12px까지 올려진 Angular 재질 카드 또는 mat-card 카드로 구성됩니다.

재료 카드는 다른 div 태그로 사용할 수 있는 또 다른 종류의 컨테이너입니다. 재료 라이브러리는 아래에서 볼 수 있는 것처럼 이미지 배치, 제목, 부제목, 설명 및 동작과 같이 mat-card 에 잘 정의된 정보를 배치하기 위한 몇 가지 속성을 제공합니다.

카드 예(큰 미리보기)

위의 HTML 스니펫에서 우리는 다른 컨테이너와 마찬가지로 mat-card 를 사용했습니다. 사용된 또 다른 재료 라이브러리 요소는 matTooltip . 사용자가 요소 위에 마우스를 올리거나 길게 누를 때 표시되는 사용하기 쉬운 또 다른 도구 설명입니다. 툴팁을 표시하려면 아래 스니펫을 사용하세요.

 matTooltip="Any text you want to show"

아이콘 버튼 또는 기타 UI 요소와 함께 사용하여 추가 정보를 전달할 수 있습니다. 응용 프로그램 컨텍스트에서 닫기 아이콘 버튼에 대한 정보를 표시합니다. 툴팁의 위치를 ​​변경하기 위해 matTooltipPosition 이 사용됩니다:

 matTooltip="Any text you want to show" matTooltipPosition="above"

matTooltip 외에도 mat-spinner spiner는 로딩 진행 상황을 표시하는 데 사용됩니다. 사용자가 "만들기" 버튼을 클릭하면 네트워크 호출이 이루어집니다. 이 때 진행률 스피너가 표시됩니다. 네트워크 호출이 결과와 함께 반환되면 스피너를 숨깁니다. 다음과 같이 간단하게 사용할 수 있습니다.

 <mat-spinner *ngIf="showProgressSpinner"></mat-spinner>

showProgressSpinner 는 진행률 스피너를 표시하거나 숨기는 데 사용되는 부울 변수입니다. 라이브러리는 또한 색상을 변경하기 위해 [color]='accent' , 진행률 스피너 유형을 변경하기 위해 [mode]='indeterminate' 와 같은 일부 다른 매개변수를 제공합니다. 확정되지 않은 진행률 스피너는 작업의 진행 상황을 표시하지 않지만 확정된 것은 작업 진행률을 반영하기 위해 다른 값을 가질 수 있습니다. 여기에서는 네트워크 호출이 얼마나 걸릴지 모르기 때문에 불확정 스피너를 사용합니다.

재료 라이브러리는 재료 가이드라인을 준수하는 다양한 텍스트 영역을 제공하지만 mat-form-field 의 하위 항목으로만 사용할 수 있습니다. 재료 텍스트 영역의 사용법은 아래와 같이 기본 HTML만큼 간단합니다.

 <mat-form-field> <textarea matInput placeholder="Hint text"></textarea> </mat-form-field>

matInput 은 기본 input 태그가 mat-form-field 와 함께 작동하도록 하는 지시문입니다. placeholder 속성을 사용하면 사용자에 대한 힌트 텍스트를 추가할 수 있습니다.

: cdkTextareaAutosize textarea 속성을 사용하여 크기를 자동으로 조정할 수 있습니다. cdkAutosizeMinRows cdkAutosizeMaxRows사용 하여 행과 열을 설정하고 세 가지 모두를 함께 사용하여 최대 행 및 열 제한 세트에 도달할 때까지 텍스트 영역의 크기를 자동으로 조정합니다.

이러한 모든 재료 라이브러리 요소를 사용하려면 app.module.ts 파일에 추가해야 합니다.

QR 모듈 가져오기 생성(큰 미리보기)

HTML에서 사용 중인 자리 표시자 이미지가 있습니다. 다운로드하여 /assets 폴더에 저장합니다.

위의 HTML도 CSS 스타일 지정이 필요하므로 create-qr.component.ts 파일을 열고 다음을 추가하세요.

 .qrCard { display: flex; flex-direction: column; align-items: center; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 20%; height: 65%; padding: 50px 20px; } .qrContent { display: flex; flex-direction: column; align-items: center; width: 100%; } .qrTextAreaDiv { width: 100%; display: flex; flex-direction: row; justify-content: center; padding: 0px 0px; position: absolute; bottom: 10%; } .createBtn { left: 50%; transform: translate(-50%, 0px); width: 80%; } .createBtnDiv { position: absolute; bottom: 5%; width: 100%; } .closeBtn { display: flex; flex-direction: row-reverse; align-items: flex-end; width: 100%; margin-bottom: 20px; } .closeBtnFont { font-size: 32px; color: rgba(0,0,0,0.75); } .qrImgDiv { top: 20%; position: absolute; display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; } .actionButtons { display: flex; flex-direction: row; padding-top: 20px; }

UI를 로직으로 연결해 봅시다. create-qr.component.ts 파일을 열고 이미 있는 줄을 남겨두고 아래 코드를 추가합니다.

 export class CreateQrComponent implements OnInit { qrCodeImage = '../../../assets/download.png'; showProgressSpinner = false; qrText: string; currentQR; showBackButton = true; title = 'Generate New QR Code'; showHistoryNav = true; constructor(private snackBar: MatSnackBar, private restutil: RestutilService, private storageService: StorageutilService) { } ngOnInit() { } createQrCode() { //Check if any value is given for the qr code text if (!!this.qrText) { //Make the http call to load qr code this.loadQRCodeImage(this.qrText); } else { //Show snackbar this.showSnackbar('Enter some text first') } } public loadQRCodeImage(text: string) { // Show progress spinner as the request is being made this.showProgressSpinner = true; // Trigger the API call this.restutil.getQRCode(text).subscribe(image =>{ // Received the result - as an image blob - require parsing this.createImageBlob(image); }, error => { console.log('Cannot fetch QR code from the url', error) // Hide the spinner - show a proper error message this.showProgressSpinner = false; }); } private createImageBlob(image: Blob) { // Create a file reader to read the image blob const reader = new FileReader(); // Add event listener for "load" - invoked once the blob reading is complete reader.addEventListener('load', () => { this.qrCodeImage = reader.result.toString(); //Hide the progress spinner this.showProgressSpinner = false; this.currentQR = reader.result.toString(); }, false); // Read image blob if it is not null or undefined if (image) { reader.readAsDataURL(image); } } saveQR() { if (!!this.qrText) { this.storageService.saveHistory(this.qrText, this.currentQR); this.showSnackbar('QR saved') } else { //Show snackbar this.showSnackbar('Enter some text first') } } showSnackbar(msg: string) { //Show snackbar this.snackBar.open(msg, '', { duration: 2000, }); } }

사용자에게 상황에 맞는 정보를 제공하기 위해 머티리얼 디자인 라이브러리의 MatSnackBar 도 사용합니다. 이것은 화면 아래에서 팝업으로 나타나고 사라지기 전에 몇 초 동안 유지됩니다. 이것은 요소가 아니라 Typescript 코드에서 호출할 수 있는 서비스입니다.

메서드 이름 showSnackbar 인 위의 스니펫은 스낵바를 여는 방법을 보여주지만, 사용하기 전에 다른 머티리얼 라이브러리 요소에 대해 했던 것처럼 app.module.ts 파일에 MatSnackBar 항목을 추가해야 합니다.

TIP : 최근 Angular 머티리얼 라이브러리 버전에서는 스낵바 스타일을 간단하게 변경할 수 있는 방법이 없습니다. 대신 코드에 두 가지를 추가해야 합니다.

먼저 아래 CSS를 사용하여 배경색과 전경색을 변경합니다.

 ::ng-deep snack-bar-container.snackbarColor { background-color: rgba(63, 81, 181, 1); } ::ng-deep .snackbarColor .mat-simple-snackbar { color: white; }

둘째, panelClass 라는 속성을 사용하여 스타일을 위의 CSS 클래스로 설정합니다.

 this.snackBar.open(msg, '', { duration: 2000, panelClass: ['snackbarColor'] });

위의 두 가지 조합을 사용하면 머티리얼 디자인 라이브러리 스낵바 구성 요소에 대한 사용자 지정 스타일 지정이 가능합니다.

이것으로 QR 페이지를 만드는 방법에 대한 단계를 완료했지만 아직 한 부분이 누락되었습니다. create-qr.component.ts 파일을 확인하면 누락된 부분에 대한 오류가 표시됩니다. 이 퍼즐에서 누락된 부분은 타사 API에서 QR 코드 이미지를 가져오는 역할을 하는 RestutilService 입니다.

터미널에서 ng gs restutil 을 입력하고 Enter를 눌러 현재 디렉토리를 services로 변경합니다. 그러면 RestUtilService 파일이 생성됩니다. restutil.service.ts 파일을 열고 다음 스니펫을 추가합니다.

 private edgeSize = '300'; private BASE_URL = 'https://api.qrserver.com/v1/create-qr-code/?data={data}!&size={edge}x{edge}'; constructor(private httpClient: HttpClient) { } public getQRCode(text: string): Observable { // Create the url with the provided data and other options let url = this.BASE_URL; url = url.replace("{data}", text).replace(/{edge}/g, this.edgeSize); // Make the http api call to the url return this.httpClient.get(url, { responseType: 'blob' }); } private edgeSize = '300'; private BASE_URL = 'https://api.qrserver.com/v1/create-qr-code/?data={data}!&size={edge}x{edge}'; constructor(private httpClient: HttpClient) { } public getQRCode(text: string): Observable { // Create the url with the provided data and other options let url = this.BASE_URL; url = url.replace("{data}", text).replace(/{edge}/g, this.edgeSize); // Make the http api call to the url return this.httpClient.get(url, { responseType: 'blob' }); }

위의 서비스는 타사 API에서 QR 이미지를 가져오고 응답은 JSON 유형이 아니라 이미지이므로 위 스니펫에서 responseType'blob' 으로 지정합니다.

Angular는 모든 HTTP 지원 서버와 통신하기 위해 HttpClient 클래스를 제공합니다. 요청이 실행되기 전에 필터링하고, 응답을 다시 받고, 콜백 및 기타를 통해 응답을 처리할 수 있게 하는 것과 같은 많은 기능을 제공합니다. 동일하게 사용하려면 app.module.ts 파일에 HttpClientModule 에 대한 항목을 추가하십시오.

마지막으로 이 서비스를 create-qr.component.ts 파일로 가져와 QR 코드 생성을 완료합니다.

하지만 기다려! 위의 QR 로직 생성에 문제가 있습니다. 사용자가 동일한 텍스트를 사용하여 QR을 계속해서 생성하면 네트워크 호출이 발생합니다. 이 문제를 해결하는 한 가지 방법은 요청을 기반으로 캐싱하여 요청 텍스트가 동일한 경우 캐시에서 응답을 제공하는 것입니다.

캐싱 요청

Angular는 HttpInterceptor와 함께 HTTP 호출, HttpClient를 만드는 간단한 방법을 제공하여 서버에 대한 HTTP 요청 또는 응답을 검사하고 변환합니다. 인증이나 캐싱 등에 사용할 수 있으며 여러 인터셉터를 추가하고 추가 처리를 위해 연결할 수 있습니다. 이 경우 QR 텍스트가 동일한 경우 요청을 가로채고 캐시에서 응답을 제공합니다.

인터셉터 폴더를 만든 다음 cache-interceptor.ts 파일을 만듭니다.

캐시 인터셉터(큰 미리보기)

파일에 아래 코드 스니펫을 추가합니다.

 import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpResponse, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http'; import { tap } from 'rxjs/operators'; import { of, Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class RequestCachingService implements HttpInterceptor { private cacheMap = new Map<string, HttpResponse<any>>(); constructor() { } intercept(req: HttpRequest , next: HttpHandler): Observable<HttpEvent<any>> { const cachedResponse = this.cacheMap.get(req.urlWithParams); if (cachedResponse) { return of(cachedResponse); } return next.handle(req).pipe(tap(event => { if (event instanceof HttpResponse) { this.cacheMap.set(req.urlWithParams, event); } })) } } import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpResponse, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http'; import { tap } from 'rxjs/operators'; import { of, Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class RequestCachingService implements HttpInterceptor { private cacheMap = new Map<string, HttpResponse<any>>(); constructor() { } intercept(req: HttpRequest , next: HttpHandler): Observable<HttpEvent<any>> { const cachedResponse = this.cacheMap.get(req.urlWithParams); if (cachedResponse) { return of(cachedResponse); } return next.handle(req).pipe(tap(event => { if (event instanceof HttpResponse) { this.cacheMap.set(req.urlWithParams, event); } })) } }

위의 코드 스니펫에는 키가 요청 URL이고 응답이 값인 맵이 있습니다. 현재 URL이 지도에 있는지 확인합니다. if it is, then return the response (the rest is handled automatically). If the URL is not in the map, we add it.

아직 끝나지 않았습니다. An entry to the app.module.ts is required for its proper functioning. Add the below snippet:

 import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { CacheInterceptor } from './interceptor/cache-interceptor'; providers: [ { provide: HTTP_INTERCEPTORS, useClass: CacheInterceptor, multi: true } ],

This adds the caching feature to our application. Let's move on to the third page, the History page.

Adding The History Page

All the saved QR codes will be visible here. To create another component, open terminal type ng gc history and press Enter.

Open history.component.css and add the below code:

 .main-content { padding: 5% 10%; } .truncate { width: 90%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .center-img { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); display: flex; flex-direction: column; align-items: center; }

Open history.component.html and replace the content with this:

 <app-header [showBackButton]="showBackButton" [currentTitle]="title" [showHistoryNav]="showHistoryNav"></app-header> <div class="main-content"> <mat-grid-list cols="4" rowHeight="500px" *ngIf="historyList.length > 0"> <mat-grid-tile *ngFor="let qr of historyList"> <mat-card> <img mat-card-image src="{{qr.imageBase64}}"> <mat-card-content> <div class="truncate"> {{qr.text}} </div> </mat-card-content> <mat-card-actions> <button mat-button (click)="share(qr.text)">SHARE</button> <button mat-button color="accent" (click)="delete(qr.text)">DELETE</button> </mat-card-actions> </mat-card> </mat-grid-tile> </mat-grid-list> <div class="center-img" *ngIf="historyList.length == 0"> <img src="../../assets/no-see.png" width="256" height="256"> <span>Nothing to see here</span> </div> </div>

As usual, we have the header component at the top. Then, the rest of the body is a grid list that will show all the saved QR codes as individual mat-card . For the grid view, we are using mat-grid-list from the Angular material library. As per the drill, before we can use it, we have to first add it to the app.module.ts file.

매트 그리드 목록은 mat-grid-tile 이라는 여러 타일 자식이 있는 컨테이너 역할을 합니다. 위의 HTML 스니펫에서 각 타일은 다른 UI 요소의 일반적인 배치를 위한 속성 중 일부를 사용하여 mat-card 를 사용하여 생성됩니다. 너비를 자동으로 계산하는 데 사용되는 number of columnsrowHeight 를 제공할 수 있습니다. 위의 스니펫에서는 열 수와 rowHeight 값을 모두 제공하고 있습니다.

히스토리가 비어 있을 때 자리 표시자 이미지를 사용하고 있으며, 이를 다운로드하여 자산 폴더에 추가합니다.

이 모든 정보를 채우는 논리를 구현하려면 history.component.ts 파일을 열고 아래 스니펫을 HistoryComponent 클래스에 추가합니다.

 showBackButton = true; title = 'History'; showHistoryNav = false; historyList; constructor(private storageService: StorageutilService, private snackbar: MatSnackBar ) { } ngOnInit() { this.populateHistory(); } private populateHistory() { this.historyList = this.storageService.readAllHistory(); } delete(text: string) { this.storageService.deleteHistory(text); this.populateHistory(); } share(text: string) { this.snackbar.open(text, '', {duration: 2000,}) }

위의 로직은 저장된 모든 QR을 가져와 페이지를 채웁니다. 사용자는 로컬 저장소에서 항목을 삭제할 저장된 QR을 삭제할 수 있습니다.

이것은 우리의 히스토리 구성요소를 끝냅니다... 아니면 합니까? 이 구성 요소에 대한 경로 매핑을 추가해야 합니다. app-routing.module.ts 를 열고 기록 페이지에 대한 매핑도 추가합니다.

 { path: 'history', component: HistoryComponent },

이제 전체 경로 배열은 다음과 같아야 합니다.

 const routes: Routes = [ { path: '', component: HomeComponent }, { path: 'create', component: CreateQrComponent }, { path: 'history', component: HistoryComponent }, ];

이제 애플리케이션을 실행하여 전체 흐름을 확인할 좋은 시간이므로 터미널을 열고 ng serve 를 입력하고 Enter 키를 누릅니다. 그런 다음 localhost:4200 으로 이동하여 애플리케이션이 작동하는지 확인합니다.

GitHub에 추가

배포 단계를 진행하기 전에 GitHub 저장소에 프로젝트를 추가하는 것이 좋습니다.

  1. GitHub를 엽니다.
  2. 새 리포지토리를 만듭니다.
  3. GitHub 새 리포지토리(큰 미리보기)
  4. VS Code에서 터미널을 사용하고 빠른 시작 가이드에 언급된 첫 번째 명령 세트에 따라 모든 프로젝트 파일을 푸시합니다.
  5. GitHub에 프로젝트 추가(큰 미리보기)

모든 파일이 표시되는지 확인하려면 페이지를 새로고침하세요. 이 시점부터 git 변경 사항(커밋, 풀/푸시 등)은 새로 생성된 이 저장소에 반영됩니다.

Netlify 및 배포

우리 애플리케이션은 로컬 시스템에서 실행되지만 다른 사람들이 액세스할 수 있도록 하려면 클라우드 플랫폼에 배포하고 도메인 이름에 등록해야 합니다. 여기에서 Netlify가 작동합니다. 지속적인 배포 서비스, GitHub와의 통합 및 더 많은 기능을 제공합니다. 바로 지금, 우리는 우리 애플리케이션에 대한 전역 액세스를 활성화하려고 합니다. 시작하자.

  1. Netlify에 가입하십시오.
  2. 대시보드에서 New site from Git 버튼을 클릭합니다.
  3. Netlify 새 사이트(큰 미리보기)
  4. 다음 화면에서 GitHub를 클릭합니다.
  5. Netlify git 공급자 선택(큰 미리보기)
  6. Netlify가 GitHub 리포지토리에 액세스할 수 있도록 승인합니다.
  7. Netlify GitHub 인증(큰 미리보기)
  8. 새로 생성된 qr 저장소를 검색하여 선택합니다.
  9. Netlify GitHub 리포지토리 선택(큰 미리보기)
  10. Netlify는 다음 단계에서 배포할 GitHub 리포지토리 분기를 선택할 수 있도록 합니다. 일반적으로 하나는 master 분기를 사용하지만 릴리스 관련 및 안정적인 기능만 포함하는 별도의 release 분기를 가질 수도 있습니다.
  11. Netlify 빌드 및 배포(큰 미리보기)

Angular 웹 애플리케이션이므로 ng build --prod 를 빌드 명령으로 추가합니다. 게시된 디렉토리는 angular.json 파일에 언급된 대로 dist/qr 입니다.

Angular 빌드 경로(큰 미리보기)

이제 ng build --prod 명령으로 프로젝트 빌드를 트리거하고 파일을 dist/qr 에 출력하는 Deploy site 버튼을 클릭합니다.

Netlify에 경로 정보를 제공했기 때문에 웹 애플리케이션 서비스를 위한 올바른 파일을 자동으로 선택합니다. Netlify는 기본적으로 애플리케이션에 임의의 도메인을 추가합니다.

Netlify 사이트 배포(큰 미리보기)

이제 위 페이지에 제공된 링크를 클릭하여 어디서나 애플리케이션에 액세스할 수 있습니다. 마지막으로 애플리케이션이 배포되었습니다.

사용자 정의 도메인

위 이미지에서 우리 애플리케이션의 URL은 하위 도메인이 무작위로 생성되는 동안 표시됩니다. 변경해 보겠습니다.

Domain settings 버튼을 클릭한 다음 맞춤 도메인 섹션에서 점 3개 메뉴를 클릭하고 Edit site name 을 선택합니다.

사용자 정의 도메인(큰 미리보기)

그러면 새 사이트 이름을 입력할 수 있는 팝업이 열립니다. 이 이름은 Netlify 도메인 전체에서 고유해야 합니다. 사용 가능한 사이트 이름을 입력하고 저장 을 클릭합니다.

사이트 이름(큰 미리보기)

이제 응용 프로그램에 대한 링크가 새 사이트 이름으로 업데이트됩니다.

분할 테스트

Netlify가 제공하는 또 다른 멋진 기능은 분할 테스트입니다. 다른 사용자 집합이 다른 응용 프로그램 배포와 상호 작용할 수 있도록 트래픽 분할을 활성화합니다. 다른 분기에 새로운 기능을 추가하고 이 분기 배포로 트래픽을 분할하고 트래픽을 분석한 다음 기능 분기를 기본 배포 분기와 병합할 수 있습니다. 구성해 보겠습니다.

분할 테스트를 활성화하기 위한 전제 조건은 최소한 두 개의 분기가 있는 GitHub 리포지토리입니다. 앞서 생성한 GitHub의 앱 리포지토리로 이동하여 새 브랜치를 생성 a .

새 분기 만들기(큰 미리보기)

저장소에는 이제 master 분기와 분기 a 있습니다. 분기 배포를 수행하려면 Netlify를 구성해야 하므로 Netlify 대시보드를 열고 Settings 을 클릭합니다. 왼쪽에서 Build & Deploy 를 클릭한 다음 Continuous Deployment 를 클릭한 다음 Deploy contexts 섹션의 오른쪽에서 Edit settings 를 클릭합니다.

분기 배포(큰 미리보기)

Branch deploys 하위 섹션에서 "개별 분기 추가" 옵션을 선택하고 분기 이름을 입력하고 저장합니다.

brances 배포는 Netlify에서 제공하는 또 다른 유용한 기능입니다. 배포할 GitHub 리포지토리 분기를 선택할 수 있으며 병합하기 전에 master 분기에 대한 모든 풀 요청에 대한 미리보기를 활성화할 수도 있습니다. 이것은 개발자가 코드 변경 사항을 기본 배포 분기에 추가하기 전에 실제로 변경 사항을 테스트할 수 있도록 하는 깔끔한 기능입니다.

이제 페이지 상단의 Split Testing 탭 옵션을 클릭하십시오. 분할 테스트 구성이 여기에 표시됩니다.

분할 테스트(큰 미리보기)

우리는 (프로덕션 브랜치가 아닌) 브랜치를 선택할 수 있습니다. 이 경우 a . 트래픽 분할 설정을 가지고 놀 수도 있습니다. 각 분기에 할당된 트래픽 비율에 따라 Netlify는 일부 사용자를 분기를 사용 a 배포된 애플리케이션으로 다시 라우팅하고 다른 사용자는 master 분기로 다시 라우팅합니다. 구성한 후 Start test 버튼을 클릭하여 트래픽 분할을 활성화합니다.

: Netlify는 연결된 GitHub 리포지토리에 두 개 이상의 분기가 있음을 인식하지 못하고 다음 오류가 발생할 수 있습니다.

분할 테스트 오류(큰 미리보기)

이 문제를 해결하려면 Build & Deploy 옵션에서 리포지토리에 다시 연결하기만 하면 됩니다.

Netlify는 다른 많은 기능도 제공합니다. Netlify의 다양한 측면을 쉽게 구성할 수 있음을 보여주기 위해 유용한 기능 중 일부를 살펴보았습니다.

이것은 우리를 여행의 끝으로 이끕니다. 웹 애플리케이션을 기반으로 Angular Material 디자인을 성공적으로 생성하여 Netlify에 배포했습니다.

결론

Angular는 웹 애플리케이션 개발을 위한 훌륭하고 인기 있는 프레임워크입니다. 공식 Angular 머티리얼 디자인 라이브러리를 사용하면 사용자와의 매우 자연스러운 상호 작용을 위해 머티리얼 디자인 사양을 준수하는 애플리케이션을 훨씬 쉽게 만들 수 있습니다. 또한 훌륭한 프레임워크로 개발된 애플리케이션은 배포를 위해 훌륭한 플랫폼을 사용해야 하며 Netlify가 바로 그것입니다. 끊임없는 발전, 훌륭한 지원 및 다양한 기능을 통해 웹 애플리케이션이나 정적 사이트를 대중에게 제공하는 훌륭한 플랫폼임이 분명합니다. 바라건대, 이 기사는 생각부터 배포까지 새로운 Angular 프로젝트를 시작하는 데 도움이 될 것입니다.

추가 읽기

  • 앵귤러 아키텍처
  • 더 많은 앵귤러 머티리얼 컴포넌트
  • Netlify 기능에 대한 추가 정보