Slide 1

Slide 1 text

⾃分好みのTSバンドラをRustで作れる! Denoの内部ライブラリの活⽤ 株式会社 Flatt Security @pizzacat56 7879/8;/7<

Slide 2

Slide 2 text

$ whoami pizzacatKL Flatt Security ソフトウェアエンジニア 2020年5⽉、株式会社Flatt Securityにセキュリティエンジニア として⼊社。セキュリティエンジニア時代はWeb‧Firebase‧ クラウドのセキュリティ診断を担当。 現在は⾃動セキュリティ診断SaaS「Shisho Cloud」の開発に従事。 かわいいアイコンが好き。 k かわいいアイコンが好き

Slide 3

Slide 3 text

本⽇お伝えしたいこと JS/TS を扱うツールを Rust で⾃作するためのライブラリが発展している s Deno をはじめとして、 Node.js, Prettier, ESLint, Jest, Webpack 等の代替が Rust で実装されている

Slide 4

Slide 4 text

Deno は「Node.js の代替」? ã

Slide 5

Slide 5 text

Batteries included å $ deno run $ deno lint $ deno fmt deno_emit deno_core dprint deno_lint deno_graph deno_ast

Slide 6

Slide 6 text

Rusty Batteries included ç $ deno run $ deno lint $ deno fmt @deno/emit deno_core dprint deno_lint deno_graph deno_ast Deno の各種ツールは Rust で実装されている ⾃分好みの JS/TS ツールも Rust で実装できる!

Slide 7

Slide 7 text

modules: file:///mod.ts: | import { func1 } from "./lib1.ts" import { func2 } from "./lib2.ts" export default function() { console.log(func1() + func2()) } file:///lib1.ts: | export function func1() { return "func1" } file:///lib2.ts: | export function func1() { return "func2" } バンドラ作りました ô import { func1 } from "./lib1.ts" import { func2 } from "./lib2.ts" export default function() { console.log(func1() + func2()) } file:///lib1.ts import { func1 } from "./lib1.ts" import { func2 } from "./lib2.ts" export default function() { console.log(func1() + func2()) } file:///lib2.ts import { func1 } from "./lib1.ts" import { func2 } from "./lib2.ts" export default function() { console.log(func1() + func2()) } file:///mod.ts 本質的には、こんな Rust 関数 async fn bundle(entrypoint: Url) -> Map

Slide 8

Slide 8 text

何のためにバンドラを⾃作したのか プログラマブルな⾃動セキュリティ診断 SaaS † セキュリティ検査を TS 等のコードで表現 security-check.ts lib1.ts lib2.ts $ shisho-cli deploy \ security-check.ts まとめて アップロード }

Slide 9

Slide 9 text

何のためにバンドラを⾃作したのか プログラマブルな⾃動セキュリティ診断 SaaS £§ セキュリティ検査を TS 等のコードで表現 security-check.ts lib1.ts lib2.ts $ shisho-cli deploy \ security-check.ts まとめて アップロード } 詳しくは TSKaigi のアーカイブ動画をご視聴ください! TSKaigik§ks pizzacatôl

Slide 10

Slide 10 text

バンドラを Rust で実装 ££ deno_graph ™ 依存モジュールを列挙するライブラリ async fn bundle(entrypoint: Url) -> Map Goal

Slide 11

Slide 11 text

バンドラを Rust で実装 £k let mut graph = deno_graph::ModuleGraph::new(deno_graph::GraphKind::All); graph.build( vec![entrypoint], &mut loader, Default::default() ).await; /* graph.modules() Λ Map ʹม׵ */ file:///path/to/security-check.ts URL で指定されたモジュールを 実際に読み込むする実装 ❓ async fn bundle(entrypoint: Url) -> Map Goal

Slide 12

Slide 12 text

deno_graph の loader deno_graph は依存グラフ構築のロジックだけを提供 → 実際にモジュールを local‧Web から fetch する処理は loader として与える £l fn load( &mut self, specifier: &ModuleSpecifier, is_dynamic: bool, ) -> deno_graph::source::LoadFuture { if scheme == "file" { // ϑΝΠϧಡΈࠐΈ } else if scheme == "http" || scheme == "https" { // HTTP ϦΫΤετ } else // ... } loader の load メソッド例

Slide 13

Slide 13 text

loader が欲しい £s Deno CLI と同様の動きをする loader はどのライブラリにある? _⼈⼈⼈⼈_ > ない <  ̄Y^Y^Y ̄

Slide 14

Slide 14 text

Deno CLI と同じ loader を使いたい £ã ライブラリに切り出されておらず 外部からインポート不可 denoland/deno/cli/cache/mod.rs fn load( &self, specifier: &ModuleSpecifier, options: deno_graph::source::LoadOptions, ) -> LoadFuture { use deno_graph::source::CacheSetting as LoaderCacheSetting; if specifier.scheme() == "file" && specifier.path().contains("/node_modules/") { // The specifier might be in a completely different symlinked tree than // what the node_modules url is in (ex. `/my- project-1/node_modules` // symlinked to `/my-project-2/node_modules`), so first we checked if the path // is in a node_modules dir to avoid needlessly canonicalizing, then now compare crate::node::resolve_specifier_into_node_modules(specifier); if self.npm_resolver.in_npm_package(&specifier) { return Box::pin(futures::future::ready(Ok(Some( LoadResponse::External { specifier }, // against the canonicalized specifier. let specifier =

Slide 15

Slide 15 text

deno_emit が使っている loader は? £å _⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈_ > TS で実装されてる <  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄ export class FetchCacher { #fileFetcher: FileFetcher; constructor(fileFetcher: FileFetcher) { this.#fileFetcher = fileFetcher; } // this should have the same interface as deno_graph's loader load = ( specifier: string, _isDynamic?: boolean, cacheSetting?: CacheSetting, checksum?: string, ): Promise => { const url = new URL(specifier); return this.#fileFetcher.fetchOnce(url, { cacheSetting, checksum }); }; } denoland/deno_cache_dir/cache.ts

Slide 16

Slide 16 text

deno_emit が使っている loader は? £ç deno_graph $ deno run } loader コンパイル jsr:@deno/emit

Slide 17

Slide 17 text

結局、Deno CLI 同等の loader を使うために Deno CLI の loader 実装をコピペして使⽤中 Deno のアプデへの追従が⼤変…… £ô #

Slide 18

Slide 18 text

Deno の内部ライブラリはまだ v∫.x.x 時々アプデで破壊的変更が⼊る まだ若い技術ゆえのペイン £† #

Slide 19

Slide 19 text

本⽇お伝えしたいこと JS/TS を扱うツールを Rust で⾃作するためのライブラリが発展している k§ Deno をはじめとして、 Node.js, Prettier, ESLint, Jest, Webpack 等の代替が Rust で実装されている

Slide 20

Slide 20 text

株式会社 Flatt Security のサービス k£ 「セキュアにつくれてる」を確認する ⼿動‧⾃動セキュリティ診断 「セキュアにつくる」ための ハンズオン形式 e-ラーニング 無料トライアルあり!

Slide 21

Slide 21 text

エンジニア積極採⽤中! kk JS/TS バンドラ JS ランタイム システム構成可視化 開発エンジニア セキュリティ診断 セキュリティエンジニア カジュアル⾯談 お待ちしてます! モダンな技術スタックのプロダクトの セキュリティに取り組める環境 セキュリティ業務未経験でも OK! 開発経験とセキュリティへの熱意を重視します (開発エンジニア出⾝2名活躍中!) 技術的に⾯⽩いことやってます! セキュリティ専⾨家として共に腕を磨きませんか! 開発

Slide 22

Slide 22 text

⾃分好みのTSバンドラをRustで作れる! Denoの内部ライブラリの活⽤ 株式会社 Flatt Security @pizzacat56 7879/8;/7<

Slide 23

Slide 23 text

High-res Deno logo — The MIT License Copyright k§£ô kevinkassimo Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ks

Slide 24

Slide 24 text

The Prettier logo — The MIT License Copyright k§£ç James Long Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. kã