210509 JavaScript engine과 Web API 그리고 Callback queue


자바스크립트의 비동기 코드가 runtime에 의존적이라고 하는 이유에 대한 의문을 시작으로 이번 포스팅을 시작하려고 한다. 이전에 비동기 함수를 테스팅하는 과정에서 에러가 발생을 했었는데 이때 비동기 코드가 runtime에 의존적인 결과코드이기 때문에 별도의 설정을 해줘야 했고, 이 에러를 겪고 해결해나가기 전에는 그 이유에 대해서 잘 몰랐었기 때문에 혹시 과거의 나와 같이 의문을 갖는 사람들을 위해 포스팅을 해보려고 한다.

이 이유에 대해서 이해하려면 자바스크립트 코드의 실행과정에 대해서 우선적으로 이해를 해야한다.

  • 자바스크립트 코드의 실행과정

자바스크립트에서는 작성된 코드들은 call stack에 쌓인 후에 실행이 된다. 하지만 JS엔진에서는 비동기 작업을 지원하지 않기 때문에 코드들 중에서 비동기 작업을 Web API(browser에 의해 제공)에 위임을 한다.

  • JS runtime engine의 역할

    JS runtime engine은 standard JS 코드를 실행하는 역할을 하는 JS engine(V8 for chrome)로 아래와 같은 프로그래밍 언어로써 독립적으로 요구되는 특징들을 지원한다.

    • variable, functions,
    • scoping, scope chaining, execution context, execution scope
  • Web API의 역할

    • Web API는 Browser로부터 제공되는 wrapper로, 표준 JS 프로그래밍 언어의 일부가 아니며, 아래의 기능들을 지원한다.

    • ajax, events(onkeyPress, onBlur와 같은 이벤트들)

    • console.log, window object, DOM을 읽고 쓰기와 같은 기능

    • 비동기 작업(Asynchronous task)지원

    • 표준 JS 언어는 위와같은 기능들을 지원하지 않기 때문에 브라우저는 JS 엔진을 브라우저의 custom wrapper들로 감싸서 웹에서의 여러 조작들이 지원 가능하도록 한다.
      (위와 같은 이유로 browser가 JS의 runtime으로 불린다)

      cf) Node는 JS에게 위와 같은 기능들을 제공하는 server side에서 동작하는 runtime이다.

Read more

210509 ReferenceError regeneratorRuntime is not defined


NodeJS 프로젝트를 진행하면서 비동기로 작성한 함수를 위한 테스트 코드를 작성하고 실행을 했는데 ReferenceError: regeneratorRuntime is not defined 에러가 발생했다.
이전에 ReactJS 프로젝트를 진행하면서 테스트 코드를 작성했을때도 위와 똑같은 에러가 발생했었는데 이러한 경우에는 아래의 두 방법으로 해결을 할 수 있다.

Solution 1) regenerator-runtime를 설치해서 비동기 함수를 작성한 파일의 최상단에 import 'regenerator-runtime/runtime';를 선언해주면 간단하게 해결할 수 있다.

Solution 2) .babelrc 의 설정을 아래와 같이 업데이트한다.

Using @babel/preset-env without that target set will result in the tests using async failing with ReferenceError: regeneratorRuntime is not defined.

1
2
3
4
5
6
7
8
9
10
11
12
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": "current"
}
}
]
]
}

이 regenerator-runtime이 무엇인가 한 번 구글링을 해보니,
regenerator-runtime은 compiled/transpiled 비동기 함수들을 위한 runtime을 지원해주는 녀석이라고 한다.
Babel과 같은 컴파일러는 자바스크립트 syntax에 대해서 최신 문법을 이전 문법으로 변환을 해주지만, runtime에 의존적인 결과 코드(비동기 코드)들은 regenerator-runtime으로부터 지원을 받는다고 한다.