Skip to content

Commit 1909cd0

Browse files
committed
feat(textlint): textlint v15.0.0をリリース - 非推奨APIの削除とNode.js 20+サポートの追加
1 parent e4c1f0e commit 1909cd0

3 files changed

Lines changed: 463 additions & 352 deletions

File tree

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
---
2+
title: "textlint v15.0.0をリリースしました。非推奨APIの削除とNode.js 20+サポート/MCPサーバの改善"
3+
author: azu
4+
layout: post
5+
date : 2025-06-25T09:00
6+
category: textlint
7+
tags:
8+
- textlint
9+
- JavaScript
10+
- Node.js
11+
12+
---
13+
14+
textlint v15.0.0をリリースしました!
15+
16+
- [Release v15.0.0 · textlint/textlint](https://github.com/textlint/textlint/releases/tag/v15.0.0)
17+
- [textlint v15.0.0 | textlint](https://textlint.org/blog/2025/06/22/textlint-15/)
18+
19+
textlint v15は、v12.3.0から非推奨としてマークされていた古いAPIをすべて削除するメジャーリリースです。
20+
21+
## textlint v15.0.0の変更点
22+
23+
主要な変更点は次の通りです。
24+
25+
## Breaking Changes
26+
27+
- Node.js 20+のサポート(Node.js 16,18はサポート終了
28+
- `TextLintEngine`を削除 → `createLinter()`
29+
- `TextFixEngine`を削除 → `createLinter()`
30+
- `TextLintCore`を削除 → `createLinter()`または`@textlint/kernel`
31+
- `textlint`(シングルトンインスタンス)を削除 → `createLinter()`
32+
- `createFormatter`を削除 → `loadFormatter()`
33+
34+
## Node.js 20以上が必要
35+
36+
textlint v15では、Node.js 20.0.0以上が必要になりました。
37+
Nodejs 18はEOL(End of Life)となっているため、Node.js 20以上を使用する必要があります。
38+
39+
- <https://nodejs.org/en/about/previous-releases>
40+
41+
## 非推奨APIの削除
42+
43+
`textlint`パッケージをNode.jsモジュールとして利用する場合のみ影響を受ける変更です。
44+
45+
textlint v15では、非推奨となっていた次のAPIが完全に削除されました。
46+
47+
移行ガイドは次のページに用意しています。
48+
49+
- [Migration Guide to textlint v15 | textlint](https://textlint.org/docs/migration-to-v15/)
50+
51+
### `TextLintEngine``createLinter()`
52+
53+
**変更前(v14以前):**
54+
```javascript
55+
const { TextLintEngine } = require("textlint");
56+
57+
const engine = new TextLintEngine({
58+
configFile: ".textlintrc.json"
59+
});
60+
const results = await engine.executeOnFiles(["*.md"]);
61+
const output = engine.formatResults(results);
62+
console.log(output);
63+
```
64+
65+
**変更後(v15以降):**
66+
```javascript
67+
import { createLinter, loadTextlintrc, loadLinterFormatter } from "textlint";
68+
69+
const descriptor = await loadTextlintrc({
70+
configFilePath: ".textlintrc.json"
71+
});
72+
const linter = createLinter({ descriptor });
73+
const results = await linter.lintFiles(["*.md"]);
74+
const formatter = await loadLinterFormatter({ formatterName: "stylish" });
75+
const output = formatter.format(results);
76+
console.log(output);
77+
```
78+
79+
### `TextFixEngine``createLinter()`
80+
81+
**変更前(v14以前):**
82+
```javascript
83+
const { TextFixEngine } = require("textlint");
84+
85+
const engine = new TextFixEngine();
86+
const results = await engine.executeOnFiles(["*.md"]);
87+
```
88+
89+
**変更後(v15以降):**
90+
```javascript
91+
import { createLinter, loadTextlintrc } from "textlint";
92+
93+
const descriptor = await loadTextlintrc();
94+
const linter = createLinter({ descriptor });
95+
const results = await linter.fixFiles(["*.md"]);
96+
```
97+
98+
### `TextLintCore``createLinter()`
99+
100+
**変更前(v14以前):**
101+
```javascript
102+
const { TextLintCore } = require("textlint");
103+
104+
const textlint = new TextLintCore();
105+
textlint.setupRules({
106+
"rule-name": require("./my-rule")
107+
});
108+
const result = await textlint.lintText("Hello world", "test.md");
109+
```
110+
111+
**変更後(v15以降):**
112+
```javascript
113+
import { createLinter } from "textlint";
114+
import { TextlintKernelDescriptor } from "@textlint/kernel";
115+
import { moduleInterop } from "@textlint/module-interop";
116+
117+
const descriptor = new TextlintKernelDescriptor({
118+
rules: [
119+
{
120+
ruleId: "rule-name",
121+
rule: moduleInterop((await import("./my-rule")).default)
122+
}
123+
]
124+
});
125+
const linter = createLinter({ descriptor });
126+
const result = await linter.lintText("Hello world", "test.md");
127+
```
128+
129+
## その他の改善
130+
131+
### Exit Statusの改善
132+
133+
textlint v15では、ESLintの動作に合わせてExit Statusが改善されました。
134+
135+
- Fatalエラー: Exit Status 2を返す(従来は1)
136+
- Lintエラー: Exit Status 1を返す(変更なし)
137+
- 成功: Exit Status 0を返す(変更なし)
138+
139+
```bash
140+
# v15+ behavior
141+
textlint nonexistent-file.md # Exit Status: 2 (file search error)
142+
textlint file-with-errors.md # Exit Status: 1 (lint errors)
143+
textlint clean-file.md # Exit Status: 0 (success)
144+
```
145+
146+
### 絶対パスのファイルも`.textlintignore`のパターンを尊重
147+
148+
textlint v15では、絶対パスのファイルが`.textlintignore`パターンを正しく尊重しない問題が修正されました。
149+
150+
以前は、`.textlintignore`に記載されたパターンにマッチしていても、`textlint`コマンドに絶対パスとして渡された場合は無視されていませんでした。
151+
textlint v15では、絶対パスのファイルも`.textlintignore`のパターンを正しく尊重するようになりました。
152+
153+
```bash
154+
# Before v15 (Bug)
155+
textlint /absolute/path/to/ignored-file.md # Lintされてしまっていた
156+
157+
# v15+ (Fixed)
158+
textlint /absolute/path/to/ignored-file.md # Lintの対象外となった
159+
```
160+
161+
詳しくは、[GitHub Issue #1412](https://github.com/textlint/textlint/issues/1412)を参照してください。
162+
163+
### Model Context Protocol (MCP)の統合強化
164+
165+
textlint v14.8.0から、`textlint --mcp`でtextlintをMCPサーバーとして起動できます。
166+
167+
- <https://textlint.org/docs/mcp/>
168+
169+
textlint v15では、MCPのサポートを改善しています。
170+
2025-06-18の[Key Changes - Model Context Protocol](https://modelcontextprotocol.io/specification/2025-06-18/changelog)に基づいて、以下の変更が行われました。
171+
172+
- [Structured Content](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#structured-content): 出力結果の構造を事前に定義することで、AIツールが結果をより正確に解釈できるようになりました
173+
- [MCP 2025-06-18 で追加された structured tool output を試す](https://zenn.dev/sushichaaaan/articles/fd57bbaa25287c)
174+
- [Output Schema](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#structured-content): 出力結果のJSON Schemaを提供することで、AIツールが結果を正確に解釈できるようにしました
175+
- `isError: true`の追加: エラーが発生した場合、`isError: true`を設定することで、AIツールがエラー状態を認識できるようにしました
176+
177+
詳しくは、次のGitHub Issueを参照してください。
178+
179+
- [Enhance MCP Server Support with 2025-06-18 Specification Updates · Issue #1563 · textlint/textlint](https://github.com/textlint/textlint/issues/1563)
180+
181+
## まとめ
182+
183+
textlint v15では、非推奨となっているものを削除したり、動作の一貫性を改善するような変更をしています。
184+
185+
またtextlintの内部的にも、[pnpm](https://pnpm.io/)[Vitest](https://vitest.dev/)への移行して、
186+
CIの合計時間が21m 5s → 7m 20sに短縮しています。(Windowsでnpmのインストールが遅かったのがボトルネック)
187+
188+
- [use pnpm instead of npm · Issue #1537 · textlint/textlint](https://github.com/textlint/textlint/issues/1537)
189+
- [refactor: migrate test runner from Mocha to Vitest by azu · Pull Request #1544 · textlint/textlint](https://github.com/textlint/textlint/pull/1544)
190+
191+
他にも[Merge Gatekeeper](https://github.com/upsidr/merge-gatekeeper)を入れてAuto Mergeをできるようにしたり、Netlifyのキャッシュがやたら不安定なので[Deploy PR Preview action](https://github.com/rossjrw/pr-preview-action)を使ってPRのプレビューを作成するなどの改善をしています。
192+
193+
- [CI: add Merge Gatekeeper workflow for pull requests by azu · Pull Request #1577 · textlint/textlint](https://github.com/textlint/textlint/pull/1577)
194+
- [feat: replace Netlify with pr-preview-action by azu · Pull Request #1580 · textlint/textlint](https://github.com/textlint/textlint/pull/1580)
195+
196+
この辺を整理したので、textlint自体の開発体験もだいぶ良くなっています。
197+
198+
まだやるべきことはたくさんあるので、興味あるひとは是非Contributorとして参加してください!
199+
200+
- [Meta: ECMAScript Modules · Issue #1307 · textlint/textlint](https://github.com/textlint/textlint/issues/1307)
201+
- [Recreate --cache flag · Issue #1327 · textlint/textlint](https://github.com/textlint/textlint/issues/1327)
202+
- [ESLint for TypeScript · Issue #685 · textlint/textlint](https://github.com/textlint/textlint/issues/685)
203+
- [feat: migrate from Mocha to Node.js built-in test runner (node:test) · Issue #1545 · textlint/textlint](https://github.com/textlint/textlint/issues/1545)
204+
- これは今回のメジャーアップデートでNode.js 18が切れたので可能になった
205+
206+
実験的なものとして[textlint-rule-preset-ai-writing](https://github.com/textlint-ja/textlint-rule-preset-ai-writing)とか書きながら考えていましたが、Linterの役割はちょっと広がってきているのかなと思いました。
207+
[Biome v2](https://biomejs.dev/blog/biome-v2/)で追加された[Assist](https://biomejs.dev/assist/)もそうですが、ErrorやWarningじゃなくてSuggestionに近い部分も増えてきているように感じます。SuggestはLinterの役割なのかは微妙なところですが、この辺の機能はLinterの延長として実装されることが多い感じはしています。
208+
209+
特に自然言語はauto fixが難しいので、Suggestionのような形でHintを提供できる仕組みがあると、人間とAIにとっても使える感じのツールになるんじゃないかなーと思っています。
210+
211+
textlintでは、Contributionを歓迎しています。
212+
213+
- [Issues · textlint/textlint](https://github.com/textlint/textlint/issues)
214+
215+
また、GitHub Sponsorsでのサポートも歓迎しています。
216+
217+
- [Sponsor @azu on GitHub Sponsors](https://github.com/sponsors/azu)
218+
219+
## 関連リンク
220+
221+
- [textlint v15.0.0のリリースノート](https://textlint.org/blog/2025/06/22/textlint-15/)
222+
- [v15移行ガイド](https://textlint.org/docs/migration-to-v15.html)
223+
- [新API ドキュメント](https://textlint.org/docs/use-as-modules.html) - 新しいAPIのドキュメント
224+
- [実装例](https://github.com/textlint/textlint/tree/master/examples/use-as-module) - 新しいAPIを使った例

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
},
99
"devDependencies": {
1010
"@proofdict/textlint-rule-proofdict": "^3.1.2",
11-
"textlint": "^14.8.0",
11+
"textlint": "^15.0.1",
1212
"textlint-rule-no-doubled-joshi": "^5.1.0",
1313
"textlint-rule-no-mix-dearu-desumasu": "^6.0.4",
1414
"textlint-rule-no-start-duplicated-conjunction": "^2.0.2"

0 commit comments

Comments
 (0)