土屋つかさの技術ブログは今か無しか

土屋つかさが主にプログラミングについて語るブログです。

「node.jsにtextlintをインストールして」「ルールをtypescriptで記述して」「VSCode上でステップ実行でデバッグしたい」をする

 近年の大規模プログラム開発環境では、ソースコードを共有する前にlinterと呼ばれるツールを使ってコード検証をするのが一般的です。linterでは決められたコーディングルールに沿っているかについて、コンパイラよりも厳格なチェックを行い、場合によっては自動的に修正してくれます。ちなみに「linter」という名称はUNIXのlintコマンドから来ていて、"lint trap(洗濯機に取り付けてある「糸くず("lint")取り」の事)"に由来しているそうです*1
github.com

 textlintは、自然言語で書かれたテキスト用のlinterとして提供されているツールです*2。提供されている様々なルールを組み合わせて、テキストを検証する事が出来ます。
 textlintはnode.js上で動くjavascriptのアプリで、独自のルールを作成してツールに組み込む事も出来ます。新規作成をサポートするテンプレート生成機能や丁寧なドキュメントも提供されています。

 今回、「node.jsにtextlintをインストールして」「ルールをtypescriptで記述して」「VSCode上でステップ実行でデバッグしたい」と考えました。ただ、その時点で「node.js」「typescript」「VSCode」のいずれもたいして知らなかったのと、ピンポイントで参考になるサイトを中々見つけられず、結構な試行錯誤が必要でした。

 最終的にはシンプルな手順で実現できたので、記事にまとめておくことにしました。同じ事をやろうとする人の参考になると思いますし、もっと言えば、多分数ヶ月後には手順を忘れているであろう自分用のリファレンスと言えます。

前提

 Windows10環境で作業しています。また、以下はインストール済みとします*3

・node.js
・VisualStudioCode

あと、環境的にはPower Shell Core(7.2.5)もインストールしてるけど、これは無くても大丈夫だと思います(ダメだったらインストールして下さい)

インストール手順

開発用フォルダを新規作成する。

 node.jsの開発用フォルダを作る所から始めます。ここでは"C:\TS_Project"配下にtextlintフォルダを作成しました。

プロジェクトフォルダを配置するディレクトリに移動

 VSCodeを起動し、メニューの「ターミナル>新しいターミナル」を選択してターミナルウィンドウを開きます。下図の右下にあるのがターミナルウィンドウです。

 ターミナルにコマンドを入力して開発用フォルダに移動します。ここでは既にカレントディレクトリが"C:\TS_Project"だったので以下の様に入力してます。

PS C:\TS_Project\textlint> cd textlint-rule-example 

 コマンドプロンプトなりPowershellなりを別途起動してもいいんですが、今回は作業がVSCode上で出来るだけ完結するようにしました。

node.jsの初期化

 textlintフォルダをnode.js開発用に初期化します。

PS C:\TS_Project\textlint> npm init -y

 "npm"はnode.js関連の様々な処理を行うコマンドです*4。"npm init"は初期化コマンドで、必要事項を記述したpackage.jsonを生成します。通常は各項目について対話形式で実行されますが、"-y"オプションを付けると全てデフォルト値で構成されます。
 フォルダを見るとpackage.jsonが生成されているのが分かります。逆に言うと、initの役割はpackage.jsonを生成・更新するのみです。

textlintをインストールする

 次にtextlintをインストールします。

PS C:\TS_Project\textlint> npm install -D textlint

 "npm install"はnpmリポジトリ*5からパッケージ(ここではtextlint)を取得してインストールするコマンドです。"-D"オプションは"-save-dev"オプションの省略系で、textlintを開発用のパッケージとしてインストールします(後述)。

(注意:撮影に使ったPCのnpmのバージョンが古かったらしく、上図にはその警告が表示されています)
 パッケージはローカルインストールされます*6。インストールが終わるとnode_modulesフォルダとpackage-lock.jsonファイルが生成されます。また、package.jsonも更新されています。
 node_modulesフォルダ内にはインストールしたtextlintパッケージと、このパッケージが依存している全てのパッケージが格納されています。確認すると分かりますが、驚くほど多くのパッケージがダウンロードされていることが分かります。
 package-lock.jsonファイルは、node_modulesフォルダ配下にダウンロードされた各パッケージのバージョン情報を格納しています。通常、手作業で更新する事はありません(package.jsonはあります)。
 package.jsonには下記の行が追記されています。

  "devDependencies": {
    "textlint": "^12.2.1"
  }

 devDependenciesは、インストールしたパッケージのうち、開発用("-D"を付与した物)のパッケージが列挙されます*7。ここではtextlintをインストールした事が示されています。

create-textlint-ruleをインストールする

 textlintのルールのテンプレートコード群を生成するcreate-textlint-ruleをインストールします。

PS C:\TS_Project\textlint> npm install -D create-textlint-rule

サンプルを作る

 インストールしたcreate-textlint-ruleでテンプレートコード群を生成します。

PS C:\TS_Project\textlint> npx create-textlint-rule example --typescript

 npxはnpmのユーティリティコマンドの一つで、インストールしたパッケージをコマンドとして実行します。ここではcreate-textlint-ruleコマンドでexampleという名前でテンプレートコード群を生成してます。"--typescript"オプションを付与すると、(javascriptではなく)typescriptのコードを生成してくれます(親切!)。
 このコマンドは対話形式で、幾つか入力を求められますが、全部エンターだけして先に進めばOKです。
 処理が終わるとtextlint-rule-exampleフォルダが生成されます。textlintの命名規則で、ルールのパッケージ名は"textlint-rule-"が先頭に付与されます。

生成されたプロジェクトを確認する

 生成されたフォルダに移動します。

PS C:\TS_Project\textlint> cd .\textlint-rule-sample\

 srcフォルダ配下にあるindex.tsが、ルールを記述するファイルになります。プロジェクトをビルドするとlibフォルダ配下にトランスパイルされたjsファイルが格納されます。このフォルダで"npm test"を実行すると、testフォルダ配下のindex-test.tsが実行され、テストルーチンが走ります。

デバッグ手順

 次は、textlint-rule-exampleをデバッグします。

VSCodeを起動してプロジェクトフォルダを開く

 VSCodeを起動して、メニュー「ファイル>フォルダを開く」で"PS C:\TS_Project\textlint\textlint-rule-example"を開きます。

 下図の確認が表示された場合は「はい、作成者を信頼します」を選択。

laucnh.jsonファイルを作成

 VSCodeでプロジェクトのデバッグをする為にはデバッグの構成を記述するlaunch.jsonというファイルを作成する必要があります。このファイルはプロジェクトルートの.vscodeフォルダに配置されます。
 左端のバーの上から四つ目(実行とデバッグ)をクリックすると、launch.jsonファイルが無い場合は下図のような表示になります。

 ここで「launch.jsonファイルを作成します。」をクリックすると、フォーカスが上部のテキスト入力欄に移り、どのようなlaunch.jsonを生成するかの選択が要求されます。ここでは"Node.js"を選択して下さい。

 .vscode/launch.jsonが生成され、その中身が表示されます。

Launch.json内に新規のデバッグ構成を記述する。

 ここでは前述したindex-test.tsによるテストの実行中にコードにアタッチすることにします。
 Launcd.json内の、"configurations"の配列内の、下図のカーソルの位置でCtrl+Spaceを押下すると、インテリセンスのリストが表示されます。

 リスト内の"Launch vis npm"を選択します。すると、配列に要素が一個追加されます。

 この中の"runtimeArgs"の配列を"test"のみに書き換えます。こうすることで、"runtimeExecutable"の"npm"と合わせて、前述した"npm test"が実行出来るようになります。保存を忘れないようにしてください。

デバッグ構成をLaucnh via NPMに変更

 準備が出来たのでデバッグを開始します。左端のバーで「実行とデバッグ」が選択されている状態で、ウィンドウ左上のデバッグ構成リストから"Launch via NPM"を選択します。

デバッグコンソールを表示

 実行結果はデバッグコンソールに出力されます。デバッグコンソールが未表示の場合は、メニューの「表示>デバッグコンソール」を選択します。

デバッグ実行

 デバッグを実行するには、先ほどデバッグ構成を選択したリストの左側にある緑色の三角アイコンをクリックします(F5でも同じ結果になります)。

 必要なビルドが行われ、デバッグコンソールにindex-test.tsの実行結果が表示されます。

ステップ実行も出来る

 プロセスへのアタッチが出来ているので、ステップ実行も可能です。src/index.ts内にブレークポイントを設定してデバッグを開始すると、ちゃんとtsファイル上でブレークがかかってくれます。

 結局書き出してみると、結構な長さになりましたが、これでようやく「node.jsにtextlintをインストールして」「ルールをtypescriptで記述して」「VSCode上でステップ実行でデバッグしたい」が達成された事になります。さあ、これでルールの開発が出来るぞ!

補足:(今回の範囲での)npmとnpxの違い

PS C:\TS_Project\textlint\textlint-rule-example> npm test

PS C:\TS_Project\textlint> npx create-textlint-rule example --typescript

 上記の2つ、何故片方がnpxで、片方はnpmなのか不思議に思うかもしれません。
 npmはpackage.json内の"scripts"に記述されたコマンド(ここでは"test")を実行するコマンドです。一方、npxはインストールされたパッケージ(ここでは"create-textlint-rule")を実行するコマンドです*8

補足2:テスト出力結果の文字化け

 VSCode上ではなく、カスタマイズしてないPowerShell7を起動して実行したら下図みたいに文字化けしていました。

 この場合、nard fontをインストールしないとダメかもしれません。とはいえ、ならなんでVSCodeのターミナルでは問題無いのかがよくわからない……。以前は普通に表示されていた気がするので環境問題のような気もします。

*1:参考:http://x68000.q-e-d.net/~68user/unix/pickup?lint

*2:標準でHTML/Markdownにも対応

*3:本当はここから始めるべきだけどそれだとあまりに長くなるので省略。すまぬ

*4:本来の用途はパッケージマネージャーの筈だけど、node.js関連の制御はこのコマンドで行うと考えて良いと思う

*5:node.jsの様々なライブラリが格納されている公開ライブラリ。誰でも登録可能で、パッケージ名は早い者勝ちで登録されている

*6:node.jsにはインストールしたフォルダ配下で使用できるローカルインストールと、環境全体で使用できるグローバルインストールがあります

*7:非開発用の場合はDependencies。開発用に分類されたパッケージは、このフォルダ下で開発したアプリをパブリッシュする時に依存パッケージの対象にしない

*8:とはいえ、この辺の使い分けを土屋自身が正直まだよくわかってません