Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Design Mistakes in Node & Deno #kng5 / deno

Design Mistakes in Node & Deno #kng5 / deno

関西Node学園 5時限目( https://nodejs.connpass.com/event/113631/ )でNode.jsの設計ミスについてとDenoの話をしました。
Denoはまだまだ試験段階なので本スライドの内容は変わるかもしれません。その点はご了承ください。

Masashi Hirano

February 01, 2019
Tweet

More Decks by Masashi Hirano

Other Decks in Programming

Transcript

  1. Design Mistakes in Node Node.js のオリジナル開発者Ryan Dahl 氏(ry) がJSConf EU

    2018 で発表したプレゼンテーション Node.js の設計ミスについて 現時点のNode.js を半年触ってみたがry が目指していたもの ではなかった Node.js の設計ミスを改善したDeno を開発していると発表 5
  2. 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
  3. 1. Not sticking with Promises 2009 年6 月にPromise を入れたが、2010 年2

    月には削除し た。それは間違いだった。 callback の方がパフォーマンスが優れていた async/await の抽象化のためにPromise は必要だった 9
  4. 3. The Build System (GYP) GYP(Generate Your Project) Chrome やV8

    やWebRTC にも使われていたが現在はGN に移 行している Node.js はそのままGYP を使っている 当時のChrome のビルドに乗っかった GN に比べてGYP は遅い Python2 系が必要 13
  5. foo/package.json { "name": "foo", "version": "1.0.0", "main": "bar.js" } index.js

    const foo = require('foo'); foo(); // => I'm bar.js 16
  6. 見つかるまで以下の優先度で探索する 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
  7. 以下のようなディレクトリ構成の場合、 ├── 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
  8. ES Modules によるモジュール解決 CJS(require) ではなくESM(import) を使ったモジュールロー ディング ディレクトリではなくファイルを指定 package.json 不要

    URL で外部モジュールを読み込むことが可能 一度読み込むとキャッシュする --reload オプションを付けると再取得する 29
  9. ネットワークへのアクセス ネットワークにアクセスするためには --allow-net を付ける $ deno hello_http.ts --allow-net OK. --allow-net

    を付けないと実行時に許可を求めてくる $ deno hello_http.ts Deno requests network access to "listen". Grant? [yN] 32
  10. 許可しなかった場合はパーミッションエラー 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
  11. Node.js からの改善点 Node.js Deno Promise Callback ベース Promise ベース Security

    ネットワークアクセスや ファイル書き込みに制限 がない デフォルトでは不可能 Build System GYP GN Module package.json 、 node_modules に依存 URL によるリソース取得、ディ レクトリではなくファイルを 指定 34
  12. Deno の構成 レイヤー ( 言語) 役割 TypeScript ユーザーが使うAPI のインターフェース。File System

    や Network へのアクセスなどはできない C++ V8 とのバインディング。TypeScript とRust のデータの受 け渡し Rust File System やNetwork へのアクセスなどを行う Privileged なレイヤー 37
  13. Deno API の処理順 1. TypeScript がV8 上で実行される 2. FlatBuffers を用いてPrivileged

    な領域にデータを渡す 3. Rust でTokio を用いて非同期タスク登録 4. Rust でファイル操作などPrivileged な処理を行う 5. 処理したデータをFlatBuffers を用いてUnprivileged な領域 に返却 39
  14. V8 Google が開発しているJavaScript エンジン Chrome やNode.js にも使われている V8 はTypeScript をそのまま実行できないのでDeno

    内部でJS に変換している 一度変換されたJS ファイルは~/.deno/gen にキャッシュさ れる コードを変更しない限りキャッシュを使って実行する 41
  15. 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