Slide 1

Slide 1 text

Deno A new way to JavaScript 平野昌士@shisama https://deno.land/

Slide 2

Slide 2 text

https://github.com/shisama/shisama

Slide 3

Slide 3 text

Agenda Design Mistakes in Node Introduction to Deno Deno Core Deno for Users 3

Slide 4

Slide 4 text

Design Mistakes in Node 4

Slide 5

Slide 5 text

Design Mistakes in Node Node.js のオリジナル開発者Ryan Dahl 氏(ry) がJSConf EU 2018 で発表したプレゼンテーション Node.js の設計ミスについて 現時点のNode.js を半年触ってみたがry が目指していたもの ではなかった Node.js の設計ミスを改善したDeno を開発していると発表 5

Slide 6

Slide 6 text

https://youtu.be/M3BM9TB-8yA 6

Slide 7

Slide 7 text

解説付き日本語訳 https://yosuke-furukawa.hatenablog.com/entry/2018/06/07/080335 7

Slide 8

Slide 8 text

Design Mistakes in Node 1. Not sticking with Promises. 2. Security 3. The Build System (GYP) 4. package.json 5. node_modules 6. require("module") without the extension ".js" 7. index.js 8

Slide 9

Slide 9 text

1. Not sticking with Promises 2009 年6 月にPromise を入れたが、2010 年2 月には削除し た。それは間違いだった。 callback の方がパフォーマンスが優れていた async/await の抽象化のためにPromise は必要だった 9

Slide 10

Slide 10 text

1. Not sticking with Promises http://b.hatena.ne.jp/entry/365474721/comment/jovi0608 10

Slide 11

Slide 11 text

現在のNode.js では v8 からutil.promisify が使える v10 からfs.promises やdns.promises が使える(Experimental) https://nodejs.org/api/ 11

Slide 12

Slide 12 text

2. Security V8 自体はとても優れたセキュリティsandbox になっている 特定のアプリケーションでその点をもっと考慮できていれ ば、他の言語にはないセキュリティを担保できた 例えば、lint を動かすだけなのにネットワークにアクセスす る必要はない 12

Slide 13

Slide 13 text

3. The Build System (GYP) GYP(Generate Your Project) Chrome やV8 やWebRTC にも使われていたが現在はGN に移 行している Node.js はそのままGYP を使っている 当時のChrome のビルドに乗っかった GN に比べてGYP は遅い Python2 系が必要 13

Slide 14

Slide 14 text

4. package.json package.json のmain のファイルをエントリポイントにして しまった npm リポジトリが中央集権になってしまった package.json のdependencies は ディレクトリをモジュールとして扱ってしまった 14

Slide 15

Slide 15 text

例えば以下のような構成になっていて . ├── foo │├── bar.js │└── package.json └── index.js foo/bar.js module.exports = () => { console.log("I'm bar.js"); } 15

Slide 16

Slide 16 text

foo/package.json { "name": "foo", "version": "1.0.0", "main": "bar.js" } index.js const foo = require('foo'); foo(); // => I'm bar.js 16

Slide 17

Slide 17 text

5. node_modules モジュール解決をとても複雜なものにしてしまっている ブラウザのセマンティクスからも外れてしまっている 17

Slide 18

Slide 18 text

https://tinyclouds.org/jsconf2018.pdf 18

Slide 19

Slide 19 text

6. require("module") without the extension ".js" ブラウザではJavaScript を読み込むときはファイルパスの拡 張子.js を省略しない 複数のロケーションのファイルシステムを探索しなければ ならない 19

Slide 20

Slide 20 text

例えば、foo というモジュールをimport しようとすると、 import foo from './foo'; 20

Slide 21

Slide 21 text

見つかるまで以下の優先度で探索する 1. ./foo 2. ./foo.mjs 3. ./foo.js 4. ./foo.json 5. ./foo.node 6. ./foo/package.json // main で指定したファイルor ディレクトリ 6-1. ./foo/bar 6-2. ./foo/bar.mjs 6-3. ./foo/bar.js 6-4. ./foo/bar.json 6-5. ./foo/bar.node 6-6. ./foo/bar/package.json // main で指定したファイルor ディレクトリ 6-6-1. ./foo/bar/hoge 6-6-2. ./foo/bar/hoge.mjs ... 7. ./foo/index 8. ./foo/index.mjs ... 21

Slide 22

Slide 22 text

https://teppeis.hatenablog.com/entry/2017/08/es-modules-in-nodejs 22

Slide 23

Slide 23 text

7. index.js index.html っぽく省略可能にしてしまった モジュールローディングを無駄に複雜にしてしまった require 関数がpackage.json をサポートした後は特に不要に なった 23

Slide 24

Slide 24 text

以下のようなディレクトリ構成の場合、 ├── index.js └── modules ├── Bar │└── index.js └── Foo └── index.js index.js を指定しなくてもディレクトリを指定するだけでモジュール 読み込みができてしまう // index.js を明示的に指定していない const bar = require("./modules/Bar"); const foo = require("./modules/Foo"); foo(); bar(); 24

Slide 25

Slide 25 text

これまで話したNode.js の設計ミスを改 善したプロジェクトをry が始めた 25

Slide 26

Slide 26 text

https://deno.land/ 26

Slide 27

Slide 27 text

Deno TypeScript をV8 で実行するためのランタイム ES Modules によるモジュール解決 Secure な実行環境 27

Slide 28

Slide 28 text

TypeScript 静的型付け可能なJavaScript のスーパーセット Deno ではユーザーがトランスパイルする必要なし TS ファイルを直接実行できる e.g. deno sample.ts 実行時にDeno がビルドする Deno が持つAPI の型定義はDeno がサポート deno --types > deno.d.ts で出力 28

Slide 29

Slide 29 text

ES Modules によるモジュール解決 CJS(require) ではなくESM(import) を使ったモジュールロー ディング ディレクトリではなくファイルを指定 package.json 不要 URL で外部モジュールを読み込むことが可能 一度読み込むとキャッシュする --reload オプションを付けると再取得する 29

Slide 30

Slide 30 text

URL による外部モジュールを読み込むことが可能 インターネット上のモジュールを指定 import * as log from "https://deno.land/x/std/log/mod.ts"; log.debug("Hello world"); 相対パスで指定 import hello from "./hello.ts"; hello(); 30

Slide 31

Slide 31 text

Secure な実行環境 デフォルトではネットワークアクセスなど安全ではない処 理は行えない 実行時にオプションを付けることで許可する --allow-net ネットワークアクセスを許可 --allow-write ファイル書き込みを許可 --allow-env 環境変数参照を許可 --allow-run サブプロセスの起動を許可 -A すべて許可 31

Slide 32

Slide 32 text

ネットワークへのアクセス ネットワークにアクセスするためには --allow-net を付ける $ deno hello_http.ts --allow-net OK. --allow-net を付けないと実行時に許可を求めてくる $ deno hello_http.ts Deno requests network access to "listen". Grant? [yN] 32

Slide 33

Slide 33 text

許可しなかった場合はパーミッションエラー Deno requests network access to "listen". Grant? [yN]N PermissionDenied: permission denied at DenoError (deno/js/errors.ts:19:5) at maybeError (deno/js/errors.ts:38:12) at maybeThrowError (deno/js/errors.ts:26:15) at sendSync (deno/js/dispatch.ts:67:5) at listen (deno/js/net.ts:145:19) at serve (file:///Users/admin/.deno/deps/https/deno.land/x/http/http.ts:53:20) at main (file:///Users/admin/hello_http.ts:6:23) at eval (file:///Users/admin/hello_http.ts:11:1) at _drainRunQueue (deno/js/compiler.ts:209:38) at run (deno/js/compiler.ts:587:10) 33

Slide 34

Slide 34 text

Node.js からの改善点 Node.js Deno Promise Callback ベース Promise ベース Security ネットワークアクセスや ファイル書き込みに制限 がない デフォルトでは不可能 Build System GYP GN Module package.json 、 node_modules に依存 URL によるリソース取得、ディ レクトリではなくファイルを 指定 34

Slide 35

Slide 35 text

Deno Core 35

Slide 36

Slide 36 text

https://tinyclouds.org/jsconf2018.pdf 36

Slide 37

Slide 37 text

Deno の構成 レイヤー ( 言語) 役割 TypeScript ユーザーが使うAPI のインターフェース。File System や Network へのアクセスなどはできない C++ V8 とのバインディング。TypeScript とRust のデータの受 け渡し Rust File System やNetwork へのアクセスなどを行う Privileged なレイヤー 37

Slide 38

Slide 38 text

https://tinyclouds.org/deno_20190124.pdf 38

Slide 39

Slide 39 text

Deno API の処理順 1. TypeScript がV8 上で実行される 2. FlatBuffers を用いてPrivileged な領域にデータを渡す 3. Rust でTokio を用いて非同期タスク登録 4. Rust でファイル操作などPrivileged な処理を行う 5. 処理したデータをFlatBuffers を用いてUnprivileged な領域 に返却 39

Slide 40

Slide 40 text

https://tinyclouds.org/deno_20190124.pdf 40

Slide 41

Slide 41 text

V8 Google が開発しているJavaScript エンジン Chrome やNode.js にも使われている V8 はTypeScript をそのまま実行できないのでDeno 内部でJS に変換している 一度変換されたJS ファイルは~/.deno/gen にキャッシュさ れる コードを変更しない限りキャッシュを使って実行する 41

Slide 42

Slide 42 text

https://tinyclouds.org/deno_20190124.pdf 42

Slide 43

Slide 43 text

FlatBuffers Google が開発しているシリアライゼーションライブラリ ProtocolBuffers より速い パースなしでシリアライズされたデータにアクセス可能 FlatBuffers 専用のフォーマットでスキーマ定義を書く Deno ではUnprivileged な領域からPrivileged な領域にデー タを渡すために使っている 43

Slide 44

Slide 44 text

https://tinyclouds.org/deno_20190124.pdf 44

Slide 45

Slide 45 text

Tokio 非同期処理を扱うRust のライブラリ イベント駆動型のNon-Blocking I/O マルチスレッドによる並列処理が可能 45

Slide 46

Slide 46 text

https://tinyclouds.org/deno_20190124.pdf 46

Slide 47

Slide 47 text

Rust Mozilla が開発しているプログラミング言語 C 、C++ に代わるプログラミング言語を目指している Cargo というパッケージマネージャ兼ビルドツールがある Deno では様々なRust のパッケージ(Crate) を使っている tokio-fs: File System 操作 reqwest: HTTP クライアント etc... 47

Slide 48

Slide 48 text

A Guide to Deno Core コアコントリビューターによるDeno のコアの内部の構成やAPI の実装 方法などの解説書 https://denolib.gitbook.io/guide 48

Slide 49

Slide 49 text

Let's Contribute! 49

Slide 50

Slide 50 text

Deno for Users 50

Slide 51

Slide 51 text

公式ページ - deno.land https://deno.land 51

Slide 52

Slide 52 text

Install Deno をインストール $ curl -L https://deno.land/x/install/install.sh | sh $ export PATH=$HOME/.deno/bin:$PATH インストール後の検証 $ deno https://deno.land/thumb.ts Downloading https://deno.land/thumb.ts... Compiling https://deno.land/thumb.ts 52

Slide 53

Slide 53 text

deno_std https://github.com/denoland/deno_std コアとは別で公式が提供している標準モジュール HTTP 、アサーション、Path などよく使われるモジュールは 揃っている 最近ではWebSocket とかPrettier が入った 53

Slide 54

Slide 54 text

Registry https://github.com/denoland/registry 公式のパッケージレジストリ 誰でも開発したモジュールを登録することができる PR を投げて承認されれば登録される 登録されると https://deno.land/x/ から始まるURL でモジュ ール参照可能になる 54

Slide 55

Slide 55 text

awesome-deno https://github.com/denolib/awesome-deno Deno のモジュールやツールや記事が紹介されている 55

Slide 56

Slide 56 text

フレームワークも既に作られている ※上記は一部です。他にもあります。 56

Slide 57

Slide 57 text

まとめ Node.js には設計ミスによる課題が残っている Deno はNode.js の課題を改善している Deno はシンプルで各レイヤーが疎結合な設計になっている ユーザーやライブラリが増えてきて盛り上がりを感じる Deno はまだ試作段階だからNode.js 使いましょう!by ry 57

Slide 58

Slide 58 text

その他参考 deno について知っていること2019 年1 月編 - keroxp の Scrapbox (@keroxp) Deno を読む(1) - unde ned (@bokuweb) 58

Slide 59

Slide 59 text

Thanks. 59