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

自分好みの TS バンドラを Rust で作れる!Deno の内部ライブラリの活用 – Denoで変わるランタイムの景色 実践事例 Lunch LT

自分好みの TS バンドラを Rust で作れる!Deno の内部ライブラリの活用 – Denoで変わるランタイムの景色 実践事例 Lunch LT

Denoで変わるランタイムの景色 実践事例 Lunch LT」(2024/06/21) での登壇資料です。

関連スライド:
Deno で作る快適な “as Code” プラットフォーム – TSKaigi 2024」(アーカイブ動画)
プログラマブルな自動セキュリティ診断 SaaS「Shisho Cloud」における、「セキュリティ検査ルールをTypeScriptで書ける」という機能の背景や仕組みについて。

pizzacat83

June 20, 2024
Tweet

More Decks by pizzacat83

Other Decks in Programming

Transcript

  1. Batteries included å $ deno run $ deno lint $

    deno fmt deno_emit deno_core dprint deno_lint deno_graph deno_ast
  2. 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 で実装できる!
  3. 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<Url, String>
  4. 何のためにバンドラを⾃作したのか プログラマブルな⾃動セキュリティ診断 SaaS £§ セキュリティ検査を TS 等のコードで表現 security-check.ts lib1.ts lib2.ts

    $ shisho-cli deploy \ security-check.ts まとめて アップロード } 詳しくは TSKaigi のアーカイブ動画をご視聴ください! TSKaigik§ks pizzacatôl
  5. バンドラを 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<Url, String> ʹม׵ */ file:///path/to/security-check.ts URL で指定されたモジュールを 実際に読み込むする実装 ❓ async fn bundle(entrypoint: Url) -> Map<Url, String> Goal
  6. 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 メソッド例
  7. 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 =
  8. 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<LoadResponse | undefined> => { const url = new URL(specifier); return this.#fileFetcher.fetchOnce(url, { cacheSetting, checksum }); }; } denoland/deno_cache_dir/cache.ts
  9. エンジニア積極採⽤中! kk JS/TS バンドラ JS ランタイム システム構成可視化 開発エンジニア セキュリティ診断 セキュリティエンジニア

    カジュアル⾯談 お待ちしてます! モダンな技術スタックのプロダクトの セキュリティに取り組める環境 セキュリティ業務未経験でも OK! 開発経験とセキュリティへの熱意を重視します (開発エンジニア出⾝2名活躍中!) 技術的に⾯⽩いことやってます! セキュリティ専⾨家として共に腕を磨きませんか! 開発
  10. 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
  11. 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ã