Deno에 대해 알아보자

Einere·2022년 8월 3일
0
post-thumbnail

원글 링크: https://kjwsx23.tistory.com/533

2020년 5월 13일, Deno 1.0이 릴리즈가 되었습니다.
니콜라스 씨도 유튜브에서 Deno에 대한 언급을 한 적 있는데, 도대체 Deno는 무엇일까요?
부족하지만 한번 정리를 해보았습니다.

Deno는?

A secure runtime for JavaScript and TypeScript.

Deno는 구글의 V8엔진과 Rust, Tokio로 개발된 JavaScript와 TypeScript 런타임입니다.
Node.js를 개발했던 Ryan Dahl이 Node.js를 개발하며 했던 후회들을 개선하기 위해 만들었다고 합니다.
한글 자료는 배영님의 노션을 참고해주세요!

Node.js를 개발하며 했던 10가지 후회들

어마무시한 node_modules

We feel that the landscape of JavaScript and the surrounding software infrastructure has changed enough that it was worthwhile to simplify. We seek a fun and productive scripting environment that can be used for a wide range of tasks.

  1. Promise를 붙이지 않은 것.
  2. 안전성
  3. 빌드 시스템
  4. package.json
  5. node_modules
  6. require() without the extension .js
  7. index.js

분명 발표 주제는 "10 Things I Regret About Node.js"인데, 발표자료에는 7가지만 명시되어 있네요.. (나머지 3개는 뭐지 🤔)

철학

  1. Deno는 현대 개발자들에게 생산성 있고 안전한 스크립트 환경을 제공하는 것을 목표로 하고 있습니다.
  2. Deno는 항상 단일 실행 파일로 배포가 됩니다. URL이 Deno 프로그램에게 주어지면, 약 15MB 내외밖에 안 되는 압축된 실행파일들과 함께 실행이 됩니다. (Deno의 핵심 실행 파일이 약 15MB입니다.) Deno는 명시적으로 런타임과 패키지 매니저의 역할을 겸임하고, URL로 모듈을 로드하기 위해 표준 브라우저 호환 프로토콜을 사용합니다.
  3. 이전에 작성되었던 bash나 python과 같은 utility scripts의 대체제입니다.

이러한 철학들은 Ryan Dahl의 후회들을 보면 나름대로 이해할 수 있습니다.

목표

임의의 네이티브 함수를 V8에 바인딩하지 않기

Deno의 목표는 다음과 같습니다.

  • 오로지 단일 실행파일만 배포한다.
  • 안전한 기본값(Secure Defaults)을 제공한다.
    • 명시적인 허용 없이는 파일 시스템이나 네트워크 등에 접근할 수 없다.
    • deno 명령어의 옵션을 통해 권한을 설정할 수 있다.
  • 브라우저 호환성을 보장한다.
    • 완전히 JS로 작성되고 Deno 글로벌 네임스페이스를 사용하지 않는 Deno 프로그램의 서브셋은 최신 웹 브라우저에서 아무런 변경 없이 실행된다.
  • 유닛 테스트, 코드 포맷팅, 린트와 같이 개발 경험을 향상할 수 있는 빌트인 툴들을 제공한다.
  • 구글의 V8 엔진의 개념을 사용자 영역으로 누출시키지 않는다.
  • HTTP를 효율적으로 제공한다.

특징

Deno 공식 홈페이지의 Schematic diagram

Deno is a simple, modern and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust.

공식 페이지에서 Deno는 간단하고 모던하고 안전한 런타임이라고 소개하고 있으며, Deno의 특징은 다음과 같습니다.

  • 안전이 기본입니다. 즉, file system과 network, environment access 등이 명시적인 허용 없이는 불가능합니다.
    • 브라우저와 같이, 코드는 안전한 샌드박스 내에서 실행됩니다.
  • TypeScript를 지원합니다.
    • Deno팀은 Deno가 넓은 문제 영역에서 실행 가능하게 하기를 원합니다. 프로그램이 커질수록 타입 체킹이 중요하다고 합니다.
    • 또한 Deno의 standard module은 모두 TypeScript로 작성되었습니다.
  • Web Assembly를 지원합니다.
  • 단일 실행 파일(.bundle.js)로 배포됩니다. (webpack이 제공하는 번들링 기능을 내장했습니다.)
  • 의존성 감시자나 코드 포매터, 유닛 테스트와 같은 유용한 툴들을 내장하고 있습니다.
  • Deno와 잘 작동하는 것이 검증이 된 standard module들이 있습니다.
  • Third Party Module을 지원합니다.

Rust API

(생략)

Runtime

Deno Runtime은 Web API와 Deno 글로벌 네임스페이스를 합친 개념이며, doc.deno.land에서 관련 레퍼런스를 열람할 수 있습니다.

Architecture

Linux와 Deno를 비교한 표입니다.

 Linux  Deno ProcessWeb WorkerSyscallsopsFile descriptorsResource idsSchedularTokioUserland: libc++ / glib / boostdeno.land/std//proc//statDeno.metrics()man pagesdeno types\begin{array}{|c | c|}\hline \text{ Linux } & \text{ Deno } \\\hline \text{Process} & \text{Web Worker}\\\hline \text{Syscalls} & \text{ops}\\\hline \text{File descriptors} & \text{Resource ids}\\\hline \text{Schedular} & \text{Tokio}\\\hline \text{Userland: libc++ / glib / boost} & \text{deno.land/std/}\\\hline \text{/proc/$$/stat} & \text{Deno.metrics()}\\\hline \text{man pages} & \text{deno types}\\\hline \end{array}

위 표를 보시면 아시겠지만, Deno는 OS와 유사하게 설계되었음을 알 수 있습니다.
웹 워커를 이용해 멀티 프로세스를 구현하며, 내부(커널)과 통신은 ops를 이용해 디커플링했습니다.
더 자세한 내용은 Deno 공식 문서의 Internal Details를 참고해주세요.

안정성

OS와 상호작용하기 위해 개발된 모든 JavaScript API는 Deno 글로벌 네임스페이스에 들어 있습니다. 이 API들은 신중하게 검토되었고, 하위 호환성을 잘 지킬 것이라고 합니다.
안전하지 않은 모든 기능들은 --unstable 플래그를 이용해 사용할 수 있습니다.

Node.js와의 차이점

Deno는 Ryan Dahl이 Node.js를 개발하면서 후회했던 것들을 개선하기 위해 개발한 런타임이기 때문에, Node.js와의 차이점을 빼놓을 수 없습니다.

  • Deno는 npm을 사용하지 않습니다. 대신, URL이나 파일 경로로 모듈을 사용합니다.
    • 따라서 중앙집중형 패키지 레지스트리가 필요 없으며, 개발자들은 자신의 패키지를 자신이 원하는 곳에 자유롭게 배포할 수 있습니다.
    • 단, URL을 이용한 접근방식 때문에 권한 및 다운로드에 문제가 있을 수 있으므로, 형상 관리 시스템을 이용해서 별도로 저장하는 것을 권장합니다.
    • 매번 같은 모듈을 불러오기 위해 URL을 반복 타이핑하는 것이 귀찮다면, import maps를 이용할 수 있습니다.
  • 모듈 의존성 관리에 package.json을 사용하지 않습니다.
    • 징그러운 node_modules 폴더가 더 이상 필요 없습니다!
    • 대신 불러온 모듈을 다운로드하고 캐시 폴더($DINODIR)에 저장하여 캐싱한다고 합니다.
  • Deno의 모든 비동기 작업은 Promise객체를 반환합니다. 따라서 Node.js와는 다른 API를 제공합니다.
    • Node.js는 JavaScript의 Promise, async/await 이전에 개발이 되었습니다. 따라서 Promise와 반대되는 Event Emitter를 사용합니다.
    • Event Emitter는 여러 가지 이슈가 있습니다. 자세한 시나리오와 문제점은 Deno 블로그의 Promises All The Way Down섹션을 참고해주세요.
  • Deno는 파일 시스템, 네트워크, 환경 접근에 명시적인 허가가 필요합니다.
  • Deno는 항상 잡히지 않은 에러(uncaught error)에 죽습니다. (즉, 빡세게 에러 핸들링을 해야 하는 것 같습니다.)
  • ES Module 시스템을 사용하기 때문에 CommonJS Module 시스템인 require()를 사용하지 않습니다. 써드 파티 모듈은 다음과 같이 URL로 임포트 됩니다. import * as log from "<https://deno.land/std/log/mod.ts>";

한계

Deno는 Node.js에서 갈라져 나온 것이 아닙니다. 완전히 별개의 구현체입니다.
다음과 같은 여러가지 요구사항에 맞춰서 Deno를 도입할지 말지 결정하길 바랍니다.

호환성

Deno는 일반적으로 Node 패키지(npm을 이용해 설치 및 관리하는 패키지)와 호환되지 않습니다. 호환성 레이어를 https://deno.land/std/node/ 에 구축하긴 했지만, 완전하지는 않습니다.

HTTP 서버 성능

Node와 Deno의 HTTP 서버 성능 분석표
Deno HTTP ServerNode HTTP Server
초당 요청 처리 개수25k34k
최대 레이턴시1.3ms2~300ms
구현 방식native TCP socket 위에 TS를 얹음C로 작성 후 JavaScript에 대해 고차 바인딩으로 노출

초당 요청 처리 개수가 현저히 적지만, Deno 팀은 이 정도로도 충분하다고 생각하고 있습니다. 또한 일반적으로 레이턴시가 현저히 적다는 것을 기대하고 있습니다.
그렇지만 Deno 팀은 점진적으로 성능을 지속적으로 모니터링하고 개선시킬 것이라고 합니다. 더 많은 정보는 Deno Benchmark에 있습니다.

TSC(TypeScript Compiler) 병목현상

Deno는 내부적으로 MicroSoft사에서 제작한 TypeScript compiler를 타입 체킹에 사용하고 있습니다. 이는 V8 엔진과 비교하면 매우 느립니다. 그래서 V8 snapshot을 이용해 성능을 향상하긴 했지만, 아직 만족스럽지는 않다고 합니다.
Deno 팀은 기존의 TS compiler를 통해 개선할 수도 있지만, 궁극적으로는 타입 체킹을 Rust로 구현해서 성능을 개선하려고 합니다. 혹시라도 기여하고 싶다면 컨텍을 해달라고 하네요. ☺️

플러그인 및 확장(extension)

커스텀 오퍼레이션으로 Deno 런타임을 확장하기 위한 초기 플러그인 시스템이 있습니다. 하지만, 이러한 인터페이스는 아직 개발 중이며 안전하지 않습니다. 그래서 Deno에서 제공하는 인터페이스를 통해 native system에 접근하는 것은 어렵다고 합니다.

참고

Deno — A secure runtime for JavaScript and TypeScript.
https://d2.naver.com/helloworld/7700312

profile
지속가능한 웹 개발자를 지향합니다. 경험의 공유를 통해 타인에게 도움이 되는 것을 좋아합니다. 사용자에게 가치를 제공하는 것에 기쁨을 느낍니다.

0개의 댓글