サクサク読めて、アプリ限定の機能も多数!
トップへ戻る
ブックレビュー
zenn.dev/sosukesuzuki
TSKaigi 2024 で話した「Prettier の未来を考える」という発表のスピーカーノートです。スライドは こんにちは、今日は「Prettierの未来を考える」というタイトルでお話させていただきたいと思います。 鈴木 颯介と言います。ユビー株式会社でプロダクト開発エンジニアとして働きながら、筑波大学でパソコンの勉強をしています。オープンソースソフトウェアが好きで、今日お話するPrettierのメンテナーをしたり、トランスパイラのBabelのコミッターをしたりしています。最近はWebKitのJSエンジンにたくさんパッチを投げたりしています。 私が働いているユビーは、TSKaigiのGold Sponsorをさせてもらっています。ブースがあります。ユビーのグッズの他に、Prettierのステッカーも配布しておりますので、興味がある方はぜひお立ち寄りください。 まず、Prettierにつ
TC39の活動で有名なJordan Harbandが作成した下記issueで知ったのでメモ。 前提として、次のコードによって x がオブジェクト型であることを判断できる。JavaScriptにおける null は typeof の結果が "object" になるという有名な変な挙動がカバーされている。 function isObjectA(x) { return (typeof x === "object" && x !== null) || typeof x === "function"; }
2023 年の Prettier の活動を振り返ります。 Prettier とは Prettier は JavaScript で書かれたコードフォーマッタです。設定可能な項目が少ないいわゆる opinionated なコードフォーマッタです。JavaScript や TypeScript だけではなく、HTML や CSS、GraphQL などもサポートしています。 リリース 2023 年は、メジャーバージョンのリリースが 1 回、マイナーバージョンのリリースが 1 回でした。これまでは 3 ヶ月に 1 回程度マイナーバージョンをリリースしていたので、頻度は少し下がっています。 ですが、メジャーバージョンである 3.0 をリリースできたことと、これまでよりもカジュアルにパッチバージョンをリリースするようになったことを考えると、開発自体が停滞しているわけではないと思っています。 「カジュアル
目標は、約100%後方互換性を持たせ、将来の安定版リリースで現在のCLIを置き換えることです。 概要 PrettierのCLIは上の図のように大まかに動作します: ファイルに対して実行したい何らかのアクションがあります。例えば、適切にフォーマットされているかどうかをチェックすることです。 このアクションを実行するために、実際にすべてのファイルを見つける必要があります。 .gitignoreファイルと.prettierignoreファイルを解決し、これらのファイルの中に無視すべきものがあるかどうかを判断します。 .editorconfigファイルを解決し、それらのファイルに対するEditorConfig固有のフォーマット設定を行います。 .prettierrcファイルなど、約10以上のPrettier固有のフォーマット設定ファイルを解決します。 各ファイルがそのフォーマット設定に一致している
この記事は vjeux 氏によって Prettier 公式ブログに投稿された「$20k Bounty was Claimed!」を許可をもらって翻訳したものです。 もとのタイトルを翻訳するのが難しかったので、できるだけわかりやすいものに翻訳しました。 PrettierというJavaScriptのコードフォーマッターは、人々がコードを書く様々な方法を慎重に扱うことで、驚くほど広く採用されています。この時点で、フォーマットロジックは安定しており、私たちの三項演算子に関する作業が完了すれば、それは満足のいく状態になるでしょう。 これは、次の重要な側面に注目できるということを意味します:パフォーマンス。Prettierは決して速いとは言えませんが、ほとんどの使用例には十分な速さです。これはいつも不満足な感じがしたので、何かをすることを望んでいました。それには、友好的な競争以上の方法はありません。
この記事は、JSConf JP 2023 で発表した「書いたJavaScriptがそのままブラウザで動く未来へ」のスピーカーノートです。もともと PDF を公開していたのですが、読みにくいという声をいただいたので移植しました。内容はそのままで、見出しだけ付けています。 はじまり こんにちは、今日は「書いたJavaScriptがそのままブラウザで動く未来へ」というタイトルで発表をします。「いやいや、JavaScriptはブラウザで普通に動くだろう」と思われる方もいらっしゃるかもしれませんが、話を聞いてもらえれば何を言っているのかわかると思います。 JSConf JPで登壇させていただくのは今回で3度目なのですが、オフラインのカンファレンスで話すのは今回がはじめてなので少々緊張しています。 最初に軽く自己紹介をします。鈴木 颯介と言います。大体のところで Sosuke Suzuki という名前
ガベージコクレクションは手を動かすまでがちょっと遠い 下記の記事で書いたように、私は今ガベージコレクションに夢中です。 少し勉強して、ガベージコレクションの難しさの1つは「実装してみる」までが遠いところなのではないかと思っています。 ガベージコレクションというのは、それ単体で成り立つものではなく、基本的にはプログラミング言語の処理系と一緒に実装されるものです。したがって「ガベージコレクションに入門するぞ〜」と意気込んで理論を勉強しても、実装する対象となる適切な処理系がない、という問題に直面することになると思います。 多分、多くの人がそうなったのでは?と勝手に予想しているんですが、どうなんでしょう。 少なくとも私はそうなりました。 現実の処理系は複雑で難しい ガベージコレクションが実装されており、かつ日本語話者が関わりやすい処理系としてはまず CRuby が思いつきます。しかし CRuby
最近「おれってガベージコレクションを勉強するにあたってめちゃくちゃ恵まれた環境にあるのでは?」とふと思い立ち、ベージコレクションの勉強を始めました。 ガベージコレクションの勉強を始めるにあたって、とりあえず「The Garbage Collection Handbook (first edition)」の邦訳である「ガベージコレクション 自動的メモリ管理を構成する理論と実装」を読むことにしました。 この記事では、読み終わってうれしいので、雑に感想を書きなぐっています。表記が「GC」だったり「ガベージコレクション」だったりするのは雑に書いたからです。 前提知識 ガベージコレクションの事前知識はほとんど不要で、何をしてくれるものか大まかにわかっていれば良い程度だと思います。つまり、ヒープに確保した領域を明示的に解放しなくても、何かのアルゴリズムでいい感じにやってくれる仕組み、ということを知って
PrettierというソフトウェアはNode.jsで動作します。他のNode.jsで動作するソフトウェアと同様に、Prettierも、サポート対象のNode.jsのバージョンを決めています。 たとえば、Prettier v2.x は Node.js 10.13.0 以降のみで動作します。それより前の Node.js でももしかしたら動くかもしれませんが、それは想定されていません。CIでもテストしてません。 現在 Prettier v3.0 の開発を進めていて、どの Node.js までサポートしようか、という議論になりました。結論が出て、今後同じような議論を避けるためにポリシーを決めたので、理由と共に紹介しようと思います。 先に結論 https://github.com/prettier/prettier/wiki/The-policy-to-drop-Node.js-version に書
タイトルの通りです。 「そんな状況ないよ」っていう人は羨ましいです。「require とかできねえんだけど」っていう人は残念でした。 function log(value) { require("fs").appendFileSync( path.join(hogePath, "log.txt"), "[main thread " + new Date().toString() + "]" + "\n " + value + "\n" ); }
Promsie を作って返す関数で、Promise コンストラクタの引数のコールバックではないところで resolve とか reject とかしたいことがある。 こんな感じで、外部に変数を作って普通に代入して外から resolve/reject を呼べるテクがある。 function registerSomething() { let resolve, reject; const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); something.registerSomething((error, info) => { if (error) reject(error); resolve(info); }) return promise; } まあ実際には、上記コードくらいだったら普通にコンストラ
私は Ruby ビギナーなんですが、最近ちょっとしたきっかけがあって、Ruby に興味津々です。 そこで、Ruby(MRI)をちょっとだけ改造して遊んでみました。 Ruby に貢献!みたいな良い話ではなくて、自分の手元の Ruby に対してあんまり意味のない改造を施して、楽しいね! っていう類の話です。 ちなみに C 言語はほとんど書いたことありません。 どう遊ぶか 私はパーサーがちょっとだけ好きなので、パーサーを触ってみたいと思いました。 パーサーを触るような改造をするなら、新しい構文を追加してみるのがてっとり早そうです。その中でも二項演算子なら簡単なのではないかと考えました。 ということで、(私が日頃から書いている)JavaScript にあって Ruby にはない演算子として、>>> 演算子を実装してみることにしました。 >>> 演算子は、符号なし右シフト演算子というやつで、Java
import timers from "node:timers/promises"; await timers.setTimeout(1000); まあこれでも大体の場合良いのだけど、たとえば async じゃない関数の中とかで、スレッドをまるっと止めたいときがある。(スレッド遊びをしているときとかね) そういうときはタイムアウト付きの Atomics.wait で止められる。 function msleep(n) { Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, n); } ここから余談。この Atomics.wait、今回の場合は同期的に止まってくれるのがありがたいポイントなのだが、本来の用途としてはスレッドを同期的に止められると困ることがある。そこで最近 Atomics.waitAsync というやつが St
Node.js v20 リリースされました。 V8 のバージョンが 11.3 まで上がったことで、いくつかの新しい ECMAScript の機能が使えるようになりました。v フラグが好きなのでうれしいです。 どのバージョンからどの機能が使えるようになったかとか忘れてしまうのでメモしておきます。 String.prototype.isWellFormed / String.prototype.toWellFormed 文字列が Well Formed Code Unit Sequence かどうか判定する isWellFormed と、それに変換する toWellFormed が追加されます。WebIDL の文脈では USV 文字列とか言われますね。 これは WebAssembly みたいな USV 文字列前提の環境とやり取りするときに便利。Babel みたいな JavaScript を解釈
日々いろんな npm パッケージに依存してるわけですが、その作者が気になるときがある。 単純に気になるときもあるけど、調査が必要になるときもある。 たとえば最近 substack の GitHub アカウントが削除された。npm から消えたわけじゃないから、すぐに困るってことはないけど、誰にも移譲されていないリポジトリがあっとして、もし自分がそれに依存してしまっていたら代替を探したくなる。 また、自分が関わっている OSS プロジェクトでは過去のメンテナーが作ったたくさんのライブラリに依存していて、その人がすでにアクティブでなくなったいるため、やや悪い影響が出始めていたりする。 そのため、自分の依存している npm パッケージの作者をシュッと調べて、フォークするか移管してもらうか色々判断できると便利である。 ということでそれに役に立つツールを作った。 npm に publish してあるの
WebAssembly というやつは便利で一度コンパイルしてしまえばブラウザでも Node.js でも実行できる。 でも .wasm のファイルをどうやって読み込むのか、というのがブラウザと Node.js では違う。 色々やり方はあると思うけど、一番素直なやり方を考えてみる。 まずブラウザの場合は main.wasm みたいなファイルを適当な場所に配置しておいて fetch で内容を取得して WebAssembly.instantiate に食わせるとかになると思う。 const response = await fetch("main.wasm"); const buf = await response.arrayBuffer(); const { instance } = await WebAssembly.instantiate(buf);
GoogleのエンジニアであるBraydon Kains 氏が開発した yamlfmt という YAML のコードフォーマッターが最近話題。 yamlfmt は Go で書かれています。ということは WebAssembly にコンパイルできるので、ブラウザで動かすことができる。 作ったもの GitHub Pages にデプロイしてます。 設計 次の3つのパッケージを作りった。monorepo の構成には moon を使ってる。 リポジトリは https://github.com/sosukesuzuki/js-yamlfmt 。 @js-yamlfmt/wasm Node.js からもブラウザからも使える yamlfmt の JS バインディング。@rollup/plugin-wasm が生成するコードを参考にして Node.js とブラウザの両方に対応した WebAssembly ライブ
趣味で TC39 のアクティビティを追ったり https://cybozu.github.io/frontend-expert/ にそういう記事を書いたりすることがあるのですが、その作業をする中でややめんどい手作業みたいなのがあったりします。 そういうのを自動化するコマンドラインツールを作ろうと思って、最初いつもどおり Node.js で作り始めました。30分くらいしていつもどおり Node.js じゃつまらないなと思ったので Deno で作ってみました。 実は Deno を使ったのは初めてだったので感想を書いてみます。哲学とかは置いといて単純にユーザーとしての利便性について。 deno lint と deno fmt が便利 自分は ESLint と Prettier に精通している方だけどとは言えそういう設定なしにシュッと動くのはかなり楽。速いし。 標準ライブラリが便利 Node.js
Prettier 2.7 がリリースされました。 このバージョンには TypeScript 4.7 の対応のほかに、新しい CLI オプションである --cache と --cache-strategy が含まれています。 --cache と --cache-strategy を実装したのは自分なので、その背景や実装、そして使い方の話を雑にしようと思います。 背景 Rome Formatter のブログが公開されて日本の開発者からもそれなりに大きな反響がありました。 私個人としてはコードフォーマッターにそこまでの速さを求めていないのであんまり興味はなかった(もちろん速いほうがいいけど)のですが、みなさん意外と興味あるんだなあという気持ちで眺めていました。 それからしばらくして Prettier の https://github.com/prettier/prettier/issues/58
メモ ES2020 の機能で import.meta というのがあります。 import.meta はモジュールのメターデータを含むオブジェクトです。ブラウザや Node.js では import.meta.url というプロパティが生えています。 これは import.meta.url が評価されたモジュールのファイルの URL を表すプロパティです。 Node.js では、ESM 環境下で createRequire をしたり __filename や __dirname に相当するものを取得する用途等でよく使われます。 import module from "node:module"; const require = module.createRequire(import.meta.url); import path from "node:path"; import url from
最近の SWC は Rust でプラグインを書くことができます。 先日、現実の Babel プラグインを SWC プラグインに移植して実際に使ってみたので、それについて書き残します。 (SWC のプラグインの仕様は変わっていく可能性が高いので、この記事や参照先のコードはあんまり参考にしすぎないように...) 移行対象の Babel プラグイン 今回の移行対象の Babel プラグインは、主に React 用の状態管理ライブラリである Valtio に実装されている useProxy という Hooks です。 この Hooks は babel-plugin-macros で実装されており、ビルド時に別の Hooks に展開されます。今回はこの挙動を SWC プラグインをとして再現します。 useProxy Valtio はシンプル(見かけ上はシンプル、実際にはシンプル/イージーでいえばイー
最近ライブラリをビルドするときはもっぱら esbuild を使っている。 esbuild を使うときには大体 ./scripts/build.mjs みたいなのを用意している。この記事では、自分が使っているビルドスクリプトの雛形を紹介する。 Stage 3 の Import Assertions と JSON modules を使って package.json を取得するので、Node.js v17 系が必要になる。 環境変数 WATCH に true を渡しておくとウォッチモードになる。 各種設定は用途に合わせてお好みで。 import { build } from "esbuild"; import pkg from "../package.json" assert { type: "json" }; const dependencies = Object.keys(pkg.depen
Rust で書かれた swc という JavaScript のトランスパイラがあります。最近は Next.js 12 からデフォルトで Babel の代わりに使われることになったので日本でも話題にあがることが多くなったように思います。 ちょっと前から、暇なときに、Rust への入門のために swc に貢献しています。この間、現在 Stage 4 の static blocks という提案を swc に実装したので、そのときの話を書きます。 ただ数ヶ月前の話なので、正直詳細まで覚えていません。なのでこの記事は雑なメモだと思ってください。とは言っても、実際に swc をいじろうとするときのとっかかりにはなるんじゃないかと思います。 Issue を立てる まず Issue を立てます。 そして「自分がやります」と表明しておきます。 AST を更新する https://github.com/swc
と書くことができます。 便利ですね。 パース処理がおもしろい 最近私はこの構文のパーサーを Babel のために書いています。 挙動を TypeScript と一貫させるために、本家(microsoft/TypeScript)のコードを読んでいたのですがその処理がおもしろかったので紹介します。 本家コードはここにあります。 一部抜粋して掲載します。 コード let isTypeOnly = false; let propertyName: Identifier | undefined; let canParseAsKeyword = true; let name = parseIdentifierName(); if (name.escapedText === "type") { // If the first token of an import specifier is 'type',
class Counter { #count = 0; get #count() { return this.#count; } set #count(value) { this.#count = value; } #foo() {} }
はじめに JavaScript において文字数を String の length で取得すると、期待した値が得られないことがある。この記事では、実際に String の length を使うことによって発生した Prettier のバグを紹介する。 前提 JavaScript の String には length というプロパティが存在する。このlengthプロパティは文字列の文字数を表すものではない。 実際には、文字列中に含まれるUTF-16のコードユニットの数を返す。つまり、ASCIIをはじめとしたBMPに含まれるものであれば我々の期待する文字数が返ってくるが、一部の漢字やemojiなどについてはそうはならない。 たとえば、漢字の𠮟(U+20B9F)はサロゲートペアであり、2つのコードユニットで表される。そのため、length は 2 になる。
Linda_ppさんが開発したactionlintというコマンドラインツールがあります。 これは GitHub Actions のワークフローファイルを静的に解析して、事前にわかる問題を指摘してくれるツールです。詳細については開発者である Linda_pp さんが書いたブログ記事を読むことをおすすめします。 私は GitHub Actions をよく使います。しかし、ワークフローファイルの記述を誤ってしまい、実際に動かしてから些細なミスに気がつくことがよくあります。これには非常にストレスを感じていました。 actionlint はこの問題を見事に解決してくれました。コマンドラインからactionlintと入力すれば、適切に問題を指摘してくれます。 作ったもの 課題 私は普段 Node.js を使って様々なものを開発しています。actionlint は Go で書かれており、Node.js
const [resolvedHexVersionId, setResolvedHexVersionId] = useState< HexVersionId | undefined >(); たしかに読みにくいと思う。 しかし、代入(や変数)の右辺に関数呼び出しがあり、その型引数が Union Types もしくは Intersection Types の場合はこんな感じにするという処理が Prettier 2.3.1 から存在し、それには合理性があると思っている。Union Types や Intersection Types が一定以上長い場合は2.3.1のようなフォーマットになっている方が整ってみえる(と思う)。 この記事の本題ではないので、気になるひとは該当の Issue や https://github.com/prettier/prettier/pull/10949 や htt
バンドルサイズを出力するシンプルな Rollup Plugin を作った。 ちょうど一年くらい前、仕事でよく Rollup Plugin を書いたりいじったりする機会があり、そのときにバンドルサイズを出力してくれる Rollup Plugin を探していたのだが、いい感じのがなく、自分で雑に書いていた。 そして最近仕事で小さな SDK 風のものを作って GitHub Packages にパブリッシュする必要が出てきた。そのパッケージのバンドルに Rollup を使うことにしたので、またバンドルサイズを出力してくれる Rollup Plugin が欲しくなった。 また、世の中にいくつかそういうプラグインはあるが、機能が豊富すぎたり、メンテされてなくて動かなかったりするので、自分で最小限のものを持っておきたいという気持ちがあった。 ということでバンドルサイズを出力してくれるシンプルな Roll
次のページ
このページを最初にブックマークしてみませんか?
『Sosuke Suzukiさんの記事一覧』の新着エントリーを見る
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く