JavaScript
#
2021-12-14#
List- JS-Proxy
- Creating a proxy object
- A simple proxy example
- Proxy Traps
#
JS-ProxyProxy
는 특정 객체를 감싸 프로퍼티 읽기, 쓰기와 같은 객체에 가해지는 작업을 중간에서 가로채는 객체이다.
가로채진 작업은 Proxy
자체에서 처리되기도 하고, 원래 객체가 처리하도록 그대로 전달되기도 한다.
#
Creating a proxy object- target – 감싸게 될 객체로, 함수를 포함한 모든 객체 포함
- handler – 동작을 가로채는 메서드인 '트랩(trap)'이 담긴 객체로, 여기서
Proxy
를 설정
#
A simple proxy exampleuser
객체에 proxyUser로
접근할경우 get()
메서드가 호출된다.
user
객체를 변경하면 proxyUser
에도 반영된다.
proxyUser
객체를 변경해도 user
에 반영된다.
#
Proxy Traps#
The get() trap일반적으로 get()
메서드에 커스텀한 로직을 작성하여 property
에 접근할 때 get() trap
을 발생시킬 수 있다.
#
The set() trapset() trap
은 target
의 property
가 set될때 발생한다.
#
The apply() trapapply() trap
은 함수가 호출될때 발생한다.
#
proxy trap의 작동 시점내부 메서드 | 핸들러 메서드 | 작동 시점 |
---|---|---|
[[Get]] | get | 프로퍼티를 읽을 때 |
[[Set]] | set | 프로퍼티에 쓸 때 |
[[HasProperty]] | has | in 연산자가 동작할 때 |
[[Delete]] | deleteProperty | delete 연산자가 동작할 때 |
[[Call]] | apply | 함수를 호출할 때 |
[[Construct]] | construct | new 연산자가 동작할 때 |
[[GetPrototypeOf]] | getPrototypeOf | Object.getPrototypeOf |
[[SetPrototypeOf]] | setPrototypeOf | Object.setPrototypeOf |
[[IsExtensible]] | isExtensible | Object.isExtensible |
[[PreventExtensions]] | preventExtensions | Object.preventExtensions |
[[DefineOwnProperty]] | defineProperty | Object.defineProperty, Object.defineProperties |
[[GetOwnProperty]] | getOwnPropertyDescriptor | Object.getOwnPropertyDescriptor, for..in, Object.keys/values/entries |
[[OwnPropertyKeys]] | ownKeys | Object.getOwnPropertyNames, Object.getOwnPropertySymbols, for..in, Object/keys/values/entries |
#
참고자료#
후기js proxy
는 다양한 라이브러리와 프레임워크에서 사용되고 있다고 한다.
잘 활용해서 JS 환경에서 좀 더 클린하고 효율적인 코드를 작성할 수 있지 않을까 기대를 해본다.
#
2021-12-21#
List- Module Bundler
- Webpack
- Rollup
#
Module BundlerModule Bundler
는 프론트엔드 개발자들이 주로 사용하며 JavaScript 모듈을 브라우저에서 실행할 수 있는 단일 JavaScript 파일로 묶는 데 사용되는 도구이다.
최신 모듈 번들러 예시
- webpack
- rollup
- fusebox
- parcel
다음과 같은 이유로 Module Bundler
를 필요로 할 수 있다.
- 브라우저는 모듈 시스템을 지원하지 않지만 오늘날에는 완전히 사실이 아닙니다.
- 코드의 종속성 관계를 관리하는 데 도움이 되며 종속성 순서로 모듈을 로드합니다.
- 종속성 순서, 이미지 자산, CSS 자산 등으로 자산을 로드하는 데 도움이 됩니다.
#
Module?Module
이란 프로그래밍 관점에서 특정 기능을 갖는 작은 코드 단위를 의미합니다.
JavaScript의 Simple Example
이 math.js 파일은 아래와 같이 3가지 기능을 갖고 있는 Module
이다.
- 두 숫자의 합을 구하는 sum() 함수
- 두 숫자의 차를 구하는 substract() 함수
- 원주율 값을 갖는 pi 상수
이처럼 성격이 비슷한 기능들을 하나의 의미 있는 파일로 관리하면 Module
로 취급된다.
#
Why Need Bundler설명을 위해 여러 JavaScript 파일로 구성된 웹 응용 프로그램을 구축하는 상황을 가정해보자
아래는 필요한 JavaScript 파일을 html에 추가하는 예시
각 파일에는 5개의 왕복 요청인 별도의 http 요청이 필요하다.
따라서 5개의 파일을 모두 하나로 결합할 수 있다면 더 효율적이다.
#
Bundle Problem- 포함될 "파일" 의 순서를 어떻게 유지?
- "파일" 사이에 일종의 종속성 순서가 있으면 좋음
- "파일" 간의 이름 충돌을 방지하려면?
- 번들 내에서 사용되지 않은 "파일"을 어떻게 확인?
다음과 같이 각 파일 간의 관계를 알면 이 모든 것을 해결할 수 있습니다.
- 어떤 파일이 다른 파일에 종속되어 있는지?
- 파일에서 노출되는 인터페이스는 무엇?
- 어떤 노출된 인터페이스가 다른 사람에 의해 사용되고 있습니까?
부여된 이러한 정보는 각각 제기된 문제를 해결할 수 있다.
따라서 우리에게 필요한 것은 파일 간의 관계를 설명하는 선언적 방법이며, 이는 우리를 JavaScript 모듈 시스템으로 이끈다.
#
CommonJS & ES6 ModuleCommonJS 또는 ES6 모듈은 우리가 의존하고 있는 파일과 파일에서 사용 중인 인터페이스를 지정할 수 있는 방법을 제공한다.
#
How Bundle?모듈 시스템에서 수집한 정보로 어떻게 파일을 함께 연결하고 모든 것을 캡슐화하는 번들 파일을 생성할까?
대표적인 2개의 Module Bundler를 사용
- webpack
- rollup
우리는 3개의 파일을 가지고 있다고 가정해보자
- circle.js
- square.js
- app.js
#
"웹팩 방식""webpack 방식" 번들은 어떻게 생겼을까?
첫째, 가장 먼저 눈에 띄는 것은
Module Map
이다. 모듈 이름을 함수로 래핑된 모듈 자체에 매핑하는 사전입니다.Module Map
은 항목을 추가하여 모듈을 쉽게 등록할 수 있다.둘째, 각 모듈은 함수로 Wrapping 된다. 이 함수는 모듈 내에서 선언된 모든 것이 자체 내에서 범위가 지정되는 모듈 범위를 시뮬레이션합니다. 함수 자체를
Module Factory Function
라고 합니다. 모듈이 인터페이스를 내보내고 다른 모듈에서 요구할 수 있도록 몇 가지 매개 변수를 사용한다.셋째, 어플리케이션이 시작되고
webpackStart
는 모든 것을 함께 붙여주는 함수이다. 종종런타임
이라고 하는 함수 자체는 번들에서 가장 중요한 부분이다.모듈 맵
과입력 모듈
을 사용하여 애플리케이션을 시작한다.
webpackStart
require function
과 module cache
의 2가지를 정의한다.
require
기능은 CommonJS의 기능과 다르다.
require
구문은 exported interface
를 module로 부터 반환한다.
예시: circle.js 라면 -> { default: function area(radius){ ... } }
반환
내보낸 인터페이스는 모듈 캐시에 캐시되므로 동일한 모듈 이름의 require
를 반복적으로 호출하면 모듈 팩토리 함수
가 한 번만 실행됩니다.
require
가 정의된 상태에서 애플리케이션을 시작하는 것은 입력 모듈을 "요구"하는 것뿐입니다.
#
"롤업 방식"이제 "롤업 방식" 번들을 살펴보자.
- 첫째, 롤업 번들의 주요 차이점은 웹팩 번들에 비해 훨씬 작다. "webpack 방식"에 비해 모듈 맵 이 없으며, 모든 모듈은 번들로 "평평하게" 정의된다. 모듈의 래핑
function
이 없다. 모듈 내에서 선언된 모든 변수/함수는 이제 전역 범위로 선언된다.
혹시 개별 모듈 범위에서 선언된 모든 것이 전역 범위로 선언된 경우 2개의 모듈이 동일한 이름의 변수/함수를 선언한다면?
- 롤업은 이름 충돌이 발생하지 않도록 변수/함수 이름을 변경한다.
- 예시에서
circle.js and square.js
는 모두function area(){}
모듈 내에서 선언 되었으며 번들될 때 충돌을 피하기 위해 두 함수와 그 사용법이 모두 이름이 변경된 것을 볼 수 있다.
모듈을 함수로 래핑하지 않는 부작용 중 하나의 동작이다
eval
. 자세한 설명 은 문서를 참조
- 둘째, 번들 내 모듈의 순서가 문제가 있을 수 있다.
circle$area
->square$area
->console.log
순서대로 작동하지만 temporal dead zone 때문에 PI전에 선언해야한다.
따라서 종속성 순서대로 모듈을 정렬하는 것은 "롤업 방식"에 중요하다.
대체로 "롤업 방식"이 "웹팩 방식"보다 나은 것 같아보인다. 모든 기능을 제거하여 더 작은 번들과 더 적은 런타임 오버헤드를 갖는 특징이 있다.
#
요약- 모듈 번들러 는 여러 JavaScript 모듈을 하나의 JavaScript 파일로 결합하는 데 큰 도움이 된다.
- "웹팩 방식"
- 모듈 맵 사용
- 함수를 사용하여 각 모듈을 래핑
- 모듈을 함께 연결하는 런타임 코드가 있음
- "롤업 방식"
- 더 평평하고 작은 묶음
- 모듈을 래핑하기 위해 함수를 사용하지 않음
- 순서 문제, 종속성을 기반으로 한 정렬 필요
- 순환 종속성이 작동하지 않을 수 있음
#
참고자료#
2021-12-28#
List- Micro Service
- Micro Service 6
- 마이크로 서비스 찬반
#
Micro Service마이크로서비스 아키텍처라고도 하는 마이크로서비스는 애플리케이션을 다음과 같은 서비스 모음으로 구성하는 아키텍처 스타일이라고 할 수 있다.
그림예시)
- 높은 유지보수 및 테스트 가능
- 느슨한 결합
- 독립적으로 배포 가능
- 비즈니스 역량을 중심으로 구성
- 소규모 팀 소유
마이크로서비스 아키텍처를 사용하면 크고 복잡한 애플리케이션을 빠르고 자주 안정적으로 전달할 수 있으며, 또한 조직이 기술 스택을 발전시킬 수 있다.
상황예시)
- 서버측 엔터프라이즈 애플리케이션을 개발 중입니다.
- 데스크톱 브라우저, 모바일 브라우저 및 기본 모바일 애플리케이션을 비롯한 다양한 클라이언트를 지원해야 합니다.
- 애플리케이션은 제3자가 사용할 API를 노출할 수도 있습니다.
- 웹 서비스나 메시지 브로커를 통해 다른 애플리케이션과 통합할 수도 있습니다.
- 애플리케이션은 비즈니스 로직을 실행하여 요청(HTTP 요청 및 메시지)을 처리합니다.
- 데이터베이스 액세스; 다른 시스템과 메시지 교환 HTML/JSON/XML 응답을 반환합니다.
- 응용 프로그램의 다양한 기능 영역에 해당하는 논리적 구성 요소가 있습니다.
#
문제애플리케이션의 배포 아키텍처
#
상황- 응용 프로그램에서 작업하는 개발자 팀이 있다
- 새로운 팀원은 신속하게 생산성을 발휘해야 한다.
- 응용 프로그램을 이해하고 수정하기 쉬워야 한다.
- 애플리케이션의 지속적인 배포를 연습하고 싶은 경우
- 확장성 및 가용성 요구 사항을 충족하려면 여러 컴퓨터에서 애플리케이션의 여러 인스턴스를 실행해야 한다.
- 새로운 기술(프레임워크, 프로그래밍 언어 등)을 활용하려는 경우
#
해결책느슨하게 결합된 협업 서비스 세트로 애플리케이션을 구성하는 아키텍처를 정의한다.
- 유지 관리 및 테스트 용이성 - 빠르고 빈번한 개발 및 배포 가능
- 다른 서비스와 느슨하게 결합 - 팀이 다른 서비스의 변경 사항에 영향을 받지 않고 다른 서비스에 영향을 주지 않고 대부분의 시간 동안 독립적으로 서비스 작업을 수행할 수 있습니다.
- 독립적으로 배포 가능 - 팀이 다른 팀과 협력하지 않고도 서비스를 배포할 수 있습니다.
- 소규모 팀으로 개발 가능 - 큰 팀의 높은 커뮤니케이션 헤드를 피하여 높은 생산성에 필수적
서비스는 HTTP/REST와 같은 동기 프로토콜 또는 AMQP와 같은 비동기 프로토콜을 사용하여 통신합니다.
서비스는 서로 독립적으로 개발 및 배포할 수 있습니다.
각 서비스에는 다른 서비스와 분리하기 위해 자체 데이터베이스 가 있습니다.
#
결과 컨텍스트이 솔루션에는 다음과 같은 많은 이점이 있다.
- 크고 복잡한 애플리케이션을 지속적으로 제공하고 배포할 수 있음
- 개선된 유지보수성 - 각 서비스가 상대적으로 작기 때문에 이해하고 변경하기 쉬움
- 더 나은 테스트 가능성 - 서비스는 더 작고 테스트하기 더 빠름
- 더 나은 배포 가능성 - 서비스를 독립적으로 배포할 수 있음
- 이를 통해 여러 자율적인 팀을 중심으로 개발 노력을 구성할 수 있다. 각(소위 두 개의 피자) 팀은 하나 이상의 서비스를 소유하고 책임이 있습니다. 각 팀은 다른 모든 팀과 독립적으로 서비스를 개발, 테스트, 배포 및 확장할 수 있습니다.
- 각 마이크로 서비스는 상대적으로 작습니다.
- 개발자가 이해하기 쉽게
- IDE는 개발자의 생산성을 더 빠르게 만듭니다.
- 애플리케이션이 더 빨리 시작되어 개발자의 생산성이 향상되고 배포 속도가 빨라집니다.
- 향상된 결함 격리. 예를 들어, 한 서비스에 메모리 누수가 있는 경우 해당 서비스만 영향을 받습니다. 다른 서비스는 계속해서 요청을 처리합니다. 이에 비해 모놀리식 아키텍처의 오작동 구성 요소 중 하나는 전체 시스템을 다운시킬 수 있습니다.
- 기술 스택에 대한 장기적인 약속을 제거합니다. 새로운 서비스를 개발할 때 새로운 기술 스택을 선택할 수 있습니다.
- 마찬가지로 기존 서비스를 크게 변경할 때 새로운 기술 스택을 사용하여 다시 작성할 수 있습니다.
#
단점이 솔루션에는 여러 가지 단점이 있다.
- 개발자는 분산 시스템 생성의 추가적인 복잡성을 처리해야 합니다.
- 개발자는 서비스 간 통신 메커니즘을 구현하고 부분적 오류를 처리해야 합니다.
- 여러 서비스에 걸친 요청을 구현하는 것이 더 어렵습니다.
- 서비스 간의 상호 작용을 테스트하는 것이 더 어렵습니다.
- 여러 서비스에 걸친 요청을 구현하려면 팀 간의 세심한 조정이 필요합니다.
- 개발자 도구/IDE는 모놀리식 애플리케이션 구축을 지향하며 분산 애플리케이션 개발에 대한 명시적인 지원을 제공하지 않습니다.
- 배포 복잡성. 프로덕션 환경에는 다양한 서비스로 구성된 시스템을 배포하고 관리하는 작업의 복잡성도 있습니다.
- 메모리 소비 증가.
마이크로서비스 아키텍처는 N개의 모놀리식 애플리케이션 인스턴스를 NxM 서비스 인스턴스로 대체한다. 각 서비스가 일반적으로 인스턴스를 격리하는 데 필요한 자체 JVM(또는 이와 동등한 것)에서 실행되는 경우 JVM 런타임의 M배에 달하는 오버헤드가 있습니다. 또한 Netflix의 경우와 같이 각 서비스가 자체 VM(예: EC2 인스턴스)에서 실행되는 경우 오버헤드가 훨씬 더 높다.
#
Micro Service 6#
1. 다중 구성 요소- 마이크로서비스로 구축된 소프트웨어는 정의에 따라 여러 구성 요소 서비스로 나눌 수 있다.
- 따라서 이러한 각 서비스는 애플리케이션의 무결성을 손상시키지 않고 독립적으로 배포, 조정 및 재배포될 수 있다.
(결과적으로 전체 응용 프로그램을 다시 배포하는 대신 하나 이상의 고유한 서비스만 변경하면 된다.) - 그러나 이 접근 방식에는 비용이 많이 드는 원격 호출(in-process 호출 대신), 더 세분화된 원격 API, 구성 요소 간 책임 재분배 시 복잡성 증가 등의 단점이 있다.
#
2. 비즈니스용으로 구축- 마이크로서비스 스타일은 일반적으로 비즈니스 기능과 우선 순위를 중심으로 구성된다.
- 각기 다른 팀이 UI, 데이터베이스, 기술 계층 또는 서버 측 논리에 대해 특정 초점을 맞추는 기존의 모놀리식 개발 접근 방식과 달리 마이크로서비스 아키텍처는 기능 간 팀을 활용한다.
- 각 팀의 책임은 메시지 버스를 통해 통신하는 하나 이상의 개별 서비스를 기반으로 특정 제품을 만드는 것이다.
#
3. 단순 라우팅- 마이크로서비스는 고전적인 UNIX 시스템과 다소 유사하게 작동한다.
- 요청을 수신하고 처리하고 그에 따라 응답을 생성한다.
- 메시지 라우팅, 구성 및 비즈니스 규칙 적용을 위한 첨단 시스템이 활용되는 ESB(Enterprise Service Buses)와 같은 다른 제품의 수와 반대이다.
- 마이크로 서비스에는 정보를 처리하고 논리를 적용하는 스마트 엔드포인트와 정보가 흐르는 덤 파이프가 있다고 말할 수 있다.
#
4. 탈중앙화- 마이크로서비스는 다양한 기술과 플랫폼을 포함하기 때문에 중앙 집중식 거버넌스의 구식 방법은 최적이 아니다.
- 마이크로서비스 커뮤니티는 분산 거버넌스를 선호한다.
(그 이유는 개발자가 유용한 도구를 생성하여 다른 사람들이 동일한 문제를 해결하는 데 사용할 수 있기 때문이다.) - 분산된 거버넌스와 마찬가지로 마이크로서비스 아키텍처도 분산된 데이터 관리를 선호합니다.
(모놀리식 시스템은 여러 애플리케이션에서 단일 논리 데이터베이스를 사용한다.) - 마이크로 서비스 애플리케이션에서 각 서비스는 일반적으로 고유한 데이터베이스를 관리한다.
#
5. 고장 방지- 다재다능한 아이처럼 마이크로서비스는 실패에 대처하도록 설계되었다.
- 여러 고유하고 다양한 서비스가 함께 통신하고 있기 때문에 서비스가 실패할 가능성이 있다.
(예: 공급자를 사용할 수 없는 경우). - 클라이언트는 가능한 인접 서비스가 작동하도록 허용해야 한다.
- 마이크로 서비스를 모니터링 하면 실패 위험을 방지하는 데 도움이 될 수 있다.
- 이런 요구 사항은 모놀리식 시스템 아키텍처에 비해 마이크로서비스에 더 많은 복잡성을 추가한다.
#
6. 진화- 마이크로서비스 아키텍처는 혁신적인 설계이며, 언젠가는 애플리케이션에 액세스할 수 있는 장치 유형을 완전히 예측할 수 없는 진화적인 시스템에 이상적이다.
- 많은 애플리케이션은 모놀리식 아키텍처를 기반으로 시작하지만 몇 가지 예상치 못한 요구 사항이 표면화됨에 따라, API를 통해 이전 모놀리식 아키텍처와 상호 작용하는 마이크로 서비스로 천천히 개선될 수 있다.
#
마이크로 서비스의 찬반마이크로서비스는 만병통치약이 아니며, 이를 구현하면 이전에는 암묵적으로 드러났지만 이제는 공개되지 않은 커뮤니케이션, 팀워크 및 기타 문제를 노출할 수 있다.
그러나 마이크로서비스의 API 게이트웨이는 빌드 및 QA 시간과 노력을 크게 줄일 수 있습니다.
- 한 가지 일반적인 문제는 서비스 간에 스키마/검증 논리를 공유하는 것과 관련된다.
- B가 다른 요구 사항을 가지고 있는 경우 일부 데이터가 유효한 것으로 간주하기 위해 A가 요구하는 것이 항상 B에 적용되는 것은 아니다.
- 가장 좋은 권장 사항은 버전 관리를 적용하고 공유 라이브러리에 스키마를 배포하는 것이다.
- 라이브러리에 대한 변경 사항은 팀 간의 토론이 될 수 있으며, 또한 강력한 버전 관리에는 종속성이 발생하여 더 많은 오버헤드가 발생할 수 있습니다.
- 이를 극복하기 위한 가장 좋은 방법은 이전 버전과의 호환성을 계획하고 외부 서비스/팀의 회귀 테스트 를 수락하는 것일 수 있다.
- 이는 다른 사람의 비즈니스 프로세스를 방해한 후에가 아니라 방해 하기 전에 대화를 나누도록 해야한다.
다른 모든 것과 마찬가지로 마이크로 서비스 아키텍처가 각 서비스에 적합한지 여부는 모두 장단점이 있기 때문에 요구 사항에 따라 다를 수 있다.
#
정리#
장점- 마이크로서비스 아키텍처는 개발자가 서비스를 독립적으로 개발하고 배포할 수 있는 자유를 제공한다.
- 마이크로 서비스는 상당히 작은 팀에서 개발할 수 있다.
- 다른 서비스에 대한 코드는 다른 언어로 작성할 수 있다.(많은 실무자가 권장하지 않음).
- 손쉬운 통합 및 자동 배포(Jenkins, Hudson 등과 같은 오픈 소스 지속적 통합 도구 사용)
- 개발자가 쉽게 이해하고 수정할 수 있으므로 새로운 팀원이 신속하게 생산성을 높일 수 있다.
- 개발자는 최신 기술을 사용할 수 있다.
- 코드는 비즈니스 기능을 중심으로 구성된다.
- 웹 컨테이너를 더 빨리 시작하므로 배포도 더 빨라진다.
- 애플리케이션의 특정 부분에 변경이 필요한 경우 관련 서비스만 수정하여 재배포할 수 있으며 전체 애플리케이션을 수정하고 재배포할 필요가 없다.
- 더 나은 오류 격리: 하나의 마이크로 서비스가 실패해도 다른 하나는 계속 작동한다.
(모놀리식 애플리케이션의 문제가 있는 영역 중 하나가 전체 시스템을 위험에 빠뜨릴 수 있음) - 쉽게 확장하고 타사 서비스와 통합
- 기술 스택에 대한 장기 약정 없음
#
단점- 분산 배포로 인해 테스트가 복잡하고 지루할 수 있다.
- 서비스 수가 증가하면 정보 장벽이 생길 수 있다.
- 이 아키텍처는 개발자가 내결함성, 네트워크 지연을 완화하고 다양한 메시지 형식과 로드 밸런싱을 처리해야 하므로 복잡성이 추가로 발생한다.
- 분산 시스템이므로 노력이 중복될 수 있습니다.
- 서비스의 수가 증가하면 전체 제품의 통합 및 관리가 복잡해질 수 있음
- 모놀리식 아키텍처의 여러 복잡성 외에도 개발자는 분산 시스템의 추가적인 복잡성을 처리해야 한다.
- 개발자는 서비스 간의 통신 메커니즘을 구현하는 데 추가 노력을 기울여야 한다.
- 분산 트랜잭션을 사용하지 않고 둘 이상의 서비스에 걸쳐 있는 사용 사례를 처리하는 것은 어려울 뿐만 아니라 다른 팀 간의 커뮤니케이션과 협력을 요구한다.
#
후기현재 아이랩팀은 모놀리식 어플리케이션의 형태로 구성이 되어있다.
서비스 증가 및 각 업무 도메인을 분산시키기 위해 마이크로 서비스가 필요해질 수 있다.
미리 많은 사례들과 마이크로 서비스의 기본 설계, 구조, 구축방향 등을 팀내에서 지속적으로 생각해놓고 정리해놓는것 또한 필요한 일이 아닐까 생각이 든다.