Romeコードリーディング
Rome は興味はあるものの、今は何ができるのかがわからないので、まずは動かしてみる。
git clone git@github.com:rome/tools.git rome-tools
cd rome-tools
いきなり tools
なんてディレクトリ作られても困るので rome-tools
に展開。
rome
というシェルスクリプトや rome.bat
っていうバッチファイルがあるので、これを実行すればコンパイルを勝手にやった上で rome を実行してくれる。開発便利スクリプトってところかな。ただ、rome-tools ディレクトリでやるとだめっぽいので、実験用のディレクトリを作って実行するっていうちょいめんどい感じに。
mkdir <other dir>/rome-test
cd <other dir>/rome-test
<rome dir>/rome init
<other dir>
で別のディレクトリに実験用ディレクトリを作成。<rome dir>
でさっき git clone してきたディレクトリを指定。
.editorconfig
と、.config/rome.rjson
が生成される。前者は、EditorConfigの設定なので良しとしておいて後者はなぞの独自形式 Rome JSONによるProject Configuration — Rome Toolchain
// For configuration documentation see https://rome.tools/#project-configuration
name: "rome-test"
root: true
初期状態だとこんな感じ。
とりあえず、src/index.ts
に適当なコードを書く。
const hoge = 1;
% ~/work/code-reading/rome-tools/rome check
Building trunk
! This command has been hidden. Consider its usage to be experimental and do not expect support or
src/index.ts:1:6 lint/js/noUnusedVariables ━━━━━━━━━━━━
✖ The const variable hoge is unused.
const hoge = 1;
^^^^
ℹ Unused variables are dead code and usually the result of incomplete refactoring.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Found 1 problem
横いっぱいに横線を表示するのはどうなんだ?とか思ったり思わなかったり。
とりあえず、unused variables で dead code やでーと言われる。
ひとまずここまで動けば、コードリーディングの足がかりにはちょうど良さそう
./rome
./rome
は、shスクリプト(正確には bash スクリプト)で、やってることは node "$DIR/scripts/dev-rome.cjs" "$@"
なだけなので、scripts/dev-rome.cjs
を起動してるだけ。
-
//# Utils
から、画面装飾用のユーティリティ -
//# Validate Node version
で、Node 12 より前のバージョンは蹴る -
//# init
で初期化-
isDevDaemonRunning
は、daemon mode 動いてる rome がいないか確認する関数 -
buildTrunk
はscripts/vendor/rome.cjs
でinternal/cli/bin/rome.ts
を bundle してtempDevBuildFolder
の指すテンポラリにindex.js
を吐き出す -
execDev
はtempDevBuildFolder
のテンポラリのindex.js
を実行する(コマンドラインの引数をそのまま受け取る)
-
という流れ。srcipts/vendor/rome.cjs
は吐き出されたコードなので読んでも仕方ないから、素直に internal/cli/bin/rome.ts
を読みに行く。
internal
% ls internal
ast codec-binary-serial codec-websocket fs node string-utils
ast-utils codec-config collections html-parser ob1 test-helpers
async codec-js-manifest commit-parser js-analysis parser-core typescript-helpers
child-process codec-js-regexp compiler js-ast-utils path v8
cli codec-json consume js-parser path-match vcs
cli-diagnostics codec-semver core js-parser-utils pretty-format virtual-packages
cli-environment codec-source-map css-parser markdown-parser project web-ui
cli-flags codec-spdx-license diagnostics markup string-charcodes
cli-layout codec-tar events markup-syntax-highlight string-diff
cli-reporter codec-url formatter messages string-escape
Rome の売りは、ゼロ依存なので、もう何もかもここに入ってる。見た感じ、どのディレクトリにも package.json
が置いてある。
internal/cli/bin/rome.ts
ROME_PROCESS_TYPE
環境変数に応じて、server
worker
testWorker
cli
が起動。
internal/cli/server.ts
internal/cli/worker.ts
internal/cli/testWorker.ts
internal/cli/cli.ts
CLIとして起動すると、internal/cli/cli.ts
が呼ばれる。
internal/cli/cli.ts
どうでもいいけど、Node.js だと、process.title = "hoge"
とかやれば、プロセスタイトルを変更できるのか。
はいきました。なんというかやってることは単純そうなのに、くっそめんどい感じのソース。まぁ必要に応じて真面目に読むとして、
@internal/core
が基本。
実行可能なコマンドは、localCommands
serverCommands
に書いてある。./rome check
を走らせる場合 serverCommands
の check
で internal/core/server/commands/check.ts
がそれに該当するっぽい。
実行するときに Client
クラスから client
オブジェクトを作成して最終的には、client.query
メソッドを実行する。
真面目に開発するなら、ここらへんの詳細も読むべきなんだろうけど今は読み飛ばす。
とりあえず internal/core/server/commands/check.ts
の最後で、Linter
クラスの throwSingle()
メソッドを実行してることまではわかるので、ひとまずそこを追いかける。
疲れたので、とりあえずここまで。続きは internal/core/server/linter/Linter.ts
の Linter
クラス、特に runSingle
メソッドを読む。
ぱっと読んだ感じは、まぁ watch モードを前提に組み立てていて、シングルショットで実行するのはどちらかというとその処理の中のごく一例みたいな実装