Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Prettier 3.0 の VSCode 拡張対応における技術的な意思決定~VSCode 拡...
Search
sosukesuzuki
September 06, 2023
1
1.8k
Prettier 3.0 の VSCode 拡張対応における技術的な意思決定~VSCode 拡張で dynamic import が動かない~
VSCode 拡張で dynamic import が動かない
sosukesuzuki
September 06, 2023
Tweet
Share
More Decks by sosukesuzuki
See All by sosukesuzuki
JavaScriptCoreのObject.groupBy/Map.groupByのバグを自分で報告して自分で直す
sosukesuzuki
1
400
「書いたJavaScriptがそのままブラウザで動く未来へ」スピーカーノート
sosukesuzuki
8
11k
ESM移行は無理だけどおれもSindreのライブラリが使いたい!
sosukesuzuki
2
1.1k
JavaScript エコシステムを維持する OSS の努力と課題
sosukesuzuki
14
9k
Prettierに従わなくてもいい場合
sosukesuzuki
7
3k
Prettier 2.0
sosukesuzuki
2
1.6k
Prettier の TypeScript 3.7 対応について
sosukesuzuki
0
370
Prettier のしくみ
sosukesuzuki
4
2.4k
Featured
See All Featured
For a Future-Friendly Web
brad_frost
175
9.4k
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.8k
A better future with KSS
kneath
238
17k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
191
16k
Statistics for Hackers
jakevdp
796
220k
Reflections from 52 weeks, 52 projects
jeffersonlam
346
20k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
Designing for humans not robots
tammielis
249
25k
Building Adaptive Systems
keathley
38
2.2k
Build The Right Thing And Hit Your Dates
maggiecrowley
32
2.4k
Fireside Chat
paigeccino
32
3k
Code Review Best Practice
trishagee
64
17k
Transcript
Prettier 3.0 の VSCode 拡張対応 における技術的な意思決定 ~ VSCode 拡張で dynamic
import が動かない~ 2023/09/06 nihonbashi.js
自己紹介 SUZUKI Sosuke • Ubie 株式会社プロダクト開発エンジニア • サイボウズ フロントエンドエキスパートチーム •
筑波大学 情報学群 情報科学類 B3 • Prettier メンテナー • Babel コミッター @__sosukesuzuki @sosukesuzuki
目次 1. Prettier 3.0 リリース 2. Prettier 3.0 はすべてが ECMAScript
Modules 3. prettier-vscode における ECMAScript Modulesの問題 4. 言語サーバーの開発と挫折 5. worker_threads による回避策 5. まとめ
Prettier 3.0 リリース
2023年7月5日、実に3年以上ぶりとなるPrettierのメジャーリリース Prettier 3.0 リリース
Prettier 3.0 リリース trailingCommaのデフォルト値がes5からallに Internet Explorer のサポート終了により、主流のウェブブラウ ザのすべてがtrailingComma: allのJavaScriptを解釈できる ようになった。
日本語とラテン文字の間にスペースを入れない Markdownのフォーマットで、日本語 /中国語とラテン文字の 間にスペースを挿入しないようになった。今回のリリースの中 で最も賛否が分かれるであろう変更。 .gitignoreのファイルを無視する .prettierignoreだけでなく.gitignoreのファイルもデフォルトで 無視するように。 --ignore-path=.prettierignoreをつければ今 まで通り。 *.d.tsファイルが本体パッケージに含まれる ライブラリとして使うときの型定義が本体パッケージに含まれ るようになった。 @types/prettier を別途インストールする必要 はもうない。 https://prettier.io/blog/2023/07/05/3.0.0.html Prettier 3.0 におけるユーザー影響が大きい変更4選
Prettier 3.0 はすべてが ECMAScript Modules
CommonJS から ECMAScript Modules へ Prettier 3.0 はすべてが ECMAScript Modules
• Prettier 2.x まではソースコードは CommonJS で書かれていた • Prettier 3.0 からはソースコードがすべて ESM になった ◦ 実行されるときもNode.jsのネイティブESM ◦ メリット ▪ (Prettierチームにとって)開発者体験が向上する ▪ Tree Shakingの精度が高くなる ▪ ビルドスクリプトの複雑さが軽減される ▪ Pure ESM パッケージのために使っていた workaround を除去できる ◦ dynamic import を使ってプラグインや設定ファイル (.prettierrc)を読み込む • 2.x ではrequireを使っている
CommonJS から ECMAScript Modules へ Prettier 3.0 はすべてが ECMAScript Modules
./node_modules/.bin/prettier ./bin/index.cjs ./internal/cli.mjs ./internal/internal.mjs 1. エントリポイントはCJSファイル 2. CLIの本体ファイル(ESM)を読み込む 3. コア実装(ESM)を読み込む 4. プラグインや設定ファイルも import で読み込む import(“./internal/cli.mjs”) import(“./internal/internal.mjs”) plugins .prettierrc import import
prettier-vscode における ECMAScript Modulesの問題
prettier-vscode prettier-vscode における ECMAScript Modulesの問題 • Prettierの公式VSCode拡張 • 正式な名前は「Prettier -
Code formatter」 ◦ 紛らわしいのでリポジトリ名から、 prettier-vscodeと呼ぶことにする • 開いているファイルをフォーマットしてくれる ◦ format on save を設定しておくと便利 ◦ Range formatting もサポートしている • なんとブラウザでも動く (= codespacesでも動く?)
prettier-vscodeのPrettier3.0対応 prettier-vscode における ECMAScript Modulesの問題 • Prettier 3.0からJavaScript APIはすべてPromiseを返す •
prettier-vscodeはPrettierのJavaScript APIを使うので、全部にawaitをつけて回る必要がある const formatted = prettier.format(text, options); const formatted = await prettier.format(text, options); Prettier 2.x Prettier 3.x
prettier-vscodeのPrettier3.0対応 prettier-vscode における ECMAScript Modulesの問題 • これくらいなら普通にサクッとやれば良い • シュッとやってBeta版を出してみた https://github.com/prettier/prettier-vscode/pull/2947
prettier-vscodeのPrettier3.0対応 prettier-vscode における ECMAScript Modulesの問題 • 本番ビルドした結果全然動いてなかった (debug モードだと動いていた )
• 調査の結果、dynamic importの実行が全部エラーになることがわかった ローカルで試したら 全然動かないです。多分 dynamic import が動いてな い...。 Prettierのビルドいじって頑張って みたけど動かない ...。 マジか
prettier-vscodeのPrettier3.0対応 prettier-vscode における ECMAScript Modulesの問題 ESLint の flat config も設定ファイ
ルを dynamic import してるはずだ けど、VSCode 拡張ちゃんと動いて いるよね。なんでだろう? たしかに 調べてみます
言語サーバーを使ったアーキテクチャ prettier-vscode における ECMAScript Modulesの問題 • vscode-eslintなどの一部のVSCode拡張は言語サーバーを使っている • VSCode拡張の本体は、その言語サーバーにとってはクライアントである •
クライアントと、別に立ち上がる Language Serverプロセスとが通信しあう ◦ LSP(Language Server Protocol) 言語サーバー vscode-eslint ESLint を実行してくれ foo.jsの3行目に ◯◯エラーが出てるよ
言語サーバーを使わないアーキテクチャ prettier-vscode における ECMAScript Modulesの問題 • prettier-vscode は言語サーバーを使わない • 全てを
VSCode 拡張本体の中で処理する prettier-vscode 今開いてるファイルに Prettierを実行して上書きす るぞ〜
言語サーバーからは dynamic import ができる prettier-vscode における ECMAScript Modulesの問題 • クライアント(拡張の本体)では
dynamic import ができない • しかし、言語サーバーからなら dynamic import ができる 言語サーバー VSCode拡張本体 foo.js dynamic import
prettier-vscode も言語サーバーがあれば dynamic import が使えるのでは? 😎
【余談】問題の原因を推測する prettier-vscode における ECMAScript Modules対応とその問題 • VSCode拡張クライアントでdynamic importしたときに起こるエラーは ◦ TypeError:
A dynamic import callback was not specified. • これは、Node.js の vm.Script 環境で dynamic import を呼び出したときに発生する ◦ つまり、VSCodeでは拡張を実行するときに vm.Script環境に隔離していそう • prettier-vscode開発中のデバッグモードではこの問題は起こらなかった ◦ 多分、デバッグモードではこの隔離が有効になっていない
言語サーバーの開発と挫折
prettier-vscodeにも言語サーバーを実装する計画 言語サーバーの開発と挫折 • dynamic importを使うために、eslint-vscodeと同じアーキテクチャに変更しようした • つまり ◦ 言語サーバーを導入し、 Prettierの実行はすべてサーバーで行う
◦ クライアントはそれを VSCodeに反映させるだけにする • しかし...
prettier-vscodeのメンテナが不在 😢
VSCode 拡張の経験者も 言語サーバーの経験者もいない 😢
挫折... 言語サーバーの開発と挫折 • イチから作れというのならまだ適当にやればよかった • が、prettier-vscodeの挙動を維持しながら言語サーバーを使ったアーキテクチャに移行するというのが 本当に困難だった ◦ 実装や仕様がわからないソフトウェアの挙動を維持しながらアーキテクチャを大幅に変えるのは一 般に困難な気がする
• 努力の残骸たち(マジで苦しかった) ◦ https://github.com/sosukesuzuki/vsce-doc-formatting-sample ◦ https://github.com/sosukesuzuki/prettier-language-server-vscode-client ◦ https://github.com/sosukesuzuki/prettier-language-server-deprecated • 言語サーバーを導入する方法は諦めた
worker_threads による 回避策
言語サーバーを使わずにdynamic importを実行する術 worker_threads による回避策 何も思いつかねえ ... VSCode拡張から新し いプロセス生やせばい けるらしいよ え?
child_processとかでプ ロセス作れば、そこから dynamic importできるら しい
worker_threads による回避策 worker_threads による回避策 • vm.Script環境ではdynamic importができない • が、vm.Script環境で新たにスレッドを立てれば、そのスレッド内からは dynamic
importができる ◦ (わざわざプロセスを作る必要はなかったので worker_threads を使うことにした) VSCode拡張 メインスレッド worker_threadで作った新しいスレッド foo.js dynamic import
これしかない 🔥
worker_threads による回避策 worker_threads による回避策 • worker_threads のスレッド内でのみ Prettier 3.0 を実行するアーキテクチャへ
◦ (Prettier 2.0 を使っている場合はメインスレッドで実行する ) prettier-vscode メインスレッド worker_threadで作った新しいスレッド .pretterrc プラグイン Prettier本体 dynamic import フォーマットした い フォーマットした よ
worker_threads による回避策 worker_threads による回避策 https://github.com/prettier/prettier-vscode/pull/3016
まとめ
まとめ まとめ • VSCode拡張でdynamic import が動かない • 言語サーバー導入しようとしたけど難しかった • だからworker_threadsでスレッド立てて、そこから
dynamic importするようにした • 今のところ重大なバグ報告は来ていないが、実装者的には普通にバグってそうな気がする • 怪しい挙動があったら教えて下さい https://opencollective.com/prettier か https://github.com/sponsors/sosukesuzuki から寄付をくれると、 メンテを継続しやすくなります。