Slide 1

Slide 1 text

semigura @ 株式会社Gaji-Labo 2023/12/08 We Are JavaScripters! @43rd【初心者歓迎・LT会】 JavaScript & TypeScript 用の オールインワンツールキット「Bun」 1

Slide 2

Slide 2 text

自己紹介 株式会社Gaji-Labo フロントエンドエンジニア React + TypeScript + Next.js で奮闘中 猫と音楽が好き 最近は Astro に興味あり 石垣祥太郎 @semigura 2

Slide 3

Slide 3 text

3 https://bun.sh/

Slide 4

Slide 4 text

4 JavaScript & TypeScript 用のランタイム & オールインワンツールキット 特徴 1. ランタイムだけではなく、バンドラー、テストランナー、パッケージマネージャーも含ま れている 2. 速い 3. 開発が活発に行われている

Slide 5

Slide 5 text

クイックスタート 5 $ bun create next-app テンプレートから作成 $ bun init 対話型で新規プロジェクトを作成

Slide 6

Slide 6 text

Bun の特徴 6 1. all-in-one (ランタイムだけではなく、バンドラー、テストランナー、 パッケージマネージャーも含まれている) 2. 速い 3. 開発が活発に行われている

Slide 7

Slide 7 text

all-in-one 7 https://bun.sh/

Slide 8

Slide 8 text

all-in-one 8 バンドラー Bun.build({ entrypoints: ['./src/index.tsx'], outdir: './build', minify: true, // additional config }); JavaScript ファイル/CLIでバンドル可 import { expect, test } from "bun:test"; test("2 + 2", () => { expect(2 + 2).toBe(4); }); テストランナー Jest 互換 $ bun add eslint -D npm 互換 パッケージマネージャー

Slide 9

Slide 9 text

Bun の特徴 9 1. all-in-one (ランタイムだけではなく、バンドラー、テストランナー、 パッケージマネージャーも含まれている) 2. 速い 3. 開発が活発に行われている

Slide 10

Slide 10 text

速い 10 React SSRのHTTPリクエスト - Node.js v20.5.0 - 13,967 リクエスト/秒 - Deno.serve() v1.36.2 - 32,921 リクエスト/ 秒 - Bun v1.0 - 66,706 リクエスト/秒 Bun のレンダリングは、Deno のほぼ 2 倍、 Node.js の約 5 倍速いとのこと https://bun.sh/

Slide 11

Slide 11 text

速い 11 作者による計測結果

Slide 12

Slide 12 text

速い 12 テストランナー パッケージマネージャー Jest の最大20倍 npm の29倍

Slide 13

Slide 13 text

Bun の特徴 13 1. all-in-one (ランタイムだけではなく、バンドラー、テストランナー、 パッケージマネージャーも含まれている) 2. 速い → 実際どれくらい速いのか? 3. 開発が活発に行われている

Slide 14

Slide 14 text

14 実計測してみる `bun create next-app` と `npx create-next-app@latest` を比較 - テスト(Next.js ビルトインの Jest と bun:test) - パッケージインストール

Slide 15

Slide 15 text

テストランナー 15 import { render, screen } from "@testing-library/react"; import { expect, it, describe } from "bun:test"; import App from "./App"; describe("render a component", () => { render(); it("exists img element has className='App-logo' and alt='logo'", () => { const logoElement = screen.getByRole("img", { name: /logo/i }); expect(logoElement).not.toBeNull(); expect(logoElement.className).toBe("App-logo"); expect(logoElement.alt).toBe("logo"); }); it("exists link element has href='https://reactjs.org/'", () => { const linkElement = screen.getByRole("link", { name: /learn react/i }); expect(linkElement).not.toBeNull(); expect(linkElement.href).toBe("https://reactjs.org/"); }); it("if exists link element has target='_blank' then it has rel='noopener noreferrer'", () => { const blankLinkElement = screen.getByRole("link", { target: "_blank" }); expect(blankLinkElement).not.toBeNull(); expect(blankLinkElement.rel).toBe("noopener noreferrer"); }); });

Slide 16

Slide 16 text

テストランナー 16 function App() { return (
logo

Edit src/App.tsx and save to reload.

Learn React
); } import { render, screen } from "@testing-library/react"; import { expect, it, describe } from "bun:test"; import App from "./App"; describe("render a component", () => { render(); it("exists img element has className='App-logo' and alt='logo'", () => { const logoElement = screen.getByRole("img", { name: /logo/i }); expect(logoElement).not.toBeNull(); expect(logoElement.className).toBe("App-logo"); expect(logoElement.alt).toBe("logo"); }); it("exists link element has href='https://reactjs.org/'", () => { const linkElement = screen.getByRole("link", { name: /learn react/i }); expect(linkElement).not.toBeNull(); expect(linkElement.href).toBe("https://reactjs.org/"); }); it("if exists link element has target='_blank' then it has rel='noopener noreferrer'", () => { const blankLinkElement = screen.getByRole("link", { target: "_blank" }); expect(blankLinkElement).not.toBeNull(); expect(blankLinkElement.rel).toBe("noopener noreferrer"); }); });

Slide 17

Slide 17 text

テストランナー 17 ✓ render a component > exists img element has className='App-logo' and alt='logo' [13.53ms] ✓ render a component > exists link element has href='https://reactjs.org/' [1.56ms] ✓ render a component > if exists link element has target='_blank' then it has rel='noopener noreferrer' [0.36ms] 3 pass 0 fail 7 expect() calls Ran 3 tests across 1 files. [436.00ms] PASS src/App.test.js render a component ✓ exists img element has className='App-logo' and alt='logo' (80 ms) ✓ exists link element has href='https://reactjs.org/' (32 ms) ✓ if exists link element has target='_blank' then it has rel='noopener noreferrer' (10 ms) Test Suites: 1 passed, 1 total Tests: 3 passed, 3 total Snapshots: 0 total Time: 1.155 s Jest Time: 1.155 s Bun Ran 3 tests across 1 files. [436.00ms] 約2.64倍の速度差

Slide 18

Slide 18 text

パッケージインストール 18 $ npm i added 333 packages, and audited 334 packages in 9s $ bun i 331 packages installed [1.60s] bun yarn 約6.6倍 npm 約5.92倍 pnpm 約7.75倍※ create-next-app の初期状態で 差があるので、 もっと大規模だとかなりの 差になることが予想できる! $ yarn ✨ Done in 10.56s. $ pnpm i Done in 12.4s

Slide 19

Slide 19 text

Bun の特徴 19 1. all-in-one (ランタイムだけではなく、バンドラー、テストランナー、 パッケージマネージャーも含まれている) 2. 速い 3. 開発が活発に行われている

Slide 20

Slide 20 text

開発が活発に行われている 20 - tsc などの CLI が最大 2 倍高速化 - エラーのシンタックスハイライト改善 - custom test matchers と additional expect matchers の追加 等

Slide 21

Slide 21 text

21 - メリット - パッケージインストール、テストの速度に優位性がある - create-next-app の初期状態だけで差があったので、 大規模なプロジェクトだとより速さを体感できそう - 開発スピードの向上や CI の最適化につながる - バンドラー、テストランナー、パッケージマネージャーはどれも Webpack, Jest, npm と互換があり乗り換えコストを感じることがなく使える - 開発が活発 - 留意点 - 他ツールに比べて情報は少ない - Jest と完全互換ではない メリット・留意点

Slide 22

Slide 22 text

会社紹介 22 すべてのサービスとプロダクトに 「手ざわりのいいUI」を 新規事業やサービス開発 ⁄ プロダクト開発に取り組 むチームのサポートが得意な会社です。 それぞれのチームの考える「手ざわりのよさ」を一緒 に捉え、事業の成⻑にコミットします。 フロントエンド開発 UIデザイン / 情報設計 チーム / プロセス支援

Slide 23

Slide 23 text

23 私たち Gaji-Labo は、 事業を成長させる UI を作ります。 少しでも興味を持っていただけましたら、気軽にお問い合わせください。 お仕事のご依頼・ご相談 採用に関するお問い合わせ サービス案内ページ https://www.gaji.jp/services 採用情報ページ https://www.gaji.jp/recruit

Slide 24

Slide 24 text

24 ご清聴ありがとうございました!

Slide 25

Slide 25 text

参考URL 25 ● Bun公式サイト: https://bun.sh/ ● Bun公式ドキュメント:https://bun.sh/docs