投稿:
更新:
ブログにTextlintを導入してpre-commitとCIを構築する【文体を自動で整える】
はじめに
こんにちは。ブログなり、サイトなり、自分で資料を作るなり、文章を書く機会が比較的多いです。
疲れていたり、ぼーっとしていると、気づかぬうちに表現にブレが生じてしまう、誤字脱字があるため予防したいと思い、工夫をすることにしました。
(自分の過去の記事をたまに読み返すと、誤字脱字も表現のブレも多くてビビっていますが、全てて読むのは辛いので、このツールでなんとかします。文章の改善はツールに頼らず自分でやります。)
手順
大まかな手順をまとめます。
- Textlint を導入する
- プラグインを導入する
- textlint コマンドを作る
- pre-commit を設定する
- ルールを無視して良い箇所を指定する
- CI を設定する
Textlint を導入する
リポジトリはtextlint/textlint: The pluggable natural language linter for text and markdown.です。
textlint のインストール・初期化をします。当然、開発環境のみで使うパッケージなので-D
オプションをつけます。
npm install -D textlint
npx textlint --init
textlint
がインストール済みであればnpx
コマンドでインストールは発生しません。
プラグインを導入する
一気にたくさんのプラグインを入れても仕方がないし、対応に困るので 1 つだけ入れて様子見します。コミットも分けてるので最悪 revert します。
textlint-ja/textlint-rule-no-dropping-the-ra: ら抜き言葉をチェックする textlint ルールを入れます。
npm install -D textlint-rule-no-dropping-the-ra
.textlintrc
を書き換えます。単にルールを有効にするだけ。
{
"rules": {
"no-dropping-the-ra": true
}
}
動かしてみると次のようになります。プロジェクト配下のsrc/data
に Markdown
を配置しているため、僕はこのように入力しています。
❯ npx textlint src/data
PATH_TO_BLOG/src/data/dummy.md
1:3 error ら抜き言葉を使用しています。 no-dropping-the-ra
当然ですが、直すと消えました。
textlint コマンドを作る
Markdown
に対してのみ動かすので、package.json
にコマンドを作ります。
JS / TS
などのプログラム中のコメントは英語で書く+日本語だとしても開発者しか見ないのでらぬき言葉だったとしても何ら問題はないです。そのため、Markdown
に対してのみ実行したいです。
また、なぜコマンドを作るかと言うと、zsh で補完が効くから、CI でコマンドを使うから、です。
ESLint と同様に--fix
オプションが使えますが、--fix
して勝手に整形されると自分が困るため設定しません。
なぜなら、メンテナンスされているか分からないプラグインがある可能性がゼロではないからです。
textlint/textlint: The pluggable natural language linter for text and markdown.にオプションなど記載あります。
{
...
"scripts":{
...
"textlint": "textlint --cache **/*.md",
...
}
...
}
キャッシュファイルは当然生成されるのでgitignore
しましょう。
.textlintcache
これで npm
スクリプトとして動かすことが可能です。
❯ npm run textlint
> textlint
> textlint --cache **/*.md
PATH_TO_BLOG/src/data/dummy.md
1:3 error ら抜き言葉を使用しています。 no-dropping-the-ra
pre-commit の設定をする
これらをインストールし、husky
だけ初期設定します。
- okonet/lint-staged: 🚫💩 — Run linters on git staged files
- typicode/husky: Git hooks made easy 🐶 woof!
npm install husky -D
npm pkg set scripts.prepare="husky install"
npm run prepare
npm install -D lint-staged
npx husky add .husky/pre-commit "npx lint-staged"
pre-commit
に追加して、適宜必要なタイミング (リモートリポジトリにデータ反映など)で動かしたいのです。
全てのファイルに対してではなく、コミット前のステージングしたファイルだけです。時間効率のため。そのためlint-staged
を使っています。また、以下のスクリプトは非常にシンプルにしていますが、本当は色々オプションを付けています。書き出したらキリもない。
- 以下のオプションを適宜使ってます(
--cache
などは付けて損ないです) - CLI · Prettier
- Command Line Interface - ESLint - Pluggable JavaScript Linter
{
...
"lint-staged": {
"*.md": [
"textlint --cache"
],
"*.{js,jsx,ts,tsx,json,css,md}": [
"eslint --fix",
"prettier --write"
]
},
...
}
"*.{js,jsx,ts,tsx,json,css,md}": [
としていますが、JS
系しか ESLint
で対応できないので以下のように設定しています(補足)。
**/*.md
**/*.css
**/*.json
当然、以下のように分けても良いです。
{
...
"lint-staged": {
"*.md": [
"textlint --cache"
],
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
],
"*.{js,jsx,ts,tsx,json,css,md}": [
"prettier --write"
]
},
...
}
実際に動かすことで確かめます。あえてルールを無視するファイルであるdummy.md
を書きます。
食べれる
dummy.md
のら抜きをコミット出来なければ良いです
❯ git commit
✔ Preparing lint-staged...
❯ Running tasks for staged files...
❯ package.json — 1 file
❯ *.md — 1 file
✖ textlint --cache [FAILED]
❯ *.{js,jsx,ts,tsx,json,css,md} — 1 file
✖ eslint --fix [KILLED]
◼ prettier --write
↓ Skipped because of errors from tasks. [SKIPPED]
✔ Reverting to original state because of errors...
✔ Cleaning up temporary files...
✖ textlint --cache:
PATH_TO_BLOG/src/data/dummy.md
1:3 error ら抜き言葉を使用しています。 no-dropping-the-ra
✖ 1 problem (1 error, 0 warnings)
✖ eslint --fix failed without output (KILLED).
husky - pre-commit hook exited with code 1 (error)
「食べれる」→「食べられる」と修正します。
❯ git commit
✔ Preparing lint-staged...
❯ Running tasks for staged files...
❯ package.json — 1 file
✔ *.md — 1 file
❯ *.{js,jsx,ts,tsx,json,css,md} — 1 file
✔ eslint --fix
⠸ prettier --write
◼ Applying modifications from tasks...
◼ Cleaning up temporary files...
これでコミットで動きます。
ルールを無視して良い箇所を指定する
本ブログでら抜き言葉の例を書くと、それもら抜き言葉のエラーを吐いてしまいダメです。ブログが公開できません。
ESLint と同様に指定した箇所を無視するようにします。
パッケージをインストールします。
npm install -D textlint-filter-rule-comments
設定ファイルを追記します。
{
...
"filters": {
"comments": true
},
...
}
本文にルールを適用します。
<!-- textlint-disable -->
```md
食べれる
```
<!-- textlint-enable -->
<!-- textlint-disable -->
「食べれる」→「食べられる」と修正します。
<!-- textlint-enable -->
これでコミットできました。
✦ ❯ git commit
✔ Preparing lint-staged...
❯ Running tasks for staged files...
❯ package.json — 1 file
✔ *.md — 1 file
❯ *.{js,jsx,ts,tsx,json,css,md} — 1 file
✔ eslint --fix
⠧ prettier --write
◼ Applying modifications from tasks...
◼ Cleaning up temporary files...
CI を設定する
特に難しいことはなく、ESLint と同様に静的解析を動かして落ちたらビルドが動かないだけです。
詳細は分量多いので載せませんが、develop
ブランチと、そのブランチへのプルリクエスト時のみ動かしてます。
JS / TS / JSX / TSX
などの静的解析 → テスト → ビルド →Slack への通知を行っています。
---
- run: npm run textlint
補足
VSCode
拡張機能は使わないです。常に視覚的に見えるのは好みではないので入れません。
また、lint-staged
では過去のファイルに対してエラーを吐かないので一応常に目に入るようにしたい人は VSCode
拡張機能を入れるのもありです。単にコマンドラインからファイル全てに対して適用するだけで事足りますが、あとは個人の好みの問題ですね。
プラグイン
たくさんあるので、随時追加しますが、自作したほうが良い気もします。
- textlint/textlint-filter-rule-comments: textlint filter rule that disables all rules between comments directive.
- textlint-ja/textlint-rule-preset-ja-technical-writing: 技術文書向けの textlint ルールプリセット
- textlint-ja/textlint-rule-preset-ja-spacing: スペース周りのスタイルを扱う textlint ルール集
おわりに
これでより良い、表記の整った文章に少しずつ変えていけるし、これからの文章は確実に良い表記になる。
あとは文章の構成能力を上げるなり、伝え方に注力しよう。