Angular Ivy의 빌드 시간, 번들 크기 및 기타 개선 사항 > 시티즌 인사이트

본문 바로가기

시티즌 커뮤니티

시티즌 인사이트

IT&개발 정보 Angular Ivy의 빌드 시간, 번들 크기 및 기타 개선 사항

페이지 정보

작성자 GrapeCity 작성일 21-04-06 11:30 조회 760회 댓글 0건

본문

Angular 9 출시와 함께 Angular의 새로운 컴파일러인 Ivy가 출시되었습니다. 처음에는 Angular 8과 함께 출시되었지만, 버전 9이 출시되면서 새로운 Angular 응용 프로그램의 기본 컴파일러가 되었습니다. Ivy는 Angular 4 출시 당시부터 Angular의 기본 컴파일러였던 View Engine 컴파일러를 대체합니다. 그러나 Angular 팀은 Angular 9에서 View Engine을 계속 사용할 수 있도록 했지만, Ivy 컴파일러에서 사용하기 위해서는 옵트인해야 합니다.


Ivy는 Angular사에 있어 큰 발전입니다. 개발자로서 Angular 응용 프로그램을 작성하는 기존의 방법을 유지하면서 프레임워크가 내부적으로 작동하는 방식을 완전히 변경한 것입니다. Angular가 Ivy를 변경한 것에는 다음의 두 가지 주요 목적이 있습니다.


  • 추가 컴파일을 통한 빌드 시간 단축

  • 개선된 트리 쉐이킹 호환성을 통한 번들 크기 향상


이 모든 것의 핵심은 개발자가 응용 프로그램 작성 방식을 바꿀 필요가 없다는 것입니다. Ivy는 기존 응용 프로그램과의 호환성을 목표로 하고 있으며, Ivy의 사용법은 대부분의 프로젝트에서 스위치를 누르는 것만큼이나 쉬울 것입니다.


번들 크기를 줄이는 것은 전반적으로 로딩 성능을 향상하면서 스마트폰이나 태블릿과 같은 모바일 디바이스를 통해 빌드한 응용 프로그램에 액세스하는 사람들의 사용자 환경을 개선하는 데 도움이 됩니다. 시간이 지남에 따라 모바일 디바이스 사용은 점점 증가해 2019년에는 미국 내 전체 인터넷 트래픽의 53%를 차지했습니다.


안타깝게도 모바일 디바이스는 종종 인터넷 연결 상태가 좋지 않고 속도가 느려서 최적의 속도로 응용 프로그램을 실행하는 것이 어렵습니다. 이 문제에 대한 해결책으로 CDN을 사용하여 파일을 제공하거나 PWA(Progressive Web App)를 사용하여 자산을 캐싱하는 방법이 있습니다. 하지만 여전히 개발자에게 가장 좋은 방법은 응용 프로그램이 생성하는 번들 크기를 줄이는 것입니다.


Ivy는 위에서 언급한 두 가지 기능 외에도 다음과 같은 기능이 향상되었습니다.

  • 빌드 오류 개선

  • 빠른 테스트

  • 더 나은 디버깅

  • CSS 및 스타일 바인딩 개선

  • 국제화 향상


블로그 전체에서 각 기능에 대해 좀 더 자세히 알아보겠습니다. 또한 개발자가 View Engine 및 Ivy 컴파일러와 호환되는 라이브러리를 만들고 Ivy 응용 프로그램 내에서 라이브러리를 사용하는 데 필요한 잠재적 변경 사항을 검토하는 시간도 가지겠습니다.



Ivy의 기능

트리 쉐이킹으로 개선된 번들링


우리가 살펴볼 첫 번째 개선 사항은 Ivy가 번들 크기를 줄이도록 돕는 방법입니다. 잠시 짚고 넘어가자면, JavaScript에서 번들링은 여러 개의 JavaScript 파일을 더 적은 수의 파일로 병합할 수 있는 최적화 기법입니다. 이 기법을 사용하면 사용자가 서버에 요청해야 하는 페이지 수를 줄일 수 있기 때문에 사용자를 위해 페이지를 더 빨리 렌더링할 수 있습니다.


그러면 트리 쉐이킹은 무엇일까요? 트리 쉐이킹은 JavaScript에서 불필요한 코드를 제거하는 것을 의미하는 용어입니다. 프로그램의 모든 실행 흐름이 함수 호출 트리로 표시되기 때문에 호출되지 않은 함수를 제거할 수 있는 것입니다.


CommonJS를 사용하여 응용 프로그램을 번들하면, 응용 프로그램을 빌드할 때 Angular에서 경고를 보냅니다. 경고를 보내는 이유는 운영 빌드를 수행할 때 CommonJS 모듈을 사용하면 번들 크기가 커질 수 있기 때문입니다. 그 이유는 CommonJS가 서버 측 응용 프로그램에서 사용되도록 설계되었기 때문입니다. 즉, 클라이언트 측 응용 프로그램에서의 실행에 최적화되지 않았기 때문입니다. 응용 프로그램이 여전히 CommonJS를 사용하는 중이면, ES 모듈을 사용하여 응용 프로그램을 번들로 전환하는 것이 좋습니다.


예를 들어, CommonJS를 사용하면 다른 모듈에서 기능을 가져올 때 경로에 변수를 전달할 수 있습니다. 반대로 ES 모듈에서는 문자열 리터럴이어야 합니다.


코드 1


첫 번째 줄은 CommonJS require 문이고, 두 번째 줄은 ES 모듈 import 문입니다. 보시는 것처럼 ES 모듈 import 문은 문자열 리터럴을 사용하는 반면, CommonJS require 문은 변수를 값으로 사용할 수 있습니다.


CommonJS는 종속성이 로드되는 방식이기 때문에 동적 접근 방식을 취할 수 있습니다. CommonJS는 런타임에 모듈을 로드해야 합니다. 모듈 로드, 인스턴스화, 평가가 모두 동시에 이루어집니다. 이 기능을 통해 변수를 파일 경로에 전달하는 등의 작업을 수행할 수 있는 것입니다. 이 작업은 런타임에 발생하기 때문에 응용 프로그램이 트리 쉐이킹을 수행하는 것을 더욱 어렵게 만듭니다.


하지만 ES 모듈은 이런 문제가 없습니다. ES 모듈은 더 정적이며, 정적으로 분석할 수 있습니다. 로드, 인스턴스화, 평가가 동시에 이루어지는 CommonJS와 달리 ES 모듈은 3개의 서로 다른 단계로 분리하여 수행됩니다. 그렇기 때문에 더 효율적인 트리 쉐이킹이 가능합니다.


그러면 ES2015를 사용하는 동안 Ivy는 왜 트리 쉐이킹을 허용하고 View Engine은 허용하지 않을까요? 이 부분은 Ivy와 View Engine이 각각 DOM을 업데이트하는 방식과 관련이 있습니다. View Engine은 응용 프로그램 코드를 처음 실행할 때, HTML 속성과 TypeScript 속성 사이의 모든 연결을 기록합니다.


그런 다음 각 HTML-TS-Property 연결을 위한 명령어 집합인 바인딩을 작성합니다. 이 바인딩은 컴포넌트에 따라 다르기 때문에, 몇 개의 일반 명령보다 최적화가 쉽습니다. 결과적으로 템플릿 데이터는 Angular 인터프리터에 의해 수집되고 DOM으로 변환됩니다.


템플릿 HTML 2


바인딩이 생성될 때마다 Angular는 변경 내용 검색을 위한 바인딩만 처리합니다. Angular에서 변경 사항을 수신하게 되면 모든 바인딩은 다시 평가됩니다. 이 과정을 더티 체킹이라고 합니다. 모든 바인딩을 다시 평가한 후 속성이 변경된 바인딩을 표시하고 업데이트합니다. 마지막으로 템플릿 데이터가 해석되고 최신 바인딩의 DOM으로 변환됩니다.


Ivy를 사용하면 템플릿 데이터를 생성하여 실행할 작업을 결정하는 인터프리터에 전달하는 대신 템플릿 명령어 집합이 직접 생성됩니다. 템플릿 명령어는 컴포넌트를 인스턴스화하는 논리가 DOM 노드를 생성하고 변경 내용 검색을 실행하는 위치에 있습니다. 두 번째 이미지에 나와 있는 새 렌더링 파이프라인을 확인해 보세요.


템플릿 HTML 3


번들링과 관련해서 마지막으로 살펴볼 것은 번들 크기가 얼마나 줄어드는가 하는 것입니다. Angular 팀에 따르면 소규모 및 대규모 응용 프로그램의 경우 번들 크기가 약 20~30% 감소할 것이며 중간 규모 응용 프로그램의 경우 이보다 약간 더 낮은 수치로 감소할 것이라고 말합니다. 내부 테스트 결과는 여기서 확인할 수 있습니다.


테스트 결과 4


이 테스트에서는 View Engine을 사용한 번들 크기와 Ivy 컴파일러를 비교했습니다. 첫 번째 열에는 각 프로젝트에 포함된 Wijmo 컨트롤이 표시됩니다. 두 번째 열은 Ivy 컴파일러의 번들 크기 출력이고, 세 번째 열은 View Engine의 번들 크기 출력이며, 마지막 열에는 두 Angular 컴파일러 사이의 번들 크기 감소가 백분율로 표시됩니다.


테스트 결과, 일부 소규모 응용 프로그램에서는 30% 이상 감소했으며, 중간 규모 응용 프로그램에서는 25% 정도 감소하는 것으로 나타났습니다. 모든 테스트가 끝났을 때 전체 번들 크기는 30% 감소한 것으로 확인되었고, 이는 Angular 팀이 예상했던 수치와 일치했습니다.



빌드 시간 및 오류 개선


지금부터 살펴볼 두 번째 큰 변화는 Ivy의 출시로 Angular 팀이 응용 프로그램 빌드 시간과 빌드 오류를 모두 개선한 것입니다. 응용 프로그램을 빌드할 때 각 빌드는 Angular가 모듈 내부의 모든 정보를 다시 컴파일하도록 하고 코드의 변경 사항을 확인합니다. 왜냐하면 컴포넌트의 생성된 코드가 다른 컴포넌트의 내부 세부 정보를 사용하고 있을 수 있기 때문입니다.


이제 각 컴포넌트는 공용 API에서만 사용하는 지시문과 컴포넌트를 참조합니다. 컴포넌트 또는 지시문의 내부 세부 정보를 수정하는 경우, 응용 프로그램은 수정된 코드를 사용하는 다른 컴포넌트가 무엇인지 알게 되며 해당 컴포넌트만 다시 컴파일합니다. 이는 많은 컴포넌트 및 지시문이 포함된 응용 프로그램의 빌드 시간에 상당히 유리할 수 있습니다. 전체 응용 프로그램을 다시 컴파일하는 대신 필요한 컴포넌트만 다시 컴파일할 수 있기 때문입니다.


이러한 변경 사항 중 일부가 실제 컴파일러에서는 어떻게 보이는지 간단한 예를 통해 살펴보겠습니다. 이 샘플에서는 컴포넌트가 생성될 때 car라는 입력 값을 갖는 모의 컴포넌트인 CarComponent에 대해 살펴봅니다.


코드 5


이제 CarComponent 컴포넌트가 다른 컴포넌트 템플릿 내에서 사용될 때의 코드는 다음과 비슷합니다.

코드 6

코드 7


View Engine과 Ivy 컴파일러가 컴포넌트의 입력으로 생성하는 코드를 살펴보겠습니다. Ivy에서는 코드가 다음과 비슷합니다.

코드 8


여기서 확인할 수 있듯이, Ivy 코드가 CarComponent의 공개 이름을 참조하고 있습니다. 다음 View Engine 컴파일러에서 생성된 코드와 비교해 보세요.

코드 9


여기에서 View Engine이 생성한 코드는 CarComponent의 개인 필드만 참조합니다. 우리가 여기서 확인할 수 있는 차이점은 Ivy의 ‘지역성의 원칙’으로 인해 발생하게 됩니다.


Ivy에서 지역성의 원칙은 Ivy에서 컴포넌트를 컴파일하기 위해 Angular가 선언할 수 있는 종속성의 이름과 패키지 이름을 제외한, 컴포넌트 자체에 대한 정보만 필요로 한다는 것을 의미합니다. 특히 Ivy는 컴포넌트를 컴파일하기 위해 선언 가능한 종속성의 메타데이터를 필요로 하지 않습니다.


그저 하나의 예시이지만, 이 내용은 소규모 응용 프로그램뿐만 아니라 대규모 응용 프로그램에도 적용됩니다. Angular 팀은 전반적으로 빌드 시간이 약 40% 정도 개선될 것으로 예상하고 있습니다.


Angular 팀이 Ivy에서 수행한 이러한 개선 사항의 장점은 Angular의 AOT(Ahead-of-Time) 빌드가 눈에 띄게 더 빠르다는 것입니다. 즉, Angular 팀이 개발자 모드와 운영 모드에서 모두 Ivy 응용 프로그램을 위한 기본 빌드를 구축했다는 것을 의미합니다.


운영 모드뿐만 아니라 개발 모드에서 이러한 종류의 빌드를 허용하는 변경 사항으로 인해 프레젠테이션의 뒷부분에서 언급할 응용 프로그램의 다른 기능들이 개선되었기 때문에 AOT 빌드에 대해 간단히 언급하고자 합니다. 따라서 AOT의 구조에 대한 간단한 이해가 필요합니다.


AOT(Ahead-of-Time) 컴파일은 브라우저가 코드를 다운로드하고 실행하기 전 빌드 중에 Angular HTML 및 TypeScript에서 효율적인 JavaScript 코드로 변환합니다. 빌드 프로세스 중에 응용 프로그램을 컴파일하면 브라우저에서 렌더링 속도가 빨라지게 됩니다.


AOT를 사용하면 좋은 점 몇 가지는 다음과 같습니다.

  • 더 빠른 렌더링 - AOT를 사용하면 브라우저가 미리 컴파일된 버전의 응용 프로그램을 다운로드합니다. 브라우저는 즉시 응용 프로그램을 렌더링하기 위해 응용 프로그램을 컴파일할 때까지 기다리지 않고 실행 코드를 로드합니다.

  • 더 적은 비동기식 요청 – 컴파일러는 외부 HTML 템플릿과 응용 프로그램 JavaScript 내의 CSS 스타일 시트를 인라인 처리하여 소스 파일에 대한 별도의 Ajax 요청을 제거합니다.

  • Angular 프레임워크 다운로드 크기 감소 - 응용 프로그램이 이미 컴파일된 경우 Angular 컴파일러를 다운로드할 필요가 없습니다. 컴파일러는 Angular 자체의 절반 정도를 차지하기 때문에 이 작업을 생략하면 응용 프로그램 페이로드를 크게 줄일 수 있습니다.

  • 더 빠른 템플릿 오류 검색 - 사용자가 확인할 수 있기 전에 AOT 컴파일러가 빌드 단계에서 템플릿 바인딩 오류를 검색하고 보고합니다.

  • 강화된 보안 - AOT는 HTML 템플릿 및 컴포넌트를 클라이언트에 제공하기 훨씬 전에 JavaScript 파일로 컴파일합니다. 읽을 템플릿이 없고 위험한 클라이언트 측 HTML 또는 JavaScript 평가가 없으면 삽입 공격의 위험도 적습니다.


Ivy 컴파일러는 빌드 시간을 개선하기 위한 변경 사항을 포함할 뿐만 아니라 빌드 프로세스 중에 Angular가 표시하는 오류 메시지도 개선했습니다. 예를 들어 Angular의 다음 오류 출력을 살펴봅시다.

오류 10


이제 우리가 Ivy 컴파일러를 사용할 때 동일한 코드가 응용 프로그램 빌드 중에 오류를 발생시킵니다.

오류 11


View Engine과 Ivy 컴파일러 사이에 오류 메시지의 가독성에는 큰 차이가 있습니다. 오류 메시지의 글머리 기호는 동일합니다. 이 글머리 기호는 로드하려는 사용자 요소가 컴포넌트일 수 있지만 빌드할 때 모듈의 일부로 포함되지 않았음을 개발자에게 알려줍니다.


하지만 Ivy 오류는 오류를 일으키는 코드가 있는 파일과 나타나는 줄로 구성되어 있습니다. 따라서 특히 더 복잡한 오류의 경우 코드 오류를 훨씬 쉽게 해결할 수 있습니다.



빠른 테스트


이제 응용 프로그램을 더 빠르고 효율적으로 테스트하기 위해 Ivy에서 변경한 몇 가지에 대해 알아보겠습니다.


Ivy가 출시되면서 Angular는 이제 테스트 단계를 비롯한 프로젝트의 모든 단계에서 AOT 컴파일을 사용할 수 있게 되었습니다. 이렇게 되면 테스트 환경과 운영 환경 간의 차이가 적어지기 때문에 오류를 더 빨리 잡아낼 수 있습니다.


또한 Angular 팀은 이 기회를 통해 Ivy에서 Angular의 TestBed 클래스 구현을 개선하여 효율성을 향상했습니다.


이전에 TestBed는 재정의 등을 통한 컴포넌트의 변경 여부에 관계없이 각 테스트 실행 사이의 모든 컴포넌트를 다시 컴파일했습니다.


Ivy에서 TestBed는 컴포넌트가 수동으로 재정의되지 않는 한 테스트 간에 컴포넌트를 다시 컴파일하지 않으므로 대부분의 개발자 테스트 간의 재컴파일 작업을 방지할 수 있습니다.


Angular 팀은 이러한 변화를 통해 프레임워크의 핵심 허용 테스트 속도가 약 40% 빨라진 것을 확인했습니다. Angular 팀은 사용자의 응용 프로그램 테스트 속도가 이전보다 약 40~50% 더 빨라질 것으로 예상한다고 밝혔습니다.


또한 Angular CDK는 버전 9의 테스트 하위 패키지를 도입하여 테스트 케이스에 대한 컴포넌트 하네스를 구현합니다.


컴포넌트 하네스는 컴포넌트의 구현 세부 정보를 숨깁니다. ARIA 특성과 같은 중요한 DOM 특성을 검색할 수 있고, 컴포넌트의 DOM을 쿼리하지 않고도 사용자처럼 컴포넌트와 상호 작용할 수 있으며, 현재 컴포넌트에 의해 트리거된 하위 컴포넌트 대화 상자 및 메뉴와 같은 하네스 관련 컴포넌트를 사용할 수 있는 API를 제공합니다.


컴포넌트 하네스는 유닛 테스트, 통합 테스트 및 엔드투엔드 테스트에 사용됩니다. Angular CDK는 즉시 사용할 수 있는 두 가지 하네스 환경과 함께 제공됩니다.

  • TestbedHarnessEnvironment는 유닛 테스트와 통합 테스트에 사용됩니다.

  • ProtractorHarnessEnvironment는 Protractor에 의해 구동되는 엔드투엔드 테스트에 사용됩니다.


TestbedHarnessEnvironment는 무엇보다도 DeFacto Angular 유닛 테스트 스택인 Jasmine 및 Karma와 함께 사용하도록 되어 있지만, 다른 테스트 러너 및 테스트 프레임워크와도 함께 작동해야 합니다.



디버깅 개선


웹 응용 프로그램을 디버깅할 수 있는 많은 도구가 있습니다. 코드에서 간단한 로깅 문을 사용하는 것부터 브라우저 개발 도구 및 웹 확장에 이르기까지 응용 프로그램 디버깅 문제를 해결할 수 있는 다양한 방법이 있습니다. 하지만 Angular 팀은 Ivy의 출시와 함께 새로운 도구, 즉 ng라는 전역 변수를 제공했습니다.


이 새로운 변수를 사용하면 해당하는 Angular 컴포넌트에 액세스할 수 있습니다. 컴포넌트 속성과 함수를 볼 수 있을 뿐만 아니라 브라우저의 콘솔에서 해당 속성과 함수를 수정하고 변경 내용 검색을 트리거할 수도 있습니다.


ng 개체를 사용하려면 dev 모드로 응용 프로그램을 실행해야 합니다. ng 개체를 사용하여 다음을 수행할 수 있습니다.

  • Angular에 컴포넌트, 지시문 등의 인스턴스에 대한 액세스 요청

  • 메서드를 수동으로 호출하고 상태 업데이트

  • 변경 내용 검색 결과를 확인하려는 경우 applyChanges를 사용한 변경 내용 검색 트리거


이렇게 하면 추가 도구 없이 브라우저에서 컴포넌트 상태를 직접 볼 수 있으므로 불필요한 로깅 문을 코드에 삽입하지 않아도 됩니다

.

Angular 개발에서 가장 골치 아픈 오류 중 하나는 ExpressionChangedAfterItHasBeenChecked 오류입니다. 오류 출력이 복잡하기 때문에 문제를 디버깅하고 근본 원인을 찾기가 어렵기 때문입니다.

오류 12


Ivy를 사용하면 오류 메시지가 훨씬 더 유용한 스택 추적을 출력하므로 변경된 식을 사용하여 템플릿 명령으로 바로 이동할 수 있습니다.


예를 들어, 아래 스택 추적에서 AppComponent_Template을 클릭하면 생성된 코드에서 오류가 발생한 특정 줄을 발견할 수 있습니다.

오류 13

오류 14


원할 경우 이 프레임워크 명령에 따라 프레임워크가 컴포넌트를 만들고 업데이트하는 방법을 살펴볼 수도 있습니다.



CSS 및 스타일 바인딩 개선


Ivy 컴파일러 및 런타임은 스타일 처리 및 HTML 템플릿 내에서 스타일 변수를 사용할 수 있는 기능에 대한 개선 사항을 제공합니다.


이전 Angular 버전의 경우, HTML 요소에서 마지막으로 평가된 스타일 바인딩은 적용된 스타일입니다 다음의 코드 조각을 확인해 보세요.

코드 15

코드 16


요소에 색상을 적용하는 방법에는 스타일 특성을 이용하는 방법, style.color를 사용해 값을 할당하는 방법, 그리고 변수로 색상 속성을 설정하는 방법의 세 가지가 있습니다. 이 시나리오에서는 적용되는 마지막 스타일이 적용될 스타일입니다. myColor와 otherColor가 모두 정의되지 않은 경우 정적 'red'는 나중에 제공된 스타일 설정에 의해 덮어쓰기되므로 무시됩니다.


Ivy 컴파일러를 사용하면 명확하고 간결한 우선순위를 통해 컴파일되는 코드에 영향을 미칠 스타일을 결정할 수 있습니다. Ivy를 사용하면 가장 구체적인 스타일은 항상 가장 높은 우선순위를 가집니다. 예를 들어, [style.color]를 통해 요소의 색상을 바인딩하면 충돌하는 바인딩을 [style]로 재정의합니다.


또 다른 변경 사항은 HTML 템플릿 내에서 CSS 변수를 사용하는 기능입니다.

코드 17


이 코드 조각을 보면 div 내에 CSS 변수를 설정한 후 이 변수를 다음 단락 요소에서 사용하는 것을 확인할 수 있습니다.


개선된 템플릿 유형 검사


TypeScript가 코드에서 형식 오류를 검색하는 방법과 마찬가지로, Angular는 응용 프로그램의 템플릿에 있는 표현식과 바인딩을 검사하고 발견된 모든 유형의 오류를 보고할 수 있습니다. View Engine에서 Ivy로 전환하면서 Angular 팀은 fullTemplateTypeCheck 설정과 사용하여 보다 쉽게 오류를 검색할 수 있도록 몇 가지를 개선하고 새로운 설정인 strictTemplates를 추가했습니다.


Ivy에서 유형 검사를 위한 새로운 변경 작업을 시작하기 전에 Angle 8에서 템플릿 유형 검사를 간단히 검토할 것입니다. 다음 컴포넌트는 템플릿의 heroes 목록을 표시합니다.

코드 18

코드 19


다음은 tsconfig.json 파일입니다. 이 파일에서는 fullTemplateTypeCheck 속성을 살펴보겠습니다(Angular 8에서 기본값은 true로 설정됨).

코드 20


ng 빌드를 사용하여 응용 프로그램을 빌드할 때 모든 내용은 성공적으로 컴파일되지만, 브라우저에 표시되는 방법에는 몇 가지 문제가 있습니다.

국가 21


표시하려는 제목이 누락되었고 각 국가 코드도 목록에 표시되지 않은 것을 볼 수 있습니다. 그러나 응용 프로그램은 빌드 프로세스 중에 오류를 발생시키지 않고 개발자에게 이 문제를 알려줍니다.


하지만 ngbuild --prod 명령을 실행하여 AOT를 사용하는 동안 응용 프로그램을 빌드하려고 하면 문제가 발생합니다. 명령을 실행하면 Angular에서 컴포넌트에 제목 속성이 존재하지 않는다고 보고합니다. AOT 및 fullTemplateTypeCheck 속성이 모두 true로 설정된 경우, Angular는 컴포넌트에서 누락된 모델을 참조할 때 검색할 수 있습니다.

오류 22


fullTemplateTypeCheck 속성이 true로 설정되어 있을 경우, Angular는 템플릿 내에서 보다 적극적으로 유형 검사를 수행합니다.

  • ngFor and ngIf와 같은 포함된 보기 확인

  • 파이프가 올바른 반환 형식인지 확인

  • 지시문과 파이프에 대한 로컬 참조가 올바른 유형인지 확인(모든 일반 매개 변수 제외)


이제 Ivy가 프로젝트를 빌드할 때 유형 검사를 어떻게 처리하는지 알아보겠습니다. Ivy를 사용하는 동안 tsconfig.json 파일로 다시 이동하여 fullTemplateTypeCheck가 true로 설정되어 있는지 확인하겠습니다. 지금 응용 프로그램을 실행하면 이전에 ng 빌드를 사용했던 경우와 유사한 오류가 발생합니다.

오류 23


가장 먼저 눈에 띄는 것은 오류 메시지가 개선된 것입니다. 이전 메시지의 모든 정보가 포함되지만, 구성이 조금 더 개선된 것을 여기서 볼 수 있습니다. 또한 오류를 일으키는 코드 줄을 정확하게 보여줍니다. 이 경우 제목 변수에 저장된 텍스트를 표시하려고 하는 것이 HTML 줄입니다.


Ivy는 기본적으로 AOT를 사용합니다. 그래서 이제는 운영 빌드를 지정할 필요 없이 이러한 오류를 경험하게 됩니다. 모든 종류의 빌드에 대한 변경과 AOT 사용으로 인해 개발자들은 이제 이러한 템플릿 유형 검사 오류를 더 빨리 잡아낼 수 있게 됩니다. app.component.ts 파일로 돌아가서 제목 속성을 추가하고 HTML에서 국가 코드 속성 ID를 수정하면 문제없이 응용 프로그램을 실행할 수 있습니다.


국가 24


이제 Ivy에서 더 많은 유형 검사를 위해 추가된 새로운 설정인 strictTemplate을 사용한 strict 모드를 살펴보겠습니다. strict 모드는 전체 모드의 상위 집합이며 엄격한 strictTemplate 설정을 true로 설정하여 사용할 수 있습니다. strict 모드에서 Ivy는 다음과 같은 전체 모드의 검사를 능가하는 검사를 추가합니다.

  • 컴포넌트나 지시문 바인딩이 @Input()에 할당 가능한지 확인

  • 위의 유효성을 검사할 때 TypeScript의 strictNullChecks 플래그 준수

  • 제네릭을 포함하여 올바른 유형의 컴포넌트/지시문 추론

  • 템플릿 컨텍스트 유형이 구성되어 있는지 추론(예: ngFor에 대한 올바른 유형 검사 허용)

  • 컴포넌트/지시문, DOM, 애니메이션 이벤트 바인딩에서 올바른 유형의 $event 추론

  • 태그 이름을 기준으로 DOM 요소에 대한 올바른 유형의 로컬 참조 추론(예: document.createElement가 해당 태그에 대해 반환하는 유형)


strict 모드를 사용하려면 먼저 tsconfig.json 파일을 다시 열어야 합니다. fullTemplateTypeCheck 설정을 탐색하고 strictTemplate 설정으로 대체합니다. 그런 다음 응용 프로그램이 strict 모드 템플릿 유형 검사를 수행하도록 strictTemplate 설정이 true로 설정되어 있는지 확인해야 합니다.

코드 25



향상된 국제화 및 현지화

Ivy 컴파일러는 응용 프로그램 국제화 및 현지화 기능도 향상했습니다. 국제화는 다른 언어에서도 응용 프로그램이 사용될 수 있도록 설계하고 준비하는 과정입니다. 현지화는 국제화된 응용 프로그램을 특정 로케일의 특정 언어로 번역하는 과정입니다.

현지화 가능한 메시지를 추가할 항목을 표시하려면 i18n 특성을 요소에 포함해야 합니다.

Angular 컴파일러는 컴파일러 구성에서 번역 집합이 제공된 경우 템플릿을 다른 텍스트로 컴파일할 때 해당 텍스트를 대체합니다. i18n 태그는 뛰어난 태그입니다. i18n 태그는 특성과 콘텐츠에서 사용할 수 있으며 복잡한 중첩 ICU 표현식을 포함할 수 있고 메타데이터를 첨부할 수도 있습니다.

하지만 국제화 및 현지화에서도 몇 가지 문제가 있습니다. 가장 큰 문제는 템플릿 컴파일 중에 번역이 되어야 한다는 것이었습니다. 컴파일은 빌드 파이프라인이 시작될 때 바로 발생합니다. 따라서 응용 프로그램에서 지원할 각 로케일에 대해 전체 빌드, 컴파일 번들링 축소 등이 수행되어야 합니다.

즉, 단일 빌드에 2분이 걸리는 경우 12개 언어를 지원하기 위한 총 빌드 시간은 24분이 됩니다.

게다가, 번역을 위해 응용 프로그램 코드에 텍스트를 표시하고 컴포넌트 템플릿의 텍스트만 표시하는 것은 불가능했습니다. 이로 인해 개발자가 단지 번역된 텍스트를 보관하기 위해 존재하는 인공 컴포넌트를 만드는 어색한 해결 방법이 생겼습니다.

결국 런타임에 번역을 로드하는 것이 불가능했습니다. 즉, 자체 번역을 제공하려는 최종 사용자에게 응용 프로그램을 제공할 수 없었습니다.

Ivy 컴파일러는 번역을 직접 하지 않고 $localize가 태그된 문자열을 생성하도록 다시 변경되었습니다. 이것은 Angular 컴파일러가 작업을 완료한 후, i18n 특성이 표시된 모든 템플릿 텍스트가 $localize 태그된 문자열로 변환되어 태그가 지정된 다른 문자열과 동일하게 처리될 수 있음을 의미합니다.


Ivy 컴파일러 사용하기


Angular 9 이상 버전을 사용하고 있으면 기본적으로 프로젝트에서 Ivy가 활성화되어 있습니다. 현재 Angular 8에서 작업 중이면 View Engine은 기본적으로 활성화되어 있지만 원하는 경우 Ivy 컴파일러를 허용할 수 있습니다. 하지만 Ivy 컴파일러를 사용하려면 최신 버전의 Angular를 사용하는 것이 좋습니다. 그렇게 하면 Angular 팀이 공개하는 최신 기능과 수정 사항을 모두 이용할 수 있습니다.


Ivy를 사용하기 위해 기존 응용 프로그램을 업그레이드하는 경우 Angular 팀은 개발자가 Ivy에서 응용 프로그램을 실행하기 위해 최소한의 작업만 수행할 수 있도록 최선을 다했습니다. 하지만 여전히 변경해야 할 사항이 몇 가지 있을 수 있습니다.


Ivy 사용 중에 오류가 발생하는 경우 먼저 Ivy를 종료하세요. 이 작업은 tsconfig.json file의 angularCompilerOptions에서 수행할 수 있습니다. false로 설정하고 응용 프로그램을 다시 시작하세요. 아무 오류도 발견되지 않으면 해당 문제가 Ivy와 관련이 있는 것입니다.


가장 일반적인 변경 사항은 다음과 같습니다.

  • 기본적으로 @ContentChildren 쿼리는 DOM 계층에서 직접 하위 노드만 검색합니다(이전에는 DOM에서 다른 명령이 일치하지 않는 한 모든 중첩 수준을 검색함).

  • Angular DI를 사용하는 모든 클래스에는 @Directive() 또는 @Injectable과 같은 Angular 데코레이터가 있어야 합니다(이전에는 AOT 모드나 삽입 플래그가 사용된 경우에만 데코레이팅되지 않은 레벨이 허용됨).

  • 이제 변경 내용 검색이 실행되기 전에 보기를 만들 때 지시문에 대해 바인딩되지 않은 입력이 설정됩니다(이전에는 모든 입력이 변경 내용 검색 도중에 설정됨).

  • 템플릿의 HTML에 직접 설정된 정적 특성은 지시문 또는 컴포넌트에 의해 설정된 충돌하는 호스트 특성을 재정의합니다. 이전에는 지시문/컴포넌트에 의해 설정된 정적 호스트 특성이 충돌하는 경우 정적 템플릿 속성을 재정의했습니다.


개발자가 볼 수 있는 일반적인 변경 사항 몇 가지는 다음과 같습니다.

  • @Component 또는 @Directive 데코레이터 내부의 호스트와 같은 속성을 상속할 수 있습니다.

  • HammerJS 지원은 HammerJSModule을 가져올 때 옵트인됩니다.

  • @ContentChild 및 @ContentChildren 쿼리는 더 이상 지시문의 호스트 노드와 일치할 수 없습니다.

  • 토큰이 @Self 플래그의 @Host와 함께 삽입되면 모듈 인젝터는 해당 토큰을 검색하지 않습니다.

  • 템플릿 바인딩에서 이름이 같은 여러 로컬 참조에 액세스할 때 첫 번째 참조가 일치합니다.

  • 내보낸 모듈에서 사용된 지시문은 공개적으로 내보냅니다.

  • 데코레이터 메타데이터의 외부 함수 또는 외부 상수는 정적으로 확인할 수 없습니다.

  • 로컬 참조를 통해 액세스한 지시문 입력에 대한 전달 참조는 더 이상 기본적으로 지원되지 않습니다.

  • 바인딩되지 않은 css 특성과 [class] 바인딩이 모두 있는 경우 바인딩되지 않은 특성 클래스도 추가됩니다.

  • 이제 ngFor="let items of items"의 item과 같은 템플릿 전용 변수에 값을 할당하는 것은 오류입니다.

  • 이제 더 이상 테스트를 위해 지시문 인스턴스에서 모의로 수명 주기 후크를 덮어쓸 수 없습니다.

  • 특수 삽입 토큰은 요청될 때마다 새 인스턴스를 반환합니다. 이는 주로 해당 개체의 ID 비교를 수행하는 테스트에 영향을 미칩니다.

  • ICU 구문 분석은 런타임에 실행되므로 ICU 사례 내에서 텍스트, HTML 태그, 텍스트 바인딩만 허용됩니다.

  • 원본 템플릿에 없는 i18n 번역에 텍스트 바인딩을 추가하면 런타임 오류가 발생합니다.

  • 원본 템플릿에 없는 i18n 번역의 추가 HTML 태그는 일반 텍스트로 렌더링됩니다.

  • useValue, useFactory, useExisting 또는 useClass 속성이 없는 {provide: X}로 형식이 지정된 Privoder는 {provide: X, useClass: X}처럼 처리됩니다.

  • DebugElement.attributes는 추가된 후 제거된 특성에 대해 정의되지 않은 상태로 반환합니다.

  • DebugElement.classes는 추가된 후 제거된 클래스에 대해 정의되지 않은 상태로 반환합니다.

  • *ngFor를 통해 옵션이 생성되는 선택 항목에서 네이티브 옵션 요소를 선택하는 경우 선택 요소의 [value] 속성에 바인딩하는 대신 옵션의 [selected] 속성을 사용하세요.

  • 포함된 보기는 이제 이전과 마찬가지로 앵커 DOM 주석 노드 뒤에 삽입되지 않고 앵커 DOM 주석 노드 앞에 삽입됩니다.



Ivy로 라이브러리 빌드 및 이용

View Engine 컴파일러에서 Ivy 컴파일러로 변경되면서 개발자들은 View Engine을 사용하여 빌드된 라이브러리를 계속 사용할지에 대해 의문을 가질 수 있습니다. 다행히 Angular 팀은 View Engine 컴파일 라이브러리를 Ivy와 함께 쉽게 사용할 수 있도록 Angular 호환성 컴파일러를 제작했습니다.


Angular 호환성 Aompiler(또는 ngcc)는 View Engine 컴파일러에서 생성한 사전 컴파일된 JavaScript 코드를 구문 분석합니다. 그러면 Ivy 컴파일러가 컴파일한 것처럼 코드를 업데이트합니다.


View Engine 내에 구축된 라이브러리를 사용하는 경우 호환성 컴파일러를 활성화해야 합니다. 이렇게 하려면 프로젝트의 package.json 파일을 열고 postinstall npm 스크립트를 추가해야 합니다.

{  
“scripts”: {  
  “postinstall”: “ngcc”  
}  
}


postinstall 스크립트는 ng update 및 ng add에 의해 수행된 node_modules를 포함하여 모든 node_modules 설치 시 실행됩니다.


호환성 컴파일러는 .metadata.json 파일을 확인하여 APF(Angular Package Format)인 패키지의 node_modules 폴더를 검사하여 작동합니다. 그런 다음 호환성 컴파일러는 각 패키지에 대해 Ivy 호환 버전을 생성합니다.


라이브러리 작성자이거나 Angular 라이브러리를 지원하는 경우, Angular 팀은 계속 View Engine 컴파일러를 사용하여 라이브러리를 작성할 것을 권장합니다. Ivy에서 생성한 코드는 이전 버전의 View Engine과 호환되지 않으므로 View Engine을 사용하는 응용 프로그램은 Ivy 생성 코드를 활용할 수 없기 때문입니다.


게다가, 내부 Ivy 명령어들은 아직 안정적이지 않아서, 라이브러리를 구축하는 데 사용된 것과 다른 버전의 Angular를 사용하여 응용 프로그램을 중단시킬 가능성이 있습니다. Angular CLI가 호환성 컴파일러를 사용하여 View Engine에서 생성한 코드를 Ivy와 호환 가능한 코드로 변환하도록 하는 것이 좋습니다.


마무리하며

지금까지 View Engine 컴파일러에서 Ivy 컴파일러로 전환하면서 Angular 팀이 수행할 수 있는 모든 주요 변경 사항에 대해 다루어 보았습니다. 이 프레젠테이션에서 설명한 내용이 많기 때문에 가장 중요한 변경 사항과 Ivy 컴파일러로 전환한 이유를 간략히 다시 살펴보고자 합니다.

  • 향상된 번들링: Ivy는 렌더링 처리 방식과 View Engine의 렌더링 방식을 변경했습니다. View Engine은 템플릿 HTML에서 템플릿 데이터를 만들어야 했고, 그 후 이 데이터를 DOM을 만드는 데 사용하는 Angular 컴파일러로 전달했습니다. Ivy 엔진은 DOM으로 변환하는 데 필요한 템플릿 데이터와 컴파일러를 제거하고 대신 HTML에서 생성된 템플릿 명령어 집합을 사용하여 DOM을 생성합니다. 이를 통해 번들러는 번들링 시 파일에서 사용되지 않은 코드를 제거하는 작업인 트리 쉐이킹을 보다 쉽게 수행할 수 있게 되었습니다. 그 결과 응용 프로그램의 번들 파일 크기가 작아지면서 사용자의 렌더링 속도가 향상됩니다.

  • 빌드 오류 개선: 이제 Angular 팀은 응용 프로그램을 빌드할 때 지역성의 원칙을 사용합니다. Ivy에서 지역성의 원칙은 Ivy에서 컴포넌트를 컴파일하기 위해 Angular가 선언할 수 있는 종속성의 이름과 패키지 이름을 제외한, 컴포넌트 자체에 대한 정보만 필요로 한다는 것을 의미합니다. 특히 Ivy는 컴포넌트를 컴파일하기 위해 선언 가능한 종속성의 메타데이터를 필요로 하지 않습니다. 이로 인해 AOT 컴파일이 훨씬 빨라졌습니다. Angular 팀이 AOT를 응용 프로그램의 기본 빌드 옵션으로 지정했기 때문에 운영 빌드 중에 나타날 수 있는 빌드 오류를 더 쉽게 찾아낼 수 있습니다.


지금까지 봤던 것처럼, 일부 개발자들은 View Engine 컴파일러에서 Ivy 컴파일러로 업그레이드하는 과정에 약간의 변화를 주어야 합니다. 잠재적인 변경 사항 외에도, Ivy로의 변경은 개발자가 응용 프로그램 구축 방식을 변경할 필요가 없도록 했으며, Angular 팀이 백엔드에서 변경한 사항의 모든 이점을 제공합니다.

  • 페이스북으로 공유
  • 트위터로  공유
  • 구글플러스로 공유
  • 카카오톡으로 보내기

댓글목록

등록된 댓글이 없습니다.

그레이프시티 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기

인기글

더보기
  • 인기 게시물이 없습니다.
그레이프시티 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기
이메일 : sales-kor@grapecity.com | 전화 : 1670-0583 | 경기도 안양시 동안구 시민대로 230, B-703(관양동, 아크로타워) 그레이프시티(주) 대표자 : 허경명 | 사업자등록번호 : 123-84-00981 | 통신판매업신고번호 : 2013-경기안양-00331 Copyright ⓒ 2021 GrapeCity inc.