日本語textlintをMDX/MDに導入

投稿日
2025年1月1日
更新日
2025年1月9日
日本語textlintをMDX/MDに導入の見出し画像
目次

はじめに

日本語文章の自動校正のために導入したtextlintについて紹介です。一部deprecatedな依存ツリーの解決やMDXファイル用のルール設定、VS Code拡張の導入について共有します。

バージョン情報

nodejs
22.12.0
npm
10.9.0
textlint
14.4.0

NPMパッケージのインストール

textlint本体と採用したいルールセットを入れます。

Terminal window
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 leaks
memory. Do not use it. Check out lru-cache if you want a good and tested way
to coalesce async requests by a key value, which is much more comprehensive
and powerful.
npm warn deprecated rimraf@2.6.3: Rimraf versions prior to v4
are no longer supported
npm warn deprecated glob@7.2.3: Glob versions prior to
v9 are no longer supported
npm warnが出ない場合

依存関係が見直されて同様のwarnが出ない可能性があります。その場合、この項の対応は不要です。 すでに公式で対応済みです。この警告が出た場合は最新版にアップデートしましょう。

とりあえずnpm whyinflightの依存関係を見てみると、textlintの依存パッケージflat-cacherimrafのバージョンを2.6.3で固定していることが分かります。 さらに、先ほどwarnが出ていたglobパッケージもその間に挟まっていることが分かります。

Terminal window
$ npm why inflight
node_modules/inflight
inflight@"^1.0.4" from [email protected]
node_modules/rimraf/node_modules/glob
glob@"^7.1.3" from [email protected]
node_modules/rimraf
rimraf@"2.6.3" from [email protected]
node_modules/textlint/node_modules/flat-cache
flat-cache@"^2.0.1" from [email protected]
node_modules/textlint/node_modules/file-entry-cache
file-entry-cache@"^5.0.1" from [email protected]
node_modules/textlint
dev textlint@"^14.4.0" from the root project

rimrafの最新バージョンを確認してみます。

Terminal window
$ npm show rimraf version
6.0.1

メジャーバージョンが4つも進んでいることが分かります。メジャーアップデートなので前方互換性の不安はありますが、一旦package.jsonに依存パッケージ上書きの設定を追記します。

package.json
{
"overrides": {
"textlint": {
"rimraf": "^6.0.1"
}
}
}

上記の指定は、textlintパッケージの子孫に存在するrimraf^6.0.0に強制することを意味します。 overridesの詳細な仕様はnpmの公式ドキュメントを参照のこと。

この状態で再度インストールを実行します。npm iだけでpackage.jsonの内容に応じてパッケージを更新してくれます。

Terminal window
# package.jsonの内容をインストール
npm i

これで再度rimrafパッケージの依存ツリーを確認してみましょう。

Terminal window
$ npm why rimraf
rimraf@6.0.1 dev overridden
node_modules/rimraf
overridden rimraf@"^6.0.0" (was "2.6.3") from [email protected]
node_modules/textlint/node_modules/flat-cache
flat-cache@"^2.0.1" from [email protected]
node_modules/textlint/node_modules/file-entry-cache
file-entry-cache@"^5.0.1" from [email protected]
node_modules/textlint
dev textlint@"^14.4.0" from the root project

最新版のrimrafがインストールされていることが分かります。この上書きに関連して、inflightへの依存は無くなり、かつglobのバージョンも上がったためnpm warn deprecatedは無事出なくなりました。

rimrafの前方互換性について

このrimrafバージョン6.0.1でtextlintをしばらく動かしていますが、今のところ問題はありません。なにかエラーが出るようであればここに追記します。

textlintの設定

textlintの設定ファイル.textlintrc.jsonを作成します。textlintのコマンドから初期化&生成可能です。

Terminal window
npx textlint --init

下記のようにすでにインストール済みのルールセットを参照して自動的にtrueを設定してくれる親切なinitです👍

.textlintrc.json
{
"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プラグインをインストールします。

Terminal window
npm i -D @textlint/textlint-plugin-markdown

MDファイルへの対応だけであればインストールだけでOKなので、ここからはスキップして問題ありません。

MDXへの対応のため.textlintrc.jsonpluginsの部分に下記を設定します。

.textlintrc.json
{
"plugins": {
"@textlint/markdown": {
"extensions": [".mdx", ".md"]
}
}
}

この時点で、MDXファイルへのtextlintは有効になります。textlintコマンドで適当なmdxファイルへのtextlintを試してみてください。

Terminal window
npx textlint パス.mdx

追記したルール

一部のルールセットにオプションを追記しました。

MDX内のimport文をスキップ

preset-ja-technical-writingに含まれるsentence-lengthルールは、一文あたりの文字数を制限してくれるlintです。 このルールがMDX内のimport文まで反応してしまったのでここを無視するオプションを設定しました。

.textlintrc.json
{
"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ルールで、文章末尾が絵文字になることを許容します。

.textlintrc.json
{
"rules": {
"preset-ja-technical-writing": {
"ja-no-mixed-period": {
"allowEmojiAtEnd": true
}
}
}
}

VS Code拡張機能の設定

vscode-textlintという拡張機能が存在します。ありがたい🙌

MD・MDXファイルへの対応

.vscode/settings.jsonに下記を追記します。 ファイル保存時に修正可能な内容はfixしてほしかったのでautoFixOnSaveオプションも有効にしています。

.vscode/settings.json
{
"textlint.languages": ["mdx", "markdown"],
"textlint.autoFixOnSave": true
}

lint-stagedの設定

husky+lint-stagedで、コミット前のLintを管理しているので、textlintについても下記のようにpackage.jsonで設定しています。

package.json
{
"lint-staged": {
"*.{md,mdx}": "textlint"
}
}

文章校正の場合、勝手にfixされた内容をそのままコミットするのは少し抵抗があるので、fixオプションは付けていません。

おわりに

今回初めてtextlintを導入してみましたが、冗長表現や助詞の連続使用の自動検知は大変助かっています。 細かなケアレスミスが減って効率が上がる予感です。

関連記事