Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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 }

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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; ` `

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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"); } } ` ` ` `

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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];

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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 ` ` ` ` ` `

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

こういったソフトウェアは JavaScript/TypeScript の 進化についていかなければいけない

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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 の仕様策定について

Slide 29

Slide 29 text

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 の仕様策定について

Slide 30

Slide 30 text

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 への新しい構文への対応

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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 メンテナー ` ` ` ` ` ` ` ` ` ` ` ` ` `

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

ユーザーができること

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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