日本語textlintをMDX/MDに導入

目次
はじめに
日本語文章の自動校正のために導入したtextlintについて紹介です。一部deprecatedな依存ツリーの解決やMDXファイル用のルール設定、VS Code拡張の導入について共有します。
バージョン情報
NPMパッケージのインストール
textlint本体と採用したいルールセットを入れます。
npm i -D textlint \ textlint-rule-ja-unnatural-alphabet \ textlint-rule-max-ten \ textlint-rule-no-doubled-joshi \ textlint-rule-preset-ja-technical-writing \ textlint-rule-preset-jtf-style
各ルールセットの説明は下記記事が分かりやすかったです。
deprecatedパッケージの解決
現行バージョン(14.4.0
)だと、3つのnpm warn deprecated
が表示されました。inflightというパッケージについてはメモリーリークもあると書かれているのでちゃんと解決します。
npm warn deprecated inflight@1.0.6: This module is not supported, and leaksmemory. Do not use it. Check out lru-cache if you want a good and tested wayto coalesce async requests by a key value, which is much more comprehensiveand powerful.npm warn deprecated rimraf@2.6.3: Rimraf versions prior to v4are no longer supportednpm warn deprecated glob@7.2.3: Glob versions prior tov9 are no longer supported
依存関係が見直されて同様の
すでに公式で対応済みです。この警告が出た場合は最新版にアップデートしましょう。warn
が出ない可能性があります。その場合、この項の対応は不要です。
とりあえずnpm why
でinflightの依存関係を見てみると、textlintの依存パッケージflat-cacheがrimrafのバージョンを2.6.3
で固定していることが分かります。
さらに、先ほどwarnが出ていたglobパッケージもその間に挟まっていることが分かります。
$ npm why inflightnode_modules/inflight node_modules/rimraf/node_modules/glob node_modules/rimraf node_modules/textlint/node_modules/flat-cache node_modules/textlint/node_modules/file-entry-cache node_modules/textlint dev textlint@"^14.4.0" from the root project
rimrafの最新バージョンを確認してみます。
$ npm show rimraf version6.0.1
メジャーバージョンが4つも進んでいることが分かります。メジャーアップデートなので前方互換性の不安はありますが、一旦package.json
に依存パッケージ上書きの設定を追記します。
{ "overrides": { "textlint": { "rimraf": "^6.0.1" } }}
上記の指定は、textlintパッケージの子孫に存在するrimrafを^6.0.0
に強制することを意味します。
overridesの詳細な仕様はnpmの公式ドキュメントを参照のこと。
この状態で再度インストールを実行します。npm i
だけでpackage.json
の内容に応じてパッケージを更新してくれます。
# package.jsonの内容をインストールnpm i
これで再度rimrafパッケージの依存ツリーを確認してみましょう。
$ npm why rimrafrimraf@6.0.1 dev overriddennode_modules/rimraf node_modules/textlint/node_modules/flat-cache node_modules/textlint/node_modules/file-entry-cache node_modules/textlint dev textlint@"^14.4.0" from the root project
最新版のrimrafがインストールされていることが分かります。この上書きに関連して、inflightへの依存は無くなり、かつglobのバージョンも上がったためnpm warn deprecated
は無事出なくなりました。
このrimrafバージョン6.0.1
でtextlintをしばらく動かしていますが、今のところ問題はありません。なにかエラーが出るようであればここに追記します。
textlintの設定
textlintの設定ファイル.textlintrc.json
を作成します。textlintのコマンドから初期化&生成可能です。
npx textlint --init
下記のようにすでにインストール済みのルールセットを参照して自動的にtrue
を設定してくれる親切なinit
です👍
{ "plugins": {}, "filters": {}, "rules": { "ja-unnatural-alphabet": true, "max-ten": true, "no-doubled-joshi": true, "preset-ja-technical-writing": true, "preset-jtf-style": true }}
MD・MDXファイルへの対応
デフォルトではMD・MDXに対応していないので、textlintパッケージの公式が案内しているmarkdown対応に従って設定します。
はじめに、textlintのmarkdownプラグインをインストールします。
npm i -D @textlint/textlint-plugin-markdown
MDファイルへの対応だけであればインストールだけでOKなので、ここからはスキップして問題ありません。
MDXへの対応のため.textlintrc.json
のplugins
の部分に下記を設定します。
{ "plugins": { "@textlint/markdown": { "extensions": [".mdx", ".md"] } }}
この時点で、MDXファイルへのtextlintは有効になります。textlint
コマンドで適当なmdxファイルへのtextlintを試してみてください。
npx textlint パス.mdx
追記したルール
一部のルールセットにオプションを追記しました。
MDX内のimport文をスキップ
preset-ja-technical-writing
に含まれるsentence-length
ルールは、一文あたりの文字数を制限してくれるlintです。
このルールがMDX内のimport
文まで反応してしまったのでここを無視するオプションを設定しました。
{ "rules": { "preset-ja-technical-writing": { "sentence-length": { "skipPatterns": ["/import\\s.*;/i"] } } }}
skipPatterns
は正規表現ライクな文法でスキップ対象を指定できます。
基本的には正規表現ですが、デフォルトでgu
(GlobalおよびUnicodeフラグ)がついた状態になります。つまり今回は、//igu
(大文字小文字を区別しないフラグ付き)の状態です。また、//m
(マルチラインフラグ)がオプションとして明記されていることから、デフォルトでは一行ずつの処理であることが分かるため、貪欲マッチのままでおそらく問題はないでしょう。
行頭行末を指す「^」「$」は対応していなさそうです🤔(私の指定方法が誤っていた可能性もあります)
文章を絵文字で終えることを許可
同じくpreset-ja-technical-writing
に含まれるja-no-mixed-period
ルールで、文章末尾が絵文字になることを許容します。
{ "rules": { "preset-ja-technical-writing": { "ja-no-mixed-period": { "allowEmojiAtEnd": true } } }}
VS Code拡張機能の設定
vscode-textlint
という拡張機能が存在します。ありがたい🙌
MD・MDXファイルへの対応
.vscode/settings.json
に下記を追記します。
ファイル保存時に修正可能な内容はfixしてほしかったのでautoFixOnSave
オプションも有効にしています。
{ "textlint.languages": ["mdx", "markdown"], "textlint.autoFixOnSave": true}
lint-stagedの設定
husky
+lint-staged
で、コミット前のLintを管理しているので、textlintについても下記のようにpackage.json
で設定しています。
{ "lint-staged": { "*.{md,mdx}": "textlint" }}
文章校正の場合、勝手にfixされた内容をそのままコミットするのは少し抵抗があるので、fixオプションは付けていません。
おわりに
今回初めてtextlintを導入してみましたが、冗長表現や助詞の連続使用の自動検知は大変助かっています。 細かなケアレスミスが減って効率が上がる予感です。
関連記事

