Maintainer Month: なぜtextlintを作ったか
今では200以上のルールがある自然言語のLintツールであるtextlintがどのように作られたかを振り返る記事です。
Maintainer Month
6月はMaintainer MonthというイベントをGitHubが主催しています。
Maintainer Month is a reminder for the ecosystem to support, celebrate, and compensate open source maintainers.
– Maintainer Month
Maintainer Monthは、オープンソースのメンテナーが集まって情報共有したり、メンテナーを祝ったり、支援したりするイベントです。 メンテナーがどういうサポートを求めているかを知る、負荷が特定の箇所に集中するエコシステムはバランスが悪いのでそれを支援する方法を知るといったことを思い出すのがMaintainer Monthの目的です。
Maintainer Month関係の記事
- Maintainer Month: オープンソースをメンテナンスするコツ | Web Scratch
- Maintainer Month: epubリーダーアプリ bi-epub-readerを作った | Web Scratch
textlintの誕生…の前に
2014年2月ごろに、JSer.infoであなたが読むべきJavaScript Promises - JSer.infoという記事を書いて、Promisesについてもっと知らないといけなさそうだなと考えました。 調べてもPromiseについてまとまったものはなかったので、ないなら書くかーと思ってJavaScript Promiseの本を書き始めました。
Promise本の最初のコミットは、2014年3月だったのでこの頃に書き始めたのだと思います。
- https://github.com/azu/promises-book/commit/883538b2a5fab5846d415fe0ef1abc1f125217dc
- 細かい書籍開発の流れはPromise本のおまけにも書かれていました
Promise本は最終的に100ページを越える書籍になっているのですが、書いてる途中で表記揺れなどが気になってきました。
そこで、技術評論社で使われているWEB+DB PRESS用語統一ルールというWZ EDITORの表記揺れを統一ための辞書が公開されていることに注目しました。
とりあえず、この辞書を使えば表記揺れが少なくなるかもと思って、WZ EDITOR用の形式だったので、辞書をJSONに変換できるパーサを書きました。
これを使えば、日本語Lintできるんじゃないかとか言ってたので、この頃から自然言語のLintが少し思い浮かんでいたようです。
WEB+DB PRESS用語統一ルール使った大雑把な日本語Lintみたいのできた。 pic.twitter.com/qrvjXZ2ZOp
— azu (@azu_re) June 4, 2014
結局この時は辞書をパースしただけで、Promise本での表記揺れには使っていませんでした。
- Promise本で取り組んだ電子書籍の開発ツール、CI、継続的リリースについて | Web Scratch
-
用語統一チェックの自動化 → 結局は目視チェックのみだった
-
少し日にちが経って、全く別のところでJSer.infoの記事紹介文でtypoや表記揺れが多くあることに気づきました。 これを減らそうと思って、CodeMirrorの拡張としてcodemirror-spellckeckerというものを書きました。 このスペルチェックには、先ほど登場したWEB+DB PRESS用語統一ルール をベースにしたtechnical-word-rulesという独自の辞書を使っています。
- 2014年10月: WEB+DB PRESS用語統一ルール等を使った技術用語のLintをするCodeMirrorアドオンを書いた | Web Scratch
- JSer.info 200 回目記念イベント
このcodemirror-spellckeckerは、CodeMirrorなのでブラウザ上でしか動きません。しかし、Travis CIのようなCI上でも同じ辞書を使ってチェックしたいと考えるようになってきました。
なぜなら、この少し前にJSer.infoのデータ管理もGitHubに全て移したため、紹介記事のデータもjser/jser.info: JSer.infoデータリポジトリとへコミットされるようになり、コミットしたら辞書でCI上で表記揺れを見つけたいと思ったためです。
technical-word-rulesはただの辞書のJSONファイルです。 この辞書を使ってブラウザでも、Node.jsでも、CIでも動く汎用的な自然言語のチェックツールが欲しい!となったのがtextlintを作ろうと思ったきっかけです。
現在はニンゲンが介在しないとちょっとチェックの精度が良くない感じで完全に補助するツールになってます。 (こういうの既にプロダクトとして、プログラマブルに使えるものって存在してるのかな?)
https://efcl.info/2014/10/20/lint-tech-word/
codemirror-spellckeckerは、ただの文字列一致であったため、Markdownで書いても構文を認識する訳ではありませんでした。これによる誤検知があったので、このようなことを書いているのだと思います。
そのため、textlintを作る時には文字列一致ではなくASTをベースにして扱うことを考えていました。
textlintを作り始める
2014年12月24日にnono/mddiffというライブラリを見つけて、このライブラリがCommonMarkというパッケージを使っていることに気づきました。 CommonMarkはMarkdownをパースして、内部的にASTを持っていることを発見しました。
これcommonmarkのAST使ってるんだ。CommonMarkにASTのドキュメントあるのかな? "nono/mddiff" https://t.co/PVdKNuDjIK
— azu (@azu_re) December 24, 2014
その日のうちに、CommonMarkを使って日本語Lintを作るアイデアを思いつきました。
#todo CommonMark AST + 日本語Lint
— azu (@azu_re) December 24, 2014
この次の日にtextlintを作り始めました。 そのため、textlintのfirst commitは2014年12月25日でした。
最初は、remarkではなくCommonMarkをベースにして作っていました。(そもそもこの時はremarkはまだノードの位置をASTに持ってない状態でした。そのため、CommonMark以外にはノードの位置とASTを扱えるライブラリはなかった)
そのまま一気に開発して、2014年12月30日には最初のtextlintをリリースしています。
この時のルールは、サンプルとして書いたno-todo
と先ほども出ていた独自辞書のtextlint-rule-spellcheck-tech-wordぐらいだったと思います。
textlintのプラグインの仕組みはESLintを参考にして書いていて、初期リリースはESLintのコードを結構そのまま持ってきて書き直してたきがします。
この辺の学びについては次のスライドにまとめてありました。
ESLintは結構モノリシックな作りであったため、textlintはそれをベースにモジュールを意識して書き直していた気がします。 これが、その後のTypeScript移行やブラウザで動かすためにKernel分離などに役立ったと思います。
2015年はひたすらtextlintの安定化と色々なルールを書いていました。 RedPenを参考にしたり、色々日本語の論文とか参考にしてルール書いてた気がします。
2016年になるともっとtextlintを開発するために、新しく本を書くことにしました。 JavaScript Plugin Architectureという書籍はtextlintの開発を進めるために書いた書籍で、ESLintを含むJavaScriptのプラグインアーキテクチャについて書いています。
これと同じようなことをjsprimerというJavaScript入門書を書くときにやっていた気がします。 やっぱり、実際に大きな文章があるとツールの開発が進みます。
また、この頃は思いついたアイデアをひたすらtextlintのルールに落としていた気がします。
このような形でtextlintの開発は進み、2022年ではtextlintのルールは200以上あります。
textlintの今後
今年は、去年末に書いていたRFCやNode.js ECMAScript Modules対応など結構大きな変更が必要になりそうです。
- RFC: textlint new message format · Discussion #833 · textlint/textlint
- Supports rules that are ECMAScript Modules · Issue #868 · textlint/textlint
既にRFCの一つであるRFC: Improve error location #835 は実装していてリリースされています。
この変更は、今までtextlintのエラー位置は”点”でしたが、エラーの”範囲”を報告できるようになるという変更です。(ルール側もpadding
の対応が必要です。)
この変更は@textlint/editorを作っていて、エラー位置をエディタ上で正確に出すには、点だけでは不十分となっているためです。 RFC: textlint new message format · Discussion #833 · textlint/textlintには他にもProposalがあって、ローカライズするために使えそうなMessageIdの仕組み、エラーとドキュメントを紐づける仕組み、エラーではなくサジェストの仕組みなどがあります。
この辺はやっぱりユースケースがあることで進むので、ユースケースを持ってる人は意見をください。
また、@textlint/editorで、.textlintrc
のロード周りの処理を再実装したりしてるので、これをtextlint本体に持ってきて今のよくないConfig.tsを全部書き直すなどやりたいことは色々あります。(手が足りないので、興味ある人は手をあげてください)
また、ESM対応はとりあえずルールをESMで書いて読み込めるようにするため、ルールのロードをimport()
でやるような変更を入れるつもりです。
ただし、default export
をBabelで変換したようなCJSをimport()
で読み込むとほんとひどいことになるので、どうにかしないといけません。(.default.default
という危ないプロパティを参照しないといけない…)
全部named exportにするのが一番いいのですが、既存のルールとの互換性があって大変です。
また、ルールのオプションのスキーマを書けるようにするという長年のIssueもどうにかしたいです。
BabelでTSからスキーマを生成するか、ESLintのmeta
のように手書きでJSON Schemaを書くかという部分で止まっています。
これも、textlintのルールからオプションをGUIで設定するなどの利用方法がありますが、やっぱりユースケースがある人を中心に進めるのが良いです。
textlintは、日本語が多いですが、英語や中国語などでも使われています。
- Translation: Angular、React、Vue、Nuxt.js, Next.js、Gatsby
- Book: JavaScript Primer、SurviveJS - Webpack
- Documentaion: VuePress、Cypress、Microsoft Azure Identity(ja)、OWASP Cheat Sheet Series
- 小説: 「Visual Studio Code」で執筆するSF作家 藤井太洋氏が作る物書きのための拡張機能
- Company: 弁護士ドットコム、ソラコム、ヴェルク、SmartHR、Retty
textlintは文章向けに作り始めたものではありますが、最近はプロダクトの表記揺れとかに使っているケースも増えているようです。
- textlintによる表記ゆれ撲滅 - Sansan Builders Blog
- textlintを導入してみて / Usage status and effects of the textlint - Speaker Deck
- Angularを採用したプロダクトで表記ゆれを撲滅したはなし - Speaker Deck
- プロダクト周りの文章校正をSlack botで半自動化してみた話|Shellme|note
- boardのカスタマーサポート返信時にtextlintでチェックする - ヴェルク - IT起業の記録
いつの間にかGitHubのgithub/super-linterにも含まれていました。 これが、Thank you to our maintainers | The GitHub Blogに選ばれた理由なのかはよくわかっていません。
自分もMaintainer MonthでGitHub Sponsorsの対象だった。https://t.co/gOU8eE79ta
— azu (@azu_re) June 25, 2022
Thanks to @github, Sponsors, and Maintainers 🎉 pic.twitter.com/EDqEbB2Hkq
まだやりたいことは色々ありますが、やっぱり物事を進めるのはユースケースなので、ユースケースを持ってる人は積極的に意見ください。
Twitterや #textlint
のようなハッシュタグでもいいし、Issueにコメントしたりでもいいし、Gitterは日本語でも話せます。
支援の方法は色々あるので、textlintはいつでもContributionを募集しています。
オープンソースにContributeする方法として、バグ報告/修正、機能追加、ドキュメントを書く、IssueやDiscussionのトリアージ、デザイン、マーケティングなど色々な関わり方があります。 その関わり方の一つとして、金銭的な支援をするという選択肢は、Contributorが選べるようになっているのが望ましいと思っています。
GitHub Sponsorsの募集を始めてから2年が経ったので振り返る | Web Scratch
GitHub Sponsorsでの支援は次のページからできます。GitHub Sponsorsは個人だけではなく会社単位でもできるようになっています。
お知らせ欄
JavaScript Primerの書籍版がAmazonで購入できます。
JavaScriptに関する最新情報は週一でJSer.infoを更新しています。
GitHub Sponsorsでの支援を募集しています。