자바스크립트 엔진과 런타임의 차이점은 무엇인가요?
원문: https://humanwhocodes.com/blog/2024/03/javascript-engines-runtimes/
런타임과 엔진은 종종 혼동되어 쓰이는 경우가 많습니다.
여러분은 아마 "자바스크립트 엔진"과 "자바스크립트 런타임"이라는 용어를 "자바스크립트를 실행하는 프로그램"이라는 의미로 혼용하는 것을 들어보셨을 것입니다. 이들은 종종 V8, Node.js, 혹은 관련 프로그램의 다른 조합들과 언급되어 혼용됩니다. 하지만, 자바스크립트 엔진과 자바스크립트 런타임은 범위와 기능에 상당한 차이가 있습니다. 자바스크립트를 전체적으로 잘 이해하려면 이 차이를 확실하게 아는 것이 중요합니다.
엔진과 런타임에 대해 논의하기 전에, 이들과 관련해 자주 사용되는 몇 가지 용어를 정의하는 것이 도움이 될 것입니다. 바로 ECMAScript와 JavaScript입니다.
ECMAScript란 무엇인가요?
1996년, Netscape와 Sun Microsystems는 비영리 표준화 기구인 Ecma International에 자바스크립트를 표준화하는 문제를 제기했습니다. 그 노력의 결과로 1997년에 ECMA-262 명세가 발표되었고, 이는 자바스크립트 구현이 어떻게 작동해야 하는지를 정의하는 명세입니다. Sun이 자바스크립트 상표를 기부하기를 꺼려했기 때문에 (1), 명세는 다른 이름을 가져야 했고, 그래서 ECMA-262는 "ECMAScript 언어 명세서"라는 제목을 갖게 되었습니다. 따라서 ECMAScript는 ECMA-262에 명시된 언어의 이름입니다.
ECMAScript는 구현이 어디에 내장되어 있든 반드시 준수해야 하는 자바스크립트의 핵심 기능을 정의합니다(구현을 내장한 프로그램을 호스트라고 합니다). 초기 단계에서도 Netscape는 브라우저뿐만 아니라 서버에서도 자바스크립트를 사용하고자 했으며, ECMAScript는 두 구현의 핵심 역할을 했습니다. 따라서 ECMAScript에는 웹 관련 기능도 포함되지 않고, 데이터를 입/출력하는 방법도 포함되지 않습니다(이러한 기능은 호스트에서 제공해야 합니다). 즉, ECMAScript에가 Object
, Array
, Promise
와 같은 표준 전역 클래스는 포함하지만 HTMLElement
, setTimeout
, fetch()
는 포함하지 않는다는 것을 의미합니다.
자바스크립트란 무엇인가요?
"자바스크립트"라는 용어는 공식적인 정의는 없지만 ECMAScript 언어의 상위 집합으로 널리 이해되고 있습니다. 즉, 자바스크립트는 ECMAScript 외에도 다른 명세 및 기타 기능을 구현합니다. 초기 형태에서 자바스크립트는 ECMAScript에 DOM(문서 객체 모델)과 같은 웹 기반 API와 히스토리 API와 같은 브라우저 기반 API를 더한 것으로 간주되었습니다. 오늘날 자바스크립트는 ECMAScript와 기타 호스트 제공 API의 모든 조합으로 간주됩니다. 여기에는 브라우저를 위한 웹 전용 API와 Node.js와 같은 호스트를 위한 서버 전용 API가 포함됩니다.
자바스크립트 엔진이란 무엇인가요?
일반적으로 자바스크립트 엔진이라고 불리는 것들은 더 정확하게는 ECMAScript 엔진이라고 할 수 있습니다. 왜냐하면 이들은 추가 기능 없이(또는 거의 없이) ECMA-262를 구현하기 때문입니다. 자바스크립트 엔진은 호스트에 내장되도록 설계되었으며, 호스트는 입력과 출력을 위한 추가 기능을 정의합니다. 가장 잘 알려진 자바스크립트 엔진들은 다음과 같습니다.
V8 (2) - Chromium 프로젝트용 자바스크립트 엔진으로 만들어졌으며 현재 Node.js와 Deno에서도 사용됩니다. Edge와 Opera는 Chromium을 기반으로 하기 때문에 V8은 가장 자주 사용되는 자바스크립트 엔진입니다.
SpiderMonkey (3) - Firefox의 자바스크립트 엔진입니다.
JavaScriptCore (4) - MacOS와 iOS의 Safari를 위해 만들어진 자바스크립트 엔진이며, Bun에서도 사용됩니다.
자바스크립트 엔진은 ECMAScript만 구현하고 호스트에 의해 확장되도록 되어 있기 때문에 다양한 런타임 환경에서 사용할 수 있습니다.
자바스크립트 런타임이란 무엇인가요?
자바스크립트 런타임은 ECMAScript 호스트입니다. 즉, 자바스크립트 엔진을 내장하고 자바스크립트를 통해 접근할 수 있는 추가 기능을 정의하는 프로그램입니다. Chrome, Firefox, Edge, Safari, Node.js, Deno, Bun은 모두 자바스크립트 엔진을 내장하고 자바스크립트를 통해 접근할 수 있는 추가 기능을 정의하기 때문에 자바스크립트 런타임입니다. 웹 브라우저는 DOM 및 기타 웹 API를 구현하는 반면 서버 측 런타임은 파일 시스템 접근을 구현합니다.
자바스크립트 런타임에 추가할 수 있는 기능에 대한 규칙은 없으며, 런타임 개발자가 직접 결정할 수 있습니다. 이것이 바로 Node.js, Deno, Bun이 모두 다른 방식으로 파일 시스템을 구현하는 이유이며, Deno가 fetch()
와 같은 웹 API를 선호하는 반면 Node.js는 처음에 자체 HTTP 클라이언트를 구현하기로 한 이유입니다(이후 Node.js도 fetch()
를 채택했습니다). 하지만 자바스크립트 런타임을 독특하게 만드는 것은 자바스크립트 API뿐만이 아닙니다. 자바스크립트 엔진을 사용하는 방식도 중요합니다.
예를 들어 런타임이 자바스크립트 실행과 다른 작업 수행 사이를 전환할 수 있게 하는 프로세스인 이벤트 루프는 ECMA-262에 정의되어 있지 않으므로 어떤 자바스크립트 엔진에서도 구현되어 있지 않습니다. 각 자바스크립트 런타임이 자체 이벤트 루프를 구현해야 합니다. 웹 브라우저는 HTML 명세 (5) 에 정의된 이벤트 루프 버전이 있지만, Node.js와 같은 서버 측 런타임은 자체적으로 (6) 정의합니다. 이벤트 루프는 자바스크립트 런타임에는 필수적인 것은 아니지만 범용 자바스크립트 런타임에서 찾아볼 수 있습니다.
요약
자바스크립트 엔진과 자바스크립트 런타임은 서로 관련이 있지만 동일하지는 않습니다. 자바스크립트 엔진은 ECMA-262 표준에 정의된 대로 ECMAScript를 구현합니다. ECMA-262는 입력 또는 출력에 대한 어떤 방법도 없이 자바스크립트의 핵심 기능을 정의합니다. 자바스크립트 런타임은 자바스크립트 엔진을 내장하고 입력 및 출력을 위한 추가 기능과 함께 런타임에 필요한 다른 모든 기능을 보강하는 ECMAScript 호스트입니다. 추가 기능에는 웹 브라우저의 DOM 또는 서버 측 런타임의 파일 시스템 접근이 포함될 수 있습니다. 런타임은 ECMA-262 이외의 다른 표준을 따를 의무가 없으며 필요에 따라 자체 API를 정의할 수 있기 때문에 Node.js, Deno, Bun은 모두 서로 다른 파일 시스템 API를 가지고 있습니다.