JSX

가은·2025년 2월 9일
0

JSX 소개

JSX는 JavaScript를 위한 구문 확장자로, HTML과 유사한 코드를 작성할 수 있게 해주는 도구이다.
이는 컴파일 과정을 거쳐 일반 JavaScript 코드로 변환된다.

JSX의 가장 큰 장점 중 하나는 코드를 모듈화할 수 있다는 점인데, 이는 React의 핵심 가치인 컴포넌트 기반 아키텍처를 구현하는 데 도움이 된다.

JSX 컴파일 과정

JSX 코드가 실행 가능한 JavaScript로 변환되기 위해서는 다음과 같은 세 가지 주요 단계를 거친다:

토큰화

  • 문자열을 토큰으로 분해하는 과정
  • 토크나이저는 어떤구문에서 의미있는 요소들을 토큰으로 쪼개는 역할
  • 렉서(Lexer)는 상태를 가진 토크나이저를 의미 (토큰의 의미 분석 역할)
    • 렉싱(Lexing)은 상태를 가지는 토큰화 과정
    • 렉서는 규칙에 따라 프로그래밍 언어의 텍스트에서 주요 토큰을 식별
    • 식별된 키워드들은 열거 가능한 값으로 변환

구문 분석

  • 토큰을 가져와 구문 트리로 변환하는 과정
  • 코드의 구조적 의미를 파악하고 계층 관계를 구성

코드 생성

  • 컴파일러가 추상 구문 트리에서 기계어를 생성하는 과정
  • 결과로 생성된 기계어는 자바스크립트 엔진에 의해 실행

웹 브라우저를 비롯한 최신 환경에서는 자바스크립트 코드를 효율적으로 실행하기 위해 JIT 컴파일러를 많이 사용한다. → 실시간 정보를 기반으로 최적화를 수행

JSX 작동 원리

JSX는 JavaScript 구문을 확장한 형태이기 때문에, 브라우저에서 직접 실행될 수 없다.
이를 실행 가능한 코드로 만들기 위해서는 다음과 같은 과정이 필요하다:

  1. 변환 과정: JSX 코드는 빌드 단계에서 바벨(Babel)과 같은 도구를 통해 일반 JavaScript로 변환된다.
    • Babel : 구문 트리를 사용해 자바스크립트 엔진이 이해할 수 있는 일반적인 바닐라 JS를 생성
  2. 프라그마 처리: JSX는 '<' 문자로 시작하는 특별한 구문을 사용하는데, 이는 일반적인 JavaScript에서는 인식되지 않는다.
    • '<'를 발견하게 되면 syntax error: unexpected token 오류발생
    • tag, props, children을 인자로 받아 다음과 같이 변환
// JSX 코드
<Component prop="속성 값">콘텐츠</Component>

// 변환된 JavaScript 코드
React.createElement(Component, {prop:'속성 값'}, '콘텐츠')

JIT 컴파일러 (just-in-time compilation)

= dynamic translation, 동적 번역

  • 프로그램을 실제 실행하는 시점에 기계어로 번역하는 컴파일 기법
  • 두 가지 주요 컴파일러 구성:
    • C1 컴파일러: 빠른 컴파일 속도 중심
    • C2 컴파일러: 최적화 중심
  • 코드 캐싱을 통한 성능 최적화

컴퓨터 프로그램을 만드는 방법에는 인터프리터 방식과 정적 컴파일 방식이 있다:

  • 인터프리터 방식

    • 프로그램 실행마다 한 줄씩 매번 해당 코드의 기계어 코드를 생성하면서 실행
    • 복잡한 연산이나 반복 작업에서 성능 저하
    • 한 문장씩 변환하기 때문에 오류나면 바로 프로그램 중지
    • 실행 파일이 따로 생성되는 것이 아니라서 소스 코드가 쉽게 공개됨
  • 정적 컴파일

    • 실행하기 전에 프로그램 코드를 한꺼번에 기계어 코드로 변환
    • 전체 변환으로 인해 초기 실행 시간은 오래 걸리지만, 전체적인 실행 시간은 더 빠를 수 있음
      • 초기 실행 파일을 만들어두면, 다음 실행 시엔 실행 파일만 실행시키면 되기 때문
    • 런타임 최적화 기회 X
    • 기계어로 변환하는 과정에서 파일을 만들어야 하는데 이 파일이 메모리가 꽤 필요함
    • 프로그램 실행 전에 오류을 발견할 수 있어서 프로그램 안정성 향상

JIT 컴파일러는 실시간으로 기계어 코드를 생성하면서 그 코드를 캐싱한다.
→ 인터프리터 방식과 정적 컴파일 방식의 장점을 합쳐둔 듯 하다.(근데 이제 정적 컴파일이 베이스고 인터프리터 방식을 곁들인)

  • 실행 시점에서 인터프리터와 같이 기계어 코드를 생성하면서 컴파일하고 코드를 캐싱한다.
  • 소스 코드를 바꾸지 않는 한, 이미 컴파일된 기계어를 재사용하여 매번 해석하는 오버헤드가 감소해서 실행 시간이 빨라진다.
  • 자주 실행되는 코드 영역을 최적화하는 적응형 최적화 수행한다.

→ 전체적으로 좋은 성능을 낸다.


  • 컴파일러: 고급 프로그래밍 언어로 작성된 소스 코드를 구문 트리로 변환하는 소프트웨어
  • 구문 트리(AST, 추상 구문 트리): 코드의 구조를 나타내는 트리 형태의 자료 구조
  • JIT 컴파일러: 실행 시점에 코드를 기계어로 변환하는 컴파일러
  • 런타임: 프로그램이 실행되는 동안의 환경
  • 번들: 여러 파일을 하나로 결합하는 작업
  • 트랜스파일한다: 코드를 변환한 후 컴파일한다
  • jsx 프라그마: 컴파일러에 특정 작업을 수행하도록 지시하는 지시어
profile
일이 재밌게 진행 되겠는걸?

0개의 댓글