JSX 소개
JSX는 JavaScript를 위한 구문 확장자로, HTML과 유사한 코드를 작성할 수 있게 해주는 도구이다.
이는 컴파일 과정을 거쳐 일반 JavaScript 코드로 변환된다.
JSX의 가장 큰 장점 중 하나는 코드를 모듈화할 수 있다는 점인데, 이는 React의 핵심 가치인 컴포넌트 기반 아키텍처를 구현하는 데 도움이 된다.
JSX 컴파일 과정
JSX 코드가 실행 가능한 JavaScript로 변환되기 위해서는 다음과 같은 세 가지 주요 단계를 거친다:
토큰화
- 문자열을 토큰으로 분해하는 과정
- 토크나이저는 어떤구문에서 의미있는 요소들을 토큰으로 쪼개는 역할
- 렉서(Lexer)는 상태를 가진 토크나이저를 의미 (토큰의 의미 분석 역할)
- 렉싱(Lexing)은 상태를 가지는 토큰화 과정
- 렉서는 규칙에 따라 프로그래밍 언어의 텍스트에서 주요 토큰을 식별
- 식별된 키워드들은 열거 가능한 값으로 변환
구문 분석
- 토큰을 가져와 구문 트리로 변환하는 과정
- 코드의 구조적 의미를 파악하고 계층 관계를 구성
코드 생성
- 컴파일러가 추상 구문 트리에서 기계어를 생성하는 과정
- 결과로 생성된 기계어는 자바스크립트 엔진에 의해 실행
웹 브라우저를 비롯한 최신 환경에서는 자바스크립트 코드를 효율적으로 실행하기 위해 JIT 컴파일러를 많이 사용한다. → 실시간 정보를 기반으로 최적화를 수행
JSX 작동 원리
JSX는 JavaScript 구문을 확장한 형태이기 때문에, 브라우저에서 직접 실행될 수 없다.
이를 실행 가능한 코드로 만들기 위해서는 다음과 같은 과정이 필요하다:
- 변환 과정: JSX 코드는 빌드 단계에서 바벨(Babel)과 같은 도구를 통해 일반 JavaScript로 변환된다.
- Babel : 구문 트리를 사용해 자바스크립트 엔진이 이해할 수 있는 일반적인 바닐라 JS를 생성
- 프라그마 처리: JSX는 '<' 문자로 시작하는 특별한 구문을 사용하는데, 이는 일반적인 JavaScript에서는 인식되지 않는다.
- '<'를 발견하게 되면
syntax error: unexpected token
오류발생
- tag, props, children을 인자로 받아 다음과 같이 변환
<Component prop="속성 값">콘텐츠</Component>
React.createElement(Component, {prop:'속성 값'}, '콘텐츠')
JIT 컴파일러 (just-in-time compilation)
= dynamic translation, 동적 번역
- 프로그램을 실제 실행하는 시점에 기계어로 번역하는 컴파일 기법
- 두 가지 주요 컴파일러 구성:
- C1 컴파일러: 빠른 컴파일 속도 중심
- C2 컴파일러: 최적화 중심
- 코드 캐싱을 통한 성능 최적화
컴퓨터 프로그램을 만드는 방법에는 인터프리터 방식과 정적 컴파일 방식이 있다:
-
인터프리터 방식
- 프로그램 실행마다 한 줄씩 매번 해당 코드의 기계어 코드를 생성하면서 실행
- 복잡한 연산이나 반복 작업에서 성능 저하
- 한 문장씩 변환하기 때문에 오류나면 바로 프로그램 중지
- 실행 파일이 따로 생성되는 것이 아니라서 소스 코드가 쉽게 공개됨
-
정적 컴파일
- 실행하기 전에 프로그램 코드를 한꺼번에 기계어 코드로 변환
- 전체 변환으로 인해 초기 실행 시간은 오래 걸리지만, 전체적인 실행 시간은 더 빠를 수 있음
- 초기 실행 파일을 만들어두면, 다음 실행 시엔 실행 파일만 실행시키면 되기 때문
- 런타임 최적화 기회 X
- 기계어로 변환하는 과정에서 파일을 만들어야 하는데 이 파일이 메모리가 꽤 필요함
- 프로그램 실행 전에 오류을 발견할 수 있어서 프로그램 안정성 향상
JIT 컴파일러는 실시간으로 기계어 코드를 생성하면서 그 코드를 캐싱한다.
→ 인터프리터 방식과 정적 컴파일 방식의 장점을 합쳐둔 듯 하다.(근데 이제 정적 컴파일이 베이스고 인터프리터 방식을 곁들인)
- 실행 시점에서 인터프리터와 같이 기계어 코드를 생성하면서 컴파일하고 코드를 캐싱한다.
- 소스 코드를 바꾸지 않는 한, 이미 컴파일된 기계어를 재사용하여 매번 해석하는 오버헤드가 감소해서 실행 시간이 빨라진다.
- 자주 실행되는 코드 영역을 최적화하는 적응형 최적화 수행한다.
→ 전체적으로 좋은 성능을 낸다.
- 컴파일러: 고급 프로그래밍 언어로 작성된 소스 코드를 구문 트리로 변환하는 소프트웨어
- 구문 트리(AST, 추상 구문 트리): 코드의 구조를 나타내는 트리 형태의 자료 구조
- JIT 컴파일러: 실행 시점에 코드를 기계어로 변환하는 컴파일러
- 런타임: 프로그램이 실행되는 동안의 환경
- 번들: 여러 파일을 하나로 결합하는 작업
- 트랜스파일한다: 코드를 변환한 후 컴파일한다
- jsx 프라그마: 컴파일러에 특정 작업을 수행하도록 지시하는 지시어