$30 off During Our Annual Pro Sale. View Details »

ゴーファーくんたちと辿るJavaScriptの潮流/tide-of-javascript

 ゴーファーくんたちと辿るJavaScriptの潮流/tide-of-javascript

ミニ勉強会の資料です。

iwasiman

May 23, 2023
Tweet

More Decks by iwasiman

Other Decks in Programming

Transcript

  1. 先端技術勉強会 技術講習会
    2023/5
    @iwasiman
    Advanced
    -STUDY GROUP-
    第7回 ゴーファーくんたちと辿る
    JavaScriptの潮流
    Technology
    TECH-SESSION

    View Slide

  2. 2
    この技術講習会(先端技術勉強会)について
    ゆるくやっていくので、気軽にいきましょう!
    ⚫ 新年度開始、メンバー15人に増加。グループを超えて部門の活動となりつつあるので、
    今まで通り続けていきます!!
    ⚫ 頻度は不定、基本1H+α、だいたい夕方にやっています。
    ⚫ とりあえず始めてみて様子を見ながら続けます。
    ⚫ 説明中も適宜ブレイク(間)を挟むので、リアクションはその都度音声でもチャットでもOKです!
    ⚫ テーマはフリー、参加者から聞いたりして決めていきます。
    ⚫ 次回テーマは [いよいよPythonかも?] ,[フロントエンドを題材に前後編で資料作成中] 。
    その後のテーマ候補も募集中です!
    ⚫ 皆さんが講師をしてくれるのも大歓迎です!
    第1回 ゴーファーくんと学ぶGo言語の世界 [再開催中]
    第2回 AWSの基本情報の歩き方
    第3回 ゴーファーくんと学ぶAWSサーバーレスの世界
    第4回 ゴーファーくんと辿るプログラミング言語の歴史 [再開催中]
    第5回 ゴーファーくんたちと学ぶRust言語の世界 [再開催中]
    第6回 ゴーファーくんと探るMendixの有用性
    第7回 ゴーファーくんたちと辿るJavaScriptの潮流 ★今日はここ★
    第8回 ゴーファーくんたちと辿るフロントエンドの潮流 (テーマが大きいので後編)
    第X回 某先生がPythonの機械学習コンペ(Kaggle)の話をいつか語ってくれるのでは…?

    View Slide

  3. 第7回
    ゴーファーくんたちと辿る
    JavaScriptの潮流
    目的: 変化の大きいJavaScript・フロントエンドの
    歴史とキーワードを全体の視点から概観し、
    理解の助けにしてもらう。
    前編:まず今回はJavaScript実行環境とツールチェーン
    中心に概観からスタート
    後編:TypeScriptやReact、その他の話題
    なんとなく案内役
    ゴーファーくんと
    フェリスさんです

    View Slide

  4. 1. JS周辺の歴史概観①②
    2. JavaScript実行環境(ランタイム)
    3. 補足:バックエンドでNode.jsを使うとき
    4. ツールチェーンの位置づけ
    5. モジュール、パッケージ管理
    6. トランスコンパイラ
    7. モジュールバンドラー
    8. ラップした仕組み
    9. フォーマッター、リンター
    10.フロントエンドのテストの仕組み
    11.おまけ:各言語の実行速度差イメージ(再掲)
    12.本日のまとめ
    ゴーファーくんたちと辿る
    JavaScriptの潮流

    View Slide

  5. 5
    1. JS周辺の歴史概観① ブレンダン・アイクさん
    Netscape社→Mozilla社
    CTO/CEO→Brave社
    ◆ [1995] インターネットの夜明けの時代。ブラウザのNetscape Navigator 2.0上で動く言語としてブレンダンさんが
    僅か10日(!)で開発。最初の名前はMocha, LiveScript。当時Sun Microsystemsと協業しておりJavaが注目されていたため、
    あやかってJavaScriptに改名。20年以上にわたる誤解の元が始まる…
    ◆ [1997/6] 標準化団体ECMA Internationalによる標準仕様ECMAScript (エクマスクリフ゜ト)のバージョン1登場。1998,1999にv3まで。
    この仕様をブラウザベンダー各社が実装+独自拡張したのがJavaScript言語となる
    ◆ [1998] Microsoft、Windows 95では別途配布していたInternet ExplorerをWindows98では無償で標準搭載。一気にシェアが広がり、”ネス
    ケ”vs”IE”の第一次ブラウザ戦争勃発。その後2004年にIEの勝利で終わる。2003年にNetscape社解散…
    ◆ [90年代後半~ゼロ年代前半] JSの黎明期。日本でも「ホームページ」のブーム~ブログやSNS、徐々にWebアプリ高度化。ダサめなページ
    の装飾に使われたりセキュリティホールが何度も見つかったりで、JSには“素人向けの低俗言語と”いうマイナスイメージが。不遇の時代…
    ◆ またブラウザベンダー各社は独自にJavaScriptを拡張、クロスブラウザー問題が大きくユーザーも開発者も困る。特にIEが独自拡張が多く、
    独自技術ActiveX採用など。Windowsの独占禁止法訴訟などと絡んで「悪のMS帝国」のイメージの元凶のひとつに
    ◆ [ゼロ年代前半] ECMAScript4、ベンダー各社の対立や仕様の複雑化が原因で仕様を放棄。混乱の時代が続く…
    ◆ [2005] ブラウザから非同期通信しつつ動的に画面を再構築できる手法、Ajax(Asynchronous JavaScript And XML, エージャックス)が名付けら
    れ、既存ブラウザ技術で実現可能なのが認知。Googleマップに世界が驚く。“フロントエンド元年”。JavaScriptの復権がここから始まる…!
    ◆ [2006] prototype.js、Dojo Toolkitなど当時の技術で作られたJSライブラリに並び、jQueryが登場。その後2010年代まで長く使われる
    ◆ [2008-] HTMLの新仕様HTML5に各ブラウザが先んじて対応開始。現在位置の取得、画像描画、ファイルアクセス、履歴APIなど
    JSでやれることが増えてくる。正式勧告は2014。なお2019-はバージョンを廃止してHTML LS(Living Standard)が仕様の正式名称
    ◆ [2008] 後に覇権を取るブラウザChrome登場。高速動作するJavaScriptエンジンV8搭載、Node.jsにも受け継がれる
    ◆ [2009] JS実行環境、Node.jsが登場、遂にブラウザを超えてバックエンドでも動くようになる。発展中だったライブラリが
    Node.js同梱のパッケージ管理システムnpmで管理できるようになり、オープンソースで大いに発展。この年ECMAScript5も策定
    IE4
    IE7(2006),
    8(2009)の頃
    ネットで色々画像が出てく
    るが、実はJavaScriptには
    公式ロゴがないそうです

    View Slide

  6. 6
    1. JS周辺の歴史概観②
    ◆ [2010頃~] iPhone登場が2007、日本発売が2008、スマホ・タブレットブーム。ゼロ年代を風靡したRIA(Rich Internet Application)技術…
    FlashやSilverlightが徐々に衰退。HTML5ベースのJS+Ajaxベースの通信で作る仕組みがSPA(Single Page Application)の名付けで徐々に認知
    ◆ [2010] 当時のJSの問題を解決したAltJS言語CoffeeScriptのv1。特にRuby界隈で一時期人気となるがJS自体の発展と共に不要になり滅びる
    ◆ [2011] Google、当時のJSの抱える問題を解決する新たなAltJS言語Dart発表。Chromeに搭載しJSを駆逐する野望…は
    叶わず、クロスプラットフォーム開発FWのFlutter内でのみ生き残る
    ◆ [2012] 大規模化するJS開発で型が必要なことに人々が気付く。MicrosoftよりAltJS言語TypeScript言語登場、2014にv1
    ◆ [2012] Angular、[2013] React、[2014] Vue.jsと、現在も主流のフロントエンドのフレームワーク群が出揃い、それぞれ発展。
    一方、一時期流行ったり流行らずに消えていくフレームワークやライブラリも色々…
    ◆ [2014] 第二次ブラウザ戦争終結。IEは6辺りから停滞、Mozilla Firefox、Google Chrome、AppleのSafari、Operaの5勢力。
    Chromeが5-6割のシェアを取り圧勝。その後主要ブラウザはChroniumベースに
    ◆ [2015/6] クラスやモジュール制導入、letとconstの変数宣言、新しい関数構文など大幅変更の入ったECMAScript6 (ES6, ES2015)登場。
    他の本格言語にようやく追いつき、ここからを「モダンJavaScript」と称する。以降ES2016, ES2017…のように西暦表記、毎年6月に更新
    [2015/11] 同年にMicrosoft謹製のVisual Studio Codeがリリース、強力サポートでフロントエンド開発ではほぼ一択に
    ◆ [ES6以降] JavaScriptエコシステムの中で、本資料で紹介するような様々なライブラリが発展し変化を続けていく。日本でもモダン技術として
    注目、「フロントエンドエンジニア」が職種として認知。先進的なインターネット系やベンチャー系企業でよく使われブームに
    ◆ [2020/5] Node.jsの後を継ぐ2018登場のJS実行環境Deno、v1.0に進化
    ◆ [2022/6] IEが遂にサポート終了。世界のエンジニアとデザイナーがクロスブラウザ問題の苦しみから解放。Edgeも2020からChroniumベース
    ◆ [現在] JavaScriptはES2022、TypeScriptはV5.0。FWではReactが首位。相変わらず変化が激しいが、2010年代前半の混乱期、
    ES6後の急発展の頃に比べると開発環境も成熟してきたといわれる。商業本も揃ってきた。新しい考え方の技術も登場
    ◆ [2023/2-] おまけ:Chromeの後塵を拝していたMicrosoft EdgeとBing、ChatGPTベースのAIという最大伏兵をもって復活開始…!
    Angular
    →1995年から28年間にわたる混迷と復活の歴史!
    インターネット、ブラウザの進化とも大きく関係。
    この「歴史的経緯」が、様々な周辺技術の根本になっている

    View Slide

  7. 7
    2. JavaScript実行環境(ランタイム)
    ◆Node.js (ノード・ジェイエス) [2009- 2023/4 v20.0.0]
    ◆ Chromeにも内蔵されているV8エンジンを使ったランタイム。2010年代前半から市民権を獲得し現在の主流に。
    ◆ シングルコア、シングルプロセス、シングルスレッドで動作:プロセスが全体で1つ、スレッドも1つなので軽量。
    ◆ イベントループとNon-Blocking I/O:無限のイベントループがずっと稼働、複数リクエストが飛んできても片方の終了を待たずに処理可能。
    イベントを分割してキューに貯め、細切れに処理。シングルスレッドでも性能を最大限発揮
    ◆ 標準モジュール(Core API):標準のJavaScriptにないファイルアクセスなどのAPIを用意。
    ◆ 開発用のWebサーバーも立てられたり、諸々の機能で開発をサポート。Node.js自体の中身はC++/JavaScript製
    ◆Deno (ディノ) [2018/8 v0.1- 2020/5 v1.0 - 2023/4 v1.32.5]
    ◆ Node.js作者のRyan Dahl氏本人が2009年当時の状況に基づいて作ったNode.jsの10の反省点を活かし、ゼロから構築し直した実行環境。
    ◆ ファイルやネットワークアクセスはデフォルトは制限ありでセキュア、高速、シンプル。Rust言語製+外縁部はJavaScript
    ◆ モジュール化は複雑化しがちなpackage.json, node_modules/ を廃止、内部でキャッシュ。コード上のimportはURL記述式でシンプルに
    ◆ 後述のtsc, SWC内蔵で最初からTypeScript対応、パッケージ管理、コマンドで実行できるフォーマッター、リンター、テストフレームワーク、
    開発エディタ用のLanguage Server Protocol(LSP)内蔵と便利機能を最初から全部載せ
    ◆ v1.25 [2022/9]からNode.js互換開始、v1.31で移行がさらに容易に。ライブラリの公開先はnpmとは別
    ◆ と改良型なので良いことづくめだが、Node.jsが普及しきっているので今後主流になるかは不明…
    ◆Bun (バン) [2021- 2023/4 v0.5.9]
    ◆ 別の実行環境でこちらはZig言語製。丸いパン?bundleのbun? で中華まんが目印、開発会社のOven社を立ち上げて進化中。高速を謳う
    ブラウザの中でしか動かなかったJavaScriptを、コマンドラインからでも動かせるようにする仕組み。他のバックエンド言語と同様にネットワークや
    ファイルアクセス、DBアクセスが可能に。これによってパッケージ管理やCLIツール、ビルド、Webサーバー実装、バックエンド(サーバーサイド)の
    フレームワークなどが実現可能に。Node.js登場後、フロントエンドの発展に大きく貢献した。
    →バックエンド:必須。フロントエンド:ビルド等で必要なので結局必須。
    今もNode.jsがほぼ主流だが進化中、中身に他言語を採用したり
    「ツールチェーン」の充実、
    このへんがGoやRustと似た
    アプローチ
    2009
    Zig: Rustと似た立ち位置
    のちょっとマイナーな言語
    ライアン・ダールさん
    その後リーダーを後進
    に譲っている
    コードをparse、実行時にそ
    の部分をコンパイル。インタ
    プリタとコンパイラの中間?

    View Slide

  8. 8
    3. 補足:バックエンドでNode.jsを使うとき
    ◆シングルコアである:
    ◆ チップ内にCPUをいくつも載せたマルチコアなマシンでは実はリソースを活用しきれない。clusterというモジュールで対応可能
    ◆シングルプロセス・シングルスレッドである:
    ◆ ユーザA,Bが同時リクエストするとリクエストが混じり、対応する関数が同時実行、同じ変数にアクセスしたりする。キャッシュ事故に注意
    ◆ ここから、classで状態を内包した設計、classの多用は避けた方がよいとされる。グローバル変数書き換えも全リクエストに影響
    ◆ 他の言語や技術では1リクエスト=1プロセスだが、複数リクエスト=1プロセスに割り当てとなる。そのプロセスがエラーでクラッシュすると
    全リクエストがエラー。誰かがエラーになったら、全ユーザーが見ているブラウザが一斉に503になるイメージ
    ◆ 無限に動いているイベントループは、同期処理をやるとその間停止し新規リクエストを受けられなくなる。巨大なJSONのparse、readFileSyncを
    使ったファイルの同期的読み込み、長いループ処理などが同期処理で要注意
    ◆ Linux上で動かす場合は、1プロセスごとに開けるファイル数設定(ファイルディスクリプタ)は多めにしておく必要アリ
    ◆非同期のイベント駆動型ランタイムである:
    ◆ バックエンドの関数内で A⇒重いB⇒C と書いて実行すると A⇒C⇒Bの順に処理終了したりする。async/await記法などで対応
    ◆ 標準モジュール(Core API)が提供する関数は一部 同期実行/非同期実行 の両方Verがある
    ◆ブラウザ上で動かす場合(=フロントエンド)と若干違いがある:
    ◆ windowやdocumentオブジェクトがなく、逆に標準モジュールでファイルアクセス等が可能
    ◆ 上記のリクエストが混じる話や長い同期処理を避ける話はバックエンド特有、ユーザー1人しか実行しないブラウザ上にはあまり影響しない
    ◆ 沢山のJSファイルをまとめるモジュールバンドラー(後述)はフロントエンドでは必須だが、バックエンドのNode.jsでは実は不要(TypeScriptを導
    入すると要ビルド、結局だいたい必要)
    プロセス:マシン上で動いているアプリケーションやプログラム。メモリは共有しない
    スレッド:各プロセス内で命令を逐次実行する処理単位。メモリを共有する
    マルチプロセス・マルチスレッドで動く他の言語のWebアプリでは、 リクエストが来る→その
    都度1プロセス生成 でその時実行される関数は互いに混じらないのだが…
    →イベント駆動型でネットワーク処理に強い。その特徴を活かして大量アクセスが来ても
    同時に処理、リソースを効率的に活用。その一方で独特な所もあり、実装時に注意
    C10K問題 (C10K problem): Webサーバに大量アクセスが来るとプロセス数上限
    を超えたり処理切替のコストが掛かったりで、ハードウェア性能を活かしきれなくなり、
    遅くなる問題。Apacheでだいたいクライアント1万人前後で起こるのでこの名に。
    (ただし近年では解決されつつある) Node.jsはその仕組みでこの問題を回避した
    CPUリソースを大量消費する重い処理(動
    画のエンコードなど)は、Node.jsでも辛い
    といわれる。疎結合で外出しに

    View Slide

  9. 9
    これらを使いアプリ開発
    4. ツールチェーンの位置づけ
    いろんな
    パッケージ
    (≒モジュール,
    ライブラリ)
    を管理
    ファイル群をまとめる
    モジュールバンドル
    モジュール同士の依存性解消
    プロジェクト作成支援の
    「ボイラープレート」
    JavaScript実行環境 すべての土台
    (Denoは元からNode.jsよりカバー範囲が広い)
    JavaScript界隈は特に モジュール≒ライブラリ≒パッケージ が豊富で、あるモノとあるモノが同列だったり、含んでいて包含関係だったり、
    別のモノを中で呼んでいたり、置き換わる新しいモノが出てきたり、複数の役割を兼ねていたり…と関連がややこしい。
    開発に必要な一連の技術要素を「ツールチェーン」と呼んだりする。実体の基本はターミナルから動かすJavaScript製のCLIアプリ。
    (最近はJavaScriptよりも速い他言語の採用も)
    JS/TS→JSに変換
    トランスコンパイル
    AltJS言語

    型サポート
    コードフォーマッター
    静的解析のリンター
    テストの
    仕組み
    「ビルドツール」という言葉でまとめたり
    さらに抽象度を上げ、ツールチェーンを全部
    大統一しようというこころみも (まだフォーマッターとリンターだけらしい)
    バックエンドのFW群
    フロントエンドのFW群
    両方というアプローチも
    →エコシステムの新陳代謝、流行り廃りが激しいが、今も進化中…
    技術要素同士の位置関係をイメージすると理解の助けに
    開発に使う各種のツールチェーン
    開発対象の
    アプリケーション
    (詳細は次回)

    View Slide

  10. 10
    5. モジュール、パッケージ管理
    モジュール:「より複雑な構造を構築するために使用できる単位の集合」。プログラムを複数ファイルや別ディレクトリに分解・整理することで、複雑さを
    軽減し再利用可能にして扱いやすくしていくのが「モジュール化」。プログラミングの基本概念のひとつ。
    Javaのパッケージ、C#/PHP/Ruby/Pythonの名前空間(namespace)、Go/Rustのモジュール。ほぼすべてのプログラミング言語が備えている。
    JavaScriptは当初ブラウザの中で小さな処理を行うことしか想定していなかったため、このモジュール化の概念がなかった。ES6でようやく導入。
    ※空のオブジェクト {} を使って名前空間のようなものを疑似的に使う方法は過去あったが、もう使われない
    ◆モジュール化の仕組み:歴史的経緯からまだ2種類ある
    ◆CommonJS (正式にはCommonJS modules) [2009-]
    ◆ 標準未策定の頃にNode.jsが策定した仕組み。
    ◆ 書き出し側:export.sampleFunc = …..; / 読み込み側: require(‘./sampleFunc’); //ファイル拡張子をつけない
    ◆ 拡張子は *.js か *.cjs (*.js以外はビルド必要)
    ◆ 公開されているライブラリではまだ使われていたりで、Node.jsアプリはまだこちら
    ◆ES modules, ESM (正式にはECMAScript modules) [2015-]
    ◆ その後JS標準仕様のES6(ES2015)で策定された方式
    ◆ 書き出し側: export const sampleVal = 1; / 読み込み側: import {sampleVal} from ‘/sampleVal.mjs’; // 拡張子あり
    ◆ 標準の拡張子は *.mjs (Node.jsなら動くがブラウザで動かすならビルド必要)
    ◆ フロントエンドのReactのコードなどではだいたいこちら。Denoはこちらのみ
    定義が曖昧ですが専門書によると…
    「モジュールが物理的にパッケージ化されたもの」がコンポーネント
    (JavaのjarやC#のdllが相当)
    「コードをモジュールでくるんだもの」がライブラリ
    コード<モジュール<ライブラリ<コンポーネント<1つのアプリ
    という粒度で良さそうです
    ◆パッケージ(≒モジュール、ライブラリ)管理の仕組み
    ◆npm(Node Package Manager): [2010-] Node.jsに同梱。npm(エヌピーエム)
    が正式名称の模様。広く使われている
    ◆Yarn: (ヤーン)[2016-] Facebook(現meta)発、npmと互換性を持ちより高速と話題。しかしnpmもその後進化したので大差なし?
    ◆pnpm: [2016-] performant npmの略。こちらも高速、ディスク容量効率の良さを謳う →歴史的経緯から、選択肢が複数
    あったり隆盛があったりする
    Node.jsでのディレクトリ構成:
    プロジェクト名/
    読み込む側のアプリのコード.js
    node_modules/
    書き出し側モジュールA/
    書き出し側モジュールB/

    package.json // 設定ファイル
    package-lock.json // ロック管理
    //他、ライブラリの設定ファイル等々
    昔はBower [2012-] という
    ものもあったが廃れた…
    JS実行環境でDenoなら最初から仕組みが入っているので、これらは不要

    View Slide

  11. 11
    6. トランスコンパイラ
    コンパイル(compile): ある言語のソースコードをより低水準の言語(実質は機械語や中間言語、実行形式など)に変換すること
    トランスコンパイル(transcompile): ある言語のソースコードを同水準の別の言語に変換すること。略して「トランスパイル」、実質
    「コンパイル」と呼ぶことも。現在では、言語では実質JavaScript/TypeScript/Dart -> JavaScript への変換で使う。
    ビルド(build): コンパイルもしくはトランスコンパイル+αの作業で、アプリケーションが動く状態のものを作ること。
    αでコンパイルされたものをまとめたり(リンク)、設定ファイルの変換をしたり、HTMLや画像やCSSを組み込んだり、諸々の作業が入る。
    フロントエンドではコマンド実行などで「ビルド」の工程を行うと、その背後にトランスコンパイル+後述のモジュールバンドル+その他作業 が
    入っていることが多い。
    Reactで使う
    JSXファイル
    ES6以降の
    新しいJS
    ES6以前の
    古いJS









    ◆Babel: [2014-] 旧称6to5。便利な構文の入ったES6(ES2015)以降のJSを古いJSに変換したり。まだIEが滅ぶ前に重宝。
    後述のReactで使うJSX構文も変換できる。中身はJavaScript製。~2015頃まで、今でも他のツールの裏で動いていたり
    ◆tsc (TypeScript Compiler): [2012-] TypeScriptをインストールすると入っているトランスコンパイラ。
    > tsc aaa.ts → aaa.js で単体では変換。他のツールの裏で呼ばれたり
    ◆esbuild: 2023/3でv0.17。トランスコンパイル+モジュールバンドル両方というアプローチ。
    従来より10倍~100倍を謳っており、中身がGo言語製! 進化中…
    ◆SWC(Speedy Web Compiler): 2023/3でv1.3.42。Webプラットフォーム、現状トランスコンパイラ用途でバンドラーも
    開発中。Babelの20倍高速を謳い、Vercel社製。実行環境のDeno、バックエンドのFWのNext.jsの内部でも。今後の有力
    株…? 中身はRust言語製!
    →開発時はビルド作業の裏で動いていたりするが、進化が続いている。
    かつてはこれらのツール自体もJavaScriptで動いていたが、ビルド高速化
    の動きが。Go、そしてさらに速いRust言語の波が徐々に来ている…

    View Slide

  12. 12
    7. モジュールバンドラー
    モジュールバンドラー(module bundler): ブラウザでGETリクエスト発行、HTMLやファイルを読み込んで表示する際、複数の.jsファイル
    に分散しているとサーバーとのやりとりが増えて遅くなる。ES modulesで分割されていても同じ。事前にモジュール同士の依存関係を解決、
    中身の変換や最小化(minify)など諸々をうまいことやり、大きな一つのJSファイルだけにまとめてくれる。略して「バンドラー」とも。
    開発中は素早く画面表示をしてくれる開発サーバーの役割をしてくれるものも。(ホットリロード)
    アプリ側の変換
    後のJSコード
    呼び出している
    様々なモジュー
    ル群のコード




    ReactのFW
    自体の変換後の
    JSコード 最小限の
    ファイル数に
    まとめられた
    巨大な
    バンドル.js
    昔はBrowserify, Grunt, Gulp など
    もあったが廃れた [~2010年代半ば]
    ◆Webpack: [2014-] 2016~からの主流。様々なローダーで拡張可能、
    CSSや画像も取り込める。中身はJavaScript製でNode.js上で稼働。
    ◆Rollup: [2010年代後半] Webpackと違いES6(ES2015)前提、モジュール化でES modules を使う
    同種のツール。Facebookで採用され一時期話題に
    ◆Parcel: [2021 v2] Webpackは設定ファイルが煩雑なところ、手軽に使えるようにしたシンプル方向の
    ツール。それほど人気が出なかった?
    ◆Turbopack: [2022/10] Vercel社で発表されたWebpackの後継となるツール。同じ人が携わる。
    Webpackの700倍高速を謳い大規模アプリにも対応。バックエンドのNext.jsにも搭載。
    α版で進化中、これも中身がRust製!
    JavaScript(ECMAScript)の仕様面での検討:
    Dynamic import: 初期表示時に一度に全部でなく、必要になった時にモジュールを読み込む (ES2020)
    →FWのNext.jsやビルドツールのViteでは既に導入
    Bundle preloading: 複数ファイルをまとめてブラウザで送る (検討中)
    Module declarations: 複数モジュールを変換なしでJSコードにまとめる (検討中)
    →バンドラーがいらなくなる未来もあるかも?
    →将来も検討されているが、現在はバンドラーで
    まとめたJSファイルを一度で読み込む方式がまだ必要。
    アプリ大規模化に伴いバンドル速度が重要、Rustが注目
    バンドル.js
    HTML
    HTTP GET
    1回で済む!
    画像やCSS

    View Slide

  13. 13
    8. ラップした仕組み
    ボイラープレート(Boilerplate): プロジェクト開始時に追加する定型テンプレート類のこと。テンプレートは中身を埋める必要
    があるのが違うらしいが、だいたい同じ意味。「ボイラープレートツール」のようにしてフロントエンド、Web制作で時々出てくる。
    ◆Create React App(CRA): [2016-] Reactの新規プロジェクト作成支援ツール。裏でReact本体を入れ、Babelを
    入れ、Webpackを入れ、ESLintも入れ…と環境構築をよろしくやってくれる。設定ファイルが隠蔽され弄れ
    なかったりビルド時間が増えたりで、近年では外すケースも出てきた。
    ◆Vue CLI: [2015-] FWのVue.jsで、同じようなことを最初にやってくれる対話型ツール。こちらはVue 3でも現役。
    複数の役目を担う仕組みは「ビルドツール」という呼び名でまとめることが多い。上の2つも範疇に含めたりして区別は曖昧。
    ◆Vite: [2020-] (ヴィート) Vue.jsの作者Evanさんが作ったビルドツール。プロジェクト作成でライブラリを自動で入れ、
    buildコマンドで高速に開発サーバー立ち上げ。中でesbuildを使っている。FWのVue.jsにもReactにも使える。
    Webpackの代替に近い。
    ◆Snowpack: [2020-] 依存するライブラリ群を最初からDLしてバンドラーを不要にしようというアプローチ。
    中でesbuildを使い、こちらもビルド時間が短縮。Webpackの代替に近い。
    ◆Rome: [2020発表-2023 v12で開発中] 様々なツールチェーンの組み合わせが大変すぎるので、ゼロから開発し直した
    大統一ツールチェーンで全部任せられるようにしようという壮大なアプロ-チ。名だたるOSSの開発者たちが集まっ
    ている。当初はJavaScript→途中からRustで作り直し。将来全ての道はローマに通ずるようになる…かは全く不明。
    トランス
    コンパイル
    モジュール
    バンドル
    その他
    諸々
    新規作成
    支援
    「ビルドツ―ル」でまとめたり



    トランスパイラの SWC、モジュールバンドラーのTurbopack、
    バックエンドのFWの Next.js がVecel社製。互いに統合の動
    きもあり、”Vercel勢”として有力
    →個々のツール、抽象化を進め包括したツールの
    両方が進化中。未来がどうなるかは不明…
    さらにRomeで大統一の野望も…

    View Slide

  14. 14
    9. フォーマッター、リンター
    フォーマッター(Formatter): インデント/タブの桁数統一、字下げ、スペース空け等々のコード整形。ほとんどのプログラミング言語で外部のライブラリ/エディタの機能/言語
    自体に内蔵 など各種方法で備えている。
    JavaScript界隈では、 Node.jsでは別に用意が必要。後発のJS実行環境Denoは自前で用意。ツールチェーン大統一を目指すRomeも高速を謳うフォーマッターを用意。
    ◆Prettier : [2017- v1,現v2.8] (プリティアー)
    単体ツールも可能、VSCodeの拡張機能でも定番。HTMLやJSONなども含み
    大抵の言語に対応。言語ごとに設定を変えたり、保存時/コマンド実行時での実施の切り替えなど各種設定可能。
    以前は他にも幾つかあったが、だいたいPrettierが主流で用が足りるようになってきた。
    リンター: フォーマッターと似ているが、バグの原因になりそうなコード(変数の未初期化、使っていない変数や関数などなど)を指摘して修正を促してくれる機能。JavaやC#
    の時代は「静的解析ツール」とよく称された。近年ではこの解析の動作をリント(lint)、リントしてくれるツールをリンター(linter)と呼ぶことが多い。カタカナ、英語両方使う。
    Lintは洗濯時の「糸くず」「綿ぼこり」の意、そこから転じてプログラムの中のごみを取るイメージで。JavaScript界隈でもリント/リンターと呼ぶ。
    コンパイル型言語では、かつてはコンパイルは通るが直した方がよいコードの類をリンターが指摘してくれる形だった。近年はコンパイラーの進化に伴い、コンパイルエラーで弾
    けることも増えている。
    ◆ESLint : [2015- v1,現v8] (イーエスリント) ECMAScript Lintの略。定番。npmからインストール、プロジェクト直下の設
    定ファイルに判定ルールや対応ESバージョンを書いたりして、コマンドで実行したりCI/CDの工夫でコミット時に
    自動で走らせたり。単体ツール+VSCodeの拡張機能の両方を入れると、画面上で指摘を直せたり。
    Prettierとの連携には追加でパッケージが必要。言語でTypeScriptを使う際も追加で幾つかパッケージが必要。
    →かつては他にもあったが、現在はPrettier+ESLintが主流。
    フォーマッターは今後変わる可能性もあるが、リンターは当分
    ESLintのままだと言われる
    VSCode拡張機能
    のアイコン
    よりモダンな言語(Go, Rustなど)
    になると最初からフォーマッター
    が入っていたり、コンパイルで弾
    けることが増えたり進化

    View Slide

  15. 15
    10. フロントエンドのテストの仕組み
    モダンな開発では 「ユニットテスト」というと一般的にはこれらの仕組みを使った関数やクラスのレベルのテストを指す。
    「テスト用ライブラリ」「テスティング・フレームワーク」「テストランナー」など呼び方が様々だが、大まかには同じような意味。
    Node.jsではプロジェクト配下の設定ファイルpackage.jsonに設定を書いておいてコマンドで >npm test などで実行。
    ◆②ユニットテスト (Unit Test): 独立した関数、(+コンポーネント)でのテスト
    ◆ Node.js自体 : v18[2022/4]から標準モジュールにtest,assertモジュールが追加。基本的な比較は実施可能。より本格的なテストは他の仕組みへ
    ◆ Jest: [2019-] Facebook(現meta)発。各種FWにも対応、前処理や後処理、モックの利用など各種機能豊富。JS/TS全体のユニットテストで今の主流
    ◆ Mocha: 同じくテスト用FW。他にもJasmine, Chai, Karma, Enzymeなどいくつかあるが、進化と共にだいたいJestで済むようになってきた
    ◆③結合テスト (Integration Test): コンポーネントや関数を組み合わせた機能をテスト、厚めがよいとされる
    ◆ Testing Library: [2018-] 各種FW用のライブラリを有しており、例えばReactならReact Testing Library(RTLとも)。jsdomというDOM要素を
    エミュレートしてくれるライブラリを内部で呼んで、Reactコンポーネントのテスト(ボタンを押すと持っている値がこう変わる、など)ができる
    ◆ スナップショットテスト: Reactコンポーネントが描画するHTMLを文字列として出力、想定通りかテストするというアプローチ。
    react-test-rendererというものがあったが、上のTesting Libraryで同じようなことができるようになり、公式でも推奨
    ◆④E2Eテスト (End to End Test) : 端から端まで、ユーザーがブラウザで操作するのを想定したテスト
    ◆ Cypress: [2017 v1] JSコードで操作を書いて実施するE2E用の大がかりな仕組み。対象ブラウザ内でアプリと同じランタイムで動作
    ◆ Puppeteer: [2018 v1] Node.jsで動くライブラリ、Chrome, FireFox用。”操り人形師”の意
    ◆ Playwright: [2020 v1] Microsoft製、上のPuppeteerと同じ開発陣。Chrome, Safari, Firefox用。コードを書く→Chrome系ブラウザに
    用意されている外部からの操作・通信プロトコル経由→対象ブラウザを直接操作。”劇作家”の意
    ◆ Selenium WebDriver: [2002-] JS問わずブラウザ操作自動化でよく使われてきた古くからある技術。コードで操作を書く→各ブラウザ用の
    WebDriverアプリを操作→ネットワーク経由で間接的に対象のブラウザを操作
    Testing Trophy:
    React Testing Libraryの作者
    さんが提唱した4分類。
    ①Static: eslintなどの静的解
    析、TypeScriptの型チェック
    ②Unit, ③Integration, ④E2E
    の3つ: 本ページで解説




    →フロントエンド特有の分類があり、仕組みにも変遷が




    ユニット~結合で、UI表
    示の差分を取る「画像回
    帰テスト」のアプローチも

    View Slide

  16. 16
    11. おまけ:各言語の実行速度差イメージ(再掲)
    遅い..
    ガベージ
    コレクションの壁
    仮想マシンの壁
    インタプリタ型
    言語の壁
    最速!!
    JVM言語であるScala、Kotlinも大まかにはJavaと同程度と思われる。
    C#も、JVMと似た仮想マシンの仕組みの上で動いている。
    仮想マシンを使う言語~このインタプリタ型言語の壁までの間に、かなり大きい速度の差あり。
    Node.jsなどJS実行環境はコンパイル型とインタプリタ型の中間らしく、比較的速い。
    メモリ安全の防壁
    機械語
    機械語
    中間ファイル
    逐次実行
    メモリ操作の罠
    注:簡略化していますが、実際のプログラムの
    実行速度には、これら「~の壁」以外にも
    言語の仕組みなど様々な要素が関係します。
    主要言語の中では実は遅さが目立つ。
    Python→マシンコードへ変換するコンパイラ「Codon」論文
    発表、C++並みの速度とのこと [2023/3]
    バックエンドでJavaScript/TypeScriptを選ぶと…
    ★フロントエンドと同一言語でやれて頭の切り替え
    (≒コンテキストスイッチ)不要、JSの知識も活かせる
    →JSに強い人やフロントエンドの人が多い会社で採用
    一方、バックエンドに他の選択肢もある場合は…
    ★変化の大きいJS界隈に飛び込む必要アリ
    ★非同期コードなど独特な所も
    ★TypeScriptを使えば型サポートがあるが他の言語も
    同様、純粋な速度的にはもっと速い言語もある
    →優先度合いは他の言語と同等くらいかも?

    View Slide

  17. 17
    12. 本日のまとめ
    ◆JavaScriptの源流を辿るとインターネットの夜明けとブラウザ登場の頃から
    始まり、様々な技術が互いに影響しあいながら、現在進行形で発展が続いて
    います。
    ◆変化の激しい領域ですが、それぞれの技術キーワードの立ち位置や背景を
    踏まえながら見ていくと、理解の助けになります。
    Creative Commons Attributions 3.0
    The Gopher character is based on the Go mascot designed by Renée French.
    などの話は次回に続く…!
    資料中の様々なロゴやマスコットはその言語や技術の公式・非公式のものです。書影はその書籍・雑誌のものです。
    たくさんあって迷っちゃうね
    JavaScript誕生の翌年[1996]の頃の
    Netscape Navigator 3.0 の画面
    インターネッツの夜明けの頃…

    View Slide