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

JavaScript エコシステムを維持する OSS の努力と課題

sosukesuzuki
November 27, 2021
8.2k

JavaScript エコシステムを維持する OSS の努力と課題

JSConf JP 2021 の基調講演として発表したスライドです。
https://jsconf.jp/2021/talk/javascript-maintaining-ecosystem-oss-struggles-and-challenges

sosukesuzuki

November 27, 2021
Tweet

Transcript

  1. JavaScript
    エコシステムを維持
    する OSS
    の努力と課題
    2021/11/27 JSConf JP 2021

    View Slide

  2. 自己紹介
    名前: Sosuke Suzuki
    学校:
    筑波大学 情報学群 情報科学類
    仕事:
    サイボウズ フロントエンドエキスパートチーム
    OSS: Prettier, Babel
    Twitter: @__sosukesuzuki
    GitHub: @sosukesuzuki

    View Slide

  3. 話すこと
    JavaScript/TypeScript
    の進化について
    JavaScript/TypeScript
    を扱うソフトウェアについて
    JavaScript/TypeScript
    への追従について
    OSS
    メンテナーの声
    ユーザーができること
    話さないこと
    Node.js
    や Deno
    、ウェブブラウザなどの実行環境の話
    V8
    や JavaScriptCore
    などの JavaScript
    エンジンの話
    React
    や Vue
    などの UI
    ライブラリ/
    フレームワークの話

    View Slide

  4. JavaScript/TypeScript
    の進化
    JavaScript
    は ES2015
    以降も進化し続けている
    TypeScript
    も進化を続けている

    View Slide

  5. ECMAScript 2016
    Array.prototype.includes
    [1, 2, 3].includes(2); // true
    Exponential Operators
    (2 * 2 * 2) === (2 ** 3); // true
    ` `

    View Slide

  6. ECMAScript 2017
    Async Function
    async function doSomething() {
    await somePromise;
    }

    View Slide

  7. ECMAScript 2018
    Object Rest/Spread Properties
    const { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
    x; // 1
    y; // 2
    z; // { a: 3, b: 4 }

    View Slide

  8. ECMAScript 2019
    String.prototype.{trimStart,trimEnd}
    const greeting = ' Hello world! ';
    console.log(greeting.trimEnd()); // " Hello world!"
    console.log(greeting.trimStart()); // "Hello world! "
    ` `

    View Slide

  9. ECMAScript 2020
    dynamic import
    import("https://example.com/module.js").then(m => {console.log(m.default)});
    BigInt
    const theBiggestInt = 9007199254740991n;
    const alsoHuge = BigInt(9007199254740991);
    import.meta
    console.log(import.meta.url);
    Optional Chaining
    foo?.bar;
    Nullish Coalescing Operator
    foo ?? bar;
    ` `

    View Slide

  10. ECMAScript 2021
    Logical Assignment Operators
    a ||= b;
    a &&= b;
    a ??= b;
    Numeric Separators
    const amount = 1_234_500; // 1,234,500

    View Slide

  11. ECMAScript 2022
    Class Fields
    class Foo {
    prop1 = 3;
    }
    Top-level await
    await somePromise;
    Object.hasOwn
    Object.hasOwn({ bar: 3 }, "bar"); // true
    Class Static Blocks
    class Foo {
    static {
    console.log("foo");
    }
    }
    ` `
    ` `

    View Slide

  12. TypeScript 3.7
    Assertion Functions
    function assert(condition: any, msg?: string): asserts condition {
    if (!condition) {
    throw new AssertionError(msg);
    }
    }

    View Slide

  13. TypeScript 3.8
    Type-Only Imports and Exports
    import type { SomeThing } from "./some-module.js";
    export type { SomeThing };

    View Slide

  14. TypeScript 4.0
    Labeled Tuple Elements
    type Range = [start: number, end: number];

    View Slide

  15. TypeScript 4.1
    Template Literal Types
    type World = "world";
    type Greeting = `hello ${World}`;

    View Slide

  16. TypeScript 4.2
    Leading/Middle Rest Elements in Tuple Types
    let foo: [...string[], number];
    foo = [123];
    foo = ["hello", 123];
    foo = ["hello!", "hello!", "hello!", 123];
    let bar: [boolean, ...string[], boolean];
    bar = [true, false];
    bar = [true, "some text", false];
    bar = [true, "some", "separated", "text", false];

    View Slide

  17. TypeScript 4.3
    override and the --noImplicitOverride Flag
    class SpecializedComponent extends SomeComponent {
    override show() {
    // ...
    }
    override hide() {
    // ...
    }
    }
    ` ` ` `

    View Slide

  18. TypeScript 4.5
    type Modifiers on Import Names
    import { someFunc, type BaseType } from "./some-module.js";
    ` `

    View Slide

  19. JavaScript/TypeScript
    を扱うソフトウェア

    View Slide

  20. JavaScript/TypeScript
    で Web
    フロントエンドを開発
    するとき
    宣言的に UI
    が書きたい
    React, Vue
    静的な型チェックがしたい
    TypeScript, Flow
    JSX
    や TS
    などの構文が使いたい
    Babel
    コードを静的に検証したい
    ESLint
    コードをフォーマットしたい
    Prettier, ESLint
    モジュールをバンドルしたい
    Rollup, webpack

    View Slide

  21. いろいろなソフトウェア
    目的に応じたいろいろなソフトウェアがある
    我々の Web
    開発は、そのようなソフトウェアに支えられている
    多くは OSS
    として開発されている
    JavaScript/TypeScript
    を扱うソフトウェア がある
    入力や出力が JavaScript/TypeScript
    のコード

    View Slide

  22. JavaScript/TypeScript
    を扱うソフトウェア
    ES2022:
    class Foo {
    static {
    console.log("hi");
    }
    }
    ES5:
    "use strict";
    function _classCallCheck(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
    }
    }
    var Foo = function Foo() {
    _classCallCheck(this, Foo);
    };
    (function () {
    console.log("HI");
    })();
    Babel

    View Slide

  23. JavaScript/TypeScript
    を扱うソフトウェア
    フォーマット前のコード
    :
    function foo() {console.
    log(
    "foo")}
    フォーマット後のコード
    :
    function foo() {
    console.log("foo");
    }
    Prettier

    View Slide

  24. JavaScript/TypeScript
    を扱うソフトウェア
    main.js :
    import { add3 } from "./module_1.js";
    console.log(add3(3));
    module_1.js :
    export function add3(value) {
    return value + 3;
    }
    bundled.js :
    function add3(value) {
    return value + 3;
    }
    console.log(add3(3));
    Rollup/webpack
    ` `
    ` `
    ` `

    View Slide

  25. JavaScript/TypeScript
    を扱うソフトウェア
    規則に違反するコード
    :
    const foo = "foo";
    警告
    :
    'foo' is assigned a value but never used. (no-unused-vars)
    ESLint ( no-unused-vars )
    ` `

    View Slide

  26. こういったソフトウェアは JavaScript/TypeScript

    進化についていかなければいけない

    View Slide

  27. JavaScript/TypeScript
    の進化への追従
    JavaScript/TypeScript
    は進化し続けている
    それらを扱うソフトウェアは、当然それについていく必要がある
    新しい構文の解釈
    新しい言語機能のための機能追加や修正

    View Slide

  28. JavaScript
    の進化への対応
    JavaScript
    の言語仕様である ECMAScript
    は ECMA International
    の TC39
    が策定している
    https://github.com/tc39/ecma262
    機能ごとに仕様の提案を出し、それについて議論し策定される
    https://github.com/tc39/proposals
    提案の一覧と状況が載っている
    https://github.com/tc39/agendas
    TC39
    のミーティングのアジェンダ
    https://github.com/tc39/notes
    TC39
    のミーティングの議事録
    ECMAScript
    の仕様策定について

    View Slide

  29. JavaScript
    の進化への対応
    提案には 5
    段階の Stage
    がある
    Stage 0: Strawman
    Stage 1: Proposal
    Stage 2: Draft
    Stage 3: Condidate
    Stage 4: Finished
    次の ECMAScript
    に入る(
    一年に一回更新される)
    https://tc39.es/process-document/
    ECMAScript
    の仕様策定について

    View Slide

  30. JavaScript
    の進化への対応
    estree
    https://github.com/estree/estree
    JavaScript
    の AST
    の仕様
    acorn
    https://github.com/acornjs/acorn
    JavaScript
    で書かれた JavaScript
    のパーサー
    webpack
    や Rollup
    で使われてい

    espree
    https://github.com/eslint/espree
    acorn
    をラップしたパーサー
    ESLint
    のデフォルトパーサー
    ECMAScript
    への新しい構文への対応

    View Slide

  31. TypeScript
    の進化への対応
    TypeScript
    は Microsoft
    によって開発されている
    https://github.com/microsoft/TypeScript
    ECMAScript
    のような明確な仕様は存在しない
    新しいバージョンが出るときは Microsoft Developers Blog
    で Beta
    からアナウンスされる
    リポジトリをウォッチしても進捗状況がだいたいわかる

    View Slide

  32. TypeScript
    の進化への対応
    estree
    風 AST
    Babel
    と typescript-eslint
    は両方
    TypeScript
    のパーサーを持っている
    その AST
    はできる限り統一したい
    TypeScript Beta
    がアナウンスされた
    ら、estree
    っぽい TS
    用 AST
    を考え

    Babel
    チームと typescript-eslint
    チーム
    TypeScript
    の新しい構文への対応

    View Slide

  33. メンテナーの声
    メンテナーたちにいくつか質問してみた

    View Slide

  34. Nicolò Ribaudo
    Babel
    のメンテナーの1

    TC39
    にも参加している
    Record & Tuples
    など
    数学科の大学生
    Babel
    メンテナー

    View Slide

  35. Nicolò Ribaudo
    Q1.
    今 Babel
    が抱えている大きな課題を教えて下さい。
    A. Babel
    が開発されてから 6
    年になります。 他のいくつかの業界にとっては大した年数ではないかもしれま
    せんが、OSS
    の JavaScript
    ツールとしては、とても長いです。 過去に Babel
    で行われた設計上の決定は、い
    くつかの新しい状況に対応することを不可能にしてしまっています。 私達は、つねに安定性と進化の間の完璧
    なバランスを見つけなければいけません。 Babel
    の様々な部分を書き直す必要がありますが、破壊的変更を起
    こさないように注意してそれを行う必要があります。 私たちは、週に何百万回もダウンロードされるツールに
    おいては、私たちのプロジェクトの既存のあらゆる側面に依存する数多くのユーザーが存在することを学びま
    した。 このような制約は、絶えず登場する Babel
    を置き換えようとするコンパイラには存在せず、その点では
    容易なのだと思います。
    Babel
    メンテナー

    View Slide

  36. Nicolò Ribaudo
    Q2. Babel
    の仕事で、もっともやる気がなくなるはどんなときで
    すか?
    A. Babel
    での作業では、情熱ではなく雑用のように感じることがあります。 怒っているユーザーからの、必要
    な情報が不足したバグレポートを定期的に受け取ります。そのひとたちから、必要な情報を得るための作業に
    かなりの時間を費やしています。 この作業は、私のエネルギーを消耗させ、その日の Babel
    の仕事をやめたく
    なります。 そして同時に、目に見える結果がないため、何も達成できなかったように感じてしまいます。 OSS
    にとって Issue
    のトリアージは重要な仕事であることは忘れてはいけません。 しかし、疲れていたりやる気を
    失っていたりするときは、そんなに合理的には考えられないものです。
    Babel
    メンテナー

    View Slide

  37. Nicolò Ribaudo
    Q3.
    これから JavaScript Tools (Babel, webpack, ESLint, Prettier,
    …etc)
    はどのように進化していくと思いますか?
    A.
    最終的にどうなるかはわかりません。しかし、エコシステムがどのように進化していくかを見極めるには、
    この1
    年と次の1
    年が非常に重要です。 新しいツールの中には、現在のツールエコシステムのあらゆる側面を一
    つにまとめることに焦点を当てているものもあります。 たとえば、コンパイラ、バンドラー、リンター、タイ
    プチェッカーがそれぞれ存在していなくても、一つのツールだけでこれらのすべてをまかなえるかもしれませ
    ん。 他のツールの中には、代わりにツールレスの開発体験を提供しようとしているものもあります。 今後数
    年間でエコシステムがどのように成長していくのか、まだ想像できませんが、何が出てくるのかとても楽しみ
    ですね。
    Babel
    メンテナー

    View Slide

  38. Alexander Akait
    webpack
    のメンテナーの1

    webpack
    公式が管理しているプラグインやローダー
    webpack-dev-server
    や webpack-cli
    などの開発に必要なツール
    最近は swc
    の CSS
    周りの改善に取り組んでいる
    webpack
    メンテナー

    View Slide

  39. Alexander Akait
    Q1.
    今 webpack
    が抱えている大きな課題を教えて下さい。
    A.
    正直なところ、そんなに多くはないのです。 (
    ユーザーから見た問題の中で)
    おそらくもっとも重要なのは、
    JS/TS/CSS/HTMl/etc
    、client-server
    、Web Workers
    などの仕組みを理解していないことです。 これらはかな
    り基本的なものですが、残念ながら多くの人が知らない、もしくは理解していません。 バグはどこにでも起こ
    るものなので、それを悪いものだと言うべきではありません。これはどんなプロジェクトでも当たりまえのこ
    とです。 第二位は設定です。確かに webpack
    の設定は必ずしも簡単ではなく、不親切だと思うこともあるで
    しょう。 しかし、すべてのオプションが重要です。幸いなことに、webpack v4, v5
    では設定は良く機能して
    いて、ほとんどのオプションのデフォルト値が、ユーザーに合ったものになっているでしょう。 「大いなる力
    には、大いなる責任が伴う」。理解不足のため、開発者は誤った設定を行い、誤った設定はアプリケーション
    にバグをもたらします。ときには、原点に戻って理解することが重要です。
    webpack
    メンテナー

    View Slide

  40. Alexander Akait
    Q2. webpack
    の仕事で、最もやる気がなくなるのはどんなとき
    ですか?
    A.
    他の開発者からのヘイトです。webpack
    が生まれたのはかなり昔のことで、正直なところ、過去には自分
    たちにとって正しい解決策に見えたかなり悪い決断がいくつもありました。 しかし、これらの中には標準とな
    っている多くのアイデアに命を与えました。残念ながら、多くの開発者はこれを見逃しています。 たとえば、
    import styles from "style-loader!css-loader!modules!./styles.css";
    のように webpack
    では非常
    に読みにくく使いにくい構文になっていましたが、今では import style from "./style.css" assert {
    type: "css" };
    になりました。あと、 package.json
    の exports
    もそうです。以前も
    browser / main / moule
    がありましたが、それらを使用するとよく問題が発生していました。
    webpack
    メンテナー
    ` `
    `
    ` ` ` ` `
    ` ` ` ` ` `

    View Slide

  41. Alexander Akait
    Q2. webpack
    の仕事で、最もやる気がなくなるのはどんなとき
    ですか?
    A.
    そして最後に ESM(ECMAScript Modules)
    があります。webpack
    は最初に ESM
    での記述を可能にしたツー
    ルの一つで、エコシステムに大きな影響を及ぼしました。 他にもたくさんあって、全部はあげきれません。
    私は、あなたが webpack
    を憎むべきではないと信じています。 私達が高齢者を尊ぶように、みなさんも尊敬
    の念を示してくれると幸いです。
    webpack
    メンテナー

    View Slide

  42. Alexander Akait
    Q3.
    これから JavaScript Tools (Babel, webpack, ESLint, Prettier,
    …etc)
    はどのように進化していくと思いますか?
    A.
    他のツールが成熟するには長い時間がかかると思います。しかし、最近は swc
    や esbuild
    などの新しいツー
    ルが現れています。これらは開発者の新しいムーブメントです。 私自身、最近 swc
    への貢献をはじめました。
    これらのプロジェクトは、パフォーマンスを向上させるだけでなく、以前のようなミスを避けることもできる
    でしょう。
    webpack
    メンテナー

    View Slide

  43. ユーザーができること

    View Slide

  44. それぞれのソフトウェアの役割をきちんと理解する

    View Slide

  45. ソフトウェアの役割を理解する
    Next.js
    などの登場によって、webpack
    や Babel
    や ESLint
    などを直接触ることは少なくなってきている
    だからこそ、裏側に隠れているソフトウェアの役割について意図的に理解することが必要
    適切なバグ報告やバグ修正、機能追加ができるようになる
    自分たちの開発を助ける
    メンテナーの心も助けることになるかも

    View Slide