Deno for JavaScript Beginners

eeeclipse·2020년 7월 4일
1
post-thumbnail

이 글은 Deno for JavaScript Beginners를 공부하면서 정리한 글입니다.

GOAL

  • Deno의 사용법을 익히고, 간단한 코드를 작성할 수 있다.
  • Deno 와 Node의 차이를 이해하고, 설명할 수 있다.

Introduction

Deno is a modern, fast, secure, run time

So, you're trying to learn JavaScript. You have just gotten a bit fluent with JavaScript in the browser. Then all of a sudden, you come across Deno and the #NodeKiller hype. But you don't know what any of these are. If that's the case, read on!

Before diving in, you need some background information.

JavaScript Engine

자바스크립트는 인터프리트 프로그래밍 언어입니다. 이는 소스코드가 실행되기 위하여 바이너리 코드로 컴파일 되지 않아도 된다는 것을 의미해요.

그렇다면 어떻게 컴퓨터가 플레인 텍스트 스크립트를 토대로 무엇을 해야할 지 알 수 있을까요 ?

그 '무엇'을 해야하는 지 알려즌 것이 자바스크립트 엔진입니다. 자바스크립트 엔진은 자바스크립트 코드를 실행가능한 기계어로 컴파일합니다. 이 과졍은 Just In Time (JIT) compilation이라고 부릅니다.

예를 들어, 자바스크립트를 구글 크롬에서 실행할 때를 생각해봅시다. 이때 자바스크립트 엔진은 V8입니다. 만일 모질라 파이어폭스를 사용한다면 SpiderMonkey입니다.

JavaScript Runtime

통산 자바스크립트 엔진을 직접적으로 사용하진 않습니다. 자바스크립트 엔진은 어떠한 환경 안에서 실행되는데, 이 환경은 런타임에서 실행되는 자바스크립트 응용프로그램이 여러가지 특성들(features)을 더해줍니다.

그렇다면 여기서 말하는 특성들(features)은 무엇을 의미하는 걸까요 ?

예를 들면, 이들은 엔진 외부의 환경과 통신할 수 있도록 하는 APIs 등이 있을 것입니다. 구글 크롬같은 브라우저는 데스크탑 자바스크립트 런타임환경인데, 이때 V8 자바스크립트 엔진을 사용하며 DOM API, Fetch API, Strage API 등을 제공합니다.

비슷한 방식으로, Node나 Deno같은 서버 사이드 런타임 환경은 V8 자바스크립트 엔진을 아용하면서 파일시스템 접근, 네트워크 접근, 콘솔 등을 제공합니다.

Why do we need a runtime outside of a browser?

대체로 자바스크립트의 주 환경은 웹브라우저이지만, 근래 들어서 자바스크립트는 서버 플랫폼으로도 사용되고 있습니다.

서버사이드 자바스크립트 런타임 환경은 브라우저에서 할 수 없는 작업들을 할 수 있게 해줍니다. 위에 언급된 것처럼 파일 시스템 접근이나 네트워크 접근 같은 일들이요. 따라서 MEAN이나 MARN같은 기술 스택들을 오로지 자바스크립트에 기반해 이용해서 전체 웹 응용프로그램을 빌드할 수 있습니다.

What's wrong with NodeJS?

NodeJS를 창시한 Ryan Dahl에 따르면, NodeJS는 몇 가지 잘못된 지점들이 있습니다. JSConf EU 2018에서 그는 이에 대한 내용을 발표하기도 했습니다. 발표 영상은 여기를 참고하세요.

Not sticking with Promises

Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냅니다.
사실 NodeJS가 처음 나왔을때는 promises를 지원했었습니다. 그러나 몇 달 후, 이 지원은 없어졌습니다. 이로 인해 NodeJS는 promises 적용을 위해서 제2의 해결책을 사용해야 했습니다.

Security

V8 엔진 자체는 매우 훌륭한 보안 샌드박스를 자랑합니다. NodeJS는 모든 보안 특성을 제거하고, 응용프로그램이 모든 것에 접근할 수 있도록 만들었습니다 ^^ ...

The Build System

구글 크롬은 GYP를 빌드 시스템으로 사용하기 시작했고, NodeJS도 마찬가지로 GYP로 변경했습니다. 그러나, 얼마 후 크롬은 GYP 대신 더 빠르고 간단한 GN을 사용하기 시작했습니다. Ryan Dahl는 GYP를 사용한 것이 아마도 NodeJS core의 가장 커다란 실수일 것이라고 밝혔습니다.

npm and package.json

모든 npm 패키지는 root 폴더에 package.json라는 이름의 파일을 포함하고 있습니다. 이 파일은 프로젝트에 대한 다양한 메타데이터에 대한 것을 기술하고 있습니다.

What's npm

npm(Node Package Manager)는 이름 그대로 프로젝트에 의존성이 있는 패키지를 관리하는데 사용됩니다.
듣기엔 그럴싸한데, 어떤 문제가 있는걸까요 ?

package.json 파일에는 불필요한 정보들을 담고 있습니다. npm registry에 대해서만 필요한 것들인데도 말이에요. Ryan은 이것을 "boilerplate noise"라고 표현했는데, 이는 프로젝트에 아무런 도움을 주지 않으면서 노이즈만 발생시킨다는 것을 의미합니다.

npm은 중앙집권적이고, 프라이빗하게 컨트롤됩니다. 만일 브라우저에서 어떤 프로젝트를 끝낸다면, 어떤 의존성에 연결되어있는지 알 수 있을거에요. JQuery나 Bootstrap처럼요. HTML에 어떤 종류의 링크건 추가할 수 있고, 이를 직접적으로 사용할 수도 있습니다. 노트에서는 npm외에는 의존성에 관련된 것들을 설치할 방법이 없어요.

require("module") without the extension ".js"

외부 라이브러리를 가져오는 방식에 대해 생각해봅시다. 예를 들어, 프로젝트에 JQuery를 설치하고 싶다면, npm을 설치한 후에 다음의 커맨드를 입력해야할 거에요.

npm install jquery

그리고나서 이걸 파일에서 사용하려면, 사용하고자 하는 파일에서 "require()" statement를 추가해줘야합니다.

require("JQuery")
// code that uses JQuery

꽤 간단해보이죠 ?

그러나 이 간단한 문법을 실행하기 위한 알고리즘들은 매우 복잡하고 비효율적입니다. 모듈로더는 다양한 지점에서 쿼리를 해야하고, 사용자가 필요로 하는 것이 무엇인지에 대해 추측해야하는 상황에 놓이게 되거든요

node_modules

이 부분은 저 위의 모듈을 가져오는 간단한 구문에 대한 여파입니다.
프로젝트에 의존성을 설치할때, 통상 node_modules에 다운로드하게 됩니다.

오프라인 상태에서도 모듈을 사용할 수 있으니 더 좋은 건 아닐까 싶지만 몇 가지 문제들이 숨어있습니다.

추가한 의존성은 그들 자체적으로도 의존성을 갖고 있습니다. 이 의존성 트리는 점점 더 커지고, 관리하거나 저장하는데도 어려워집니다. 그리고 이 작업들을 모든 프로젝트 하나하나에 적용해줘야합니다 ! 대부분 동일한 의존성을 갖고있을텐데도 말이에요. 프로젝트간에 의존성을 공유하는 방식에 대하여 알고 계신가요? 저는 아직까지는 들어보지 못했습니다.

자, Deno는 어떨까요 ? 두 개의 서로 다른 프로젝트를 생성했다고 가정해봅시다. 두 프로젝트는 모두 JQuery를 사용하므로,JQuery.js를 다운로드하고, 두 프로젝트가 공유하는 폴더에 넣어서 링크시켰습니다. 프로젝트를 배포하려고 한다면, 링크를 리모트 파일로 바꾸고 배포하면 됩니다. 로컬 파일을 가지고 있다가 차후 생성할 프로젝트에서 재활용을 할 수도 있습니다. 이건 Node에서는 불가능한 것이지요.

넘나 무거운 node_modules
넘나 무거운 node_modules

index.js

index.html과 비슷하게, NodeJS는 index.js를 참조합니다. 이건 정말 쓸모없는 일이에요. 모듈 로딩 시스템을 더 복잡하게만 만들어버리거든요. 특히 package.json에서 지원하는 require()를 사용한다면 더더욱 쓸모없어집니다.

Why don't they fix these problems?

이 모든 문제들의 출발 지점은 NodeJS의 core feature에 의거합니다. 이 문제들을 고치는 건 아예 완전히 새로운 걸 만드는 거라고 볼 수 있어요.
NodeJS는 어디에나 있습니다 ! 그리고 이미 NodeJS를 사용하는 수많은 코드들이 있기에, 이 문제들을 해결하려할 경우에는 기존의 코드들은 영원 속으로 사라질 수도 있을거에요. 대부분의 오래된 코드는 더이상 쓸모없어질거구요. 엄청나게 많은 기술 기업들이 NodeJS를 사용하고 있고, 많은 개발자들이 개인 프로젝트에 쓰고 있습니다. 정말 말 그대로 어디에나 있어요 !

그렇다면 왜 그들은 완전히 새로운 것을 만들지 않을까요 ?

그걸 하기 위해서는, 그 완전히 새로운 걸 만들 수 있다는 걸 확실히 알 필요가 있죠.
2009년에 NodeJS가 처음 나왔을때, 그 당시 웹 환경에서 할 수 있는 최고의 선택이었어요.

그리고 실제로, 그 완전히 새로운 무언가가 나오긴 했어요. 그게 바로 Deno입니다 .

What is Deno?

Deno is a new cross-platform runtime environment, based on Google's V8 engine, just like NodeJS.

Deno는 새로운 크로스플랫폼 런타임환경입니다. 구글의 V8엔진을 사용하고 있어요. NodeJS와 동일한 목적을 위해 Ryan Dahl에 의해 만들어졌습니다.

Deno는 NodeJS와 어떤 차이가 있을까요 ?

C++로 쓰여진 Node와 다르게, Deno는 Rust로 만들어져있고, 따라서 더 빠르고 안전합니다. 또한 멋진 기능들도 갖고 있어요.

TypeScript support

Deno는 Typescript를 지원합니다. 세팅이나 configuration을 건들지 않아도요!

TypeScript는 JavaScript의 상위확장입니다. Microsoft에 의해 개발되었습니다. 자바스크립트 응용프로그램을 쉽게 스케일업할 수 있게 도와주긷 하고, 예측가능한 버그들을 시작부터 예방해주기도 합니다.

물론 Deno를 쓰기 위해서 새로운 언어를 배울 필욘 없어요. 모든 자바스크립트 코드는 타입스크립트 코드이기도 합니다. 물론 이 명제의 역은 참이 아닙니다 ! TypeScript는 ECMAScript 3 또는 그 이상을 지원하는 자바스크립트 엔진 위에서 깔끔하고 간략한 자바스크립트 코드를 동작시키기 위해서 만들어졌습니다.

ECMAScript 는 또 뭐냐구요? 너무 어렵게 생각하지 마세요. 자바스크립트의 버전이라고 생각하면 쉽습니다. ECMAScript에 대한 더 많은 정보는 여기를 참조하세요

ES modules import syntax

Deno는 ES module 문법을 사용하는 웹으로부터 임포트를 가능케해줍니다.

그렇다면 오프라인 환경은 어떨까요?
Deno는 최초 페치할 때 의존성을 캐싱합니다. 따라서 별도의 로컬 파일을 사용할 필요가 없습니다. 그리고 캐싱된 의존성들은 프로젝트간에 공유되므로, 이를 복사해서 사용해도 문제가 없습니다.

이 부분이 node_modules의 거의 모든 문제들을 해결해주게 되는데요, 따라서 Deno는 더 성능이 좋은 표준 자바스크립트를 어디서든 사용할 수 있게 해줍니다.

Secure by default

기본적으로 Deno에서 JavaScript를 실행하면, 프로젝트 디렉토리 내에서 읽기 권한만 갖게 됩니다. 스크립트가 어떠한 권한을 갖도록 하게 하려면 명시적으로 이를 선언해주어야 합니다. 심지어 인터넷이나 로컬 네트워크 연결에 대한 권한도 부여를 해야합니다. 즉, 유저는 스크립트가 할 수 있는 범위에 대해 모든 결정권한을 가집니다.

대부분의 중요한 일은 엔진 쪽에서 이루어집니다. 런타임 그 자체는 빠르고, 브라우저 규격을 따르므로 기존에 구성된 API를 사용하거나 npm을 제거하는 등의 작업이 필요하지 않습니다. 모든 거추장스러운 것들을 벗겨버리고 최소한의, 그러나 모든게 가능한 런타임 환경을 만들어줍니다.

Deno의 탄생으로 Node는 죽었나요

사실 그렇진 않습니다. Node는 여전히 많은 곳에 있습니다. 오랜 시간동안 Node는 많은 유저와 다양한 리소스, 그리고 커뮤니티의 전폭적인 지지를 받아왔습니다. 그에 비해 Deno는 최근 들어 1.0 버전을 내놓았죠. Node에 비해 상대적으로 적은 유저들과 자료의 부족, 그리고 그 자체가 JavaScript를 양분해버렸기 때문에 아직은 걸음마 단계라고 볼 수 있습니다.

더군다나 아직 Deno를 이용한 표준 워크플로우나 개발 스택이 충분히 연구된 것도 아니에요. 구글이나 마이크로소프트 같은 거대한 테크 기업들이 Deno로 전환하는데도 엄청난 시간이 걸릴거에요.

그럼에도 불구하고 많은 사람들이 Deno를 사용하려고 시도할겁니다. 풀 커밋은 아직 저도 못해봤지만, 계속 시도하고, 공부할겁니다.

만일 자바스크립트가 처음이라면 NodeJS를 먼저 공부하세요. 미래에 Deno가 여전히 NodeKiller로서의 역할이 유효하다면, Deno로 바꾸는 건 쉬워요. 우리가 해야하는 건 간단한 불러오기 문법들을 던져버리고, 스스로가 만드는 것에 대한 책임감을 갖고 개발을 하는 것이니까요 !

Code with DENO

Installation

Deno는 커맨드라인 몇 줄로 금방 설치할 수 있습니다. OS 마다 추천방식이 있지만 특정 패키지 매니저를 사용한다면 그를 이용한 방법들로 설치할 수도 있습니다.

  • Windows (Powershell)
    iwr https://deno.land/x/install/install.ps1 -useb | iex

    • Alternative
      choco install deno
      scoop install deno
      brew install deno
  • Mac/Linux (Shell)
    curl -fsSL https://deno.land/x/install/install.sh | sh

    • Alternative
      brew install deno
      cargo install deno
  • Linux Recommended
    curl -fsSL https://deno.land/x/install/install.sh | sh

    • Alternative
      brew install deno
      cargo install deno
      apt install deno
      wget https://deno.land/x/install/install.sh; ./install.sh
      설치하면 다음과 같은 화면을 얻습니다
$ deno --version
deno 1.1.3
v8 8.5.216
typescript 3.9.2

온라인에서 실행할 수 있는 Deno Playground도 있어요 !

Coding Tools & Environment

Deno를 설치했으니 개발환경을 세팅해봅시다.
VSCode 에서는 vscode_deno 확장을 설치할 수 있습니다.

Example : Microservice

개발 환경까지 세팅했으니 간단한 마이크로서비스를 하나 만들어봅시다 .

import { serve } from 'https://deno.land/std@v0.30.0/http/server.ts';

const s = serve({ port: 80 });
console.log('Listening on http://localhost:80/');

for await (const req of s) {
  req.respond({ body: 'Hello Javascript! Hello Deno !' });
}  

서버를 띄우면 다음과 같이 나옵니다

끝 !

Reference

Deno
Deno Code

profile
mathematician, researcher, Data Scientist ⊗ Engineer ⊗ Architect, DBA

0개의 댓글