Dart2.19コマンドラインツールについてメモ書き。
概要
DartはWEBアプリ、cliツール、Windowsアプリ等々いろいろと作れる。Flutterで使う言語だし、今後Dartを採用するプロジェクトは増えると思う。
そんなDartのコマンドラインツールについて調査。
Dartのバージョンは2.19.2 (stable)。
- dartコマンド
コマンド | 説明 |
---|---|
create | 新しいDartプロジェクトを生成。 |
analyze | 静的解析(コードを実行せずに解析)を行う。 |
compile | Dartファイルをコンパイル。dart2jsとdart2nativeはこちらに移行。 |
info | ツールの診断情報を表示。 |
doc | DartプロジェクトのHTMLドキュメントを生成。 |
fix | Dartソースコードを自動修正する。ただし、全ての問題に対して対応している訳ではないらしい。 |
format | Dartガイドラインに沿ったフォーマットで空白を設定。 |
devtools | 開発ツールを起動。 |
migrate | Nullセイフティへの移行をサポート。 |
pub | Flutter、dartのパッケージ管理ツール。pubspec.yamlでパッケージの依存関係を設定。pubspec.lock ファイルがある場合には、ファイルにリストされているバージョンを取得する。 |
run | Dartファイルを実行する。 |
test | テスト用。デフォルトはDartプロジェクトのtestディレクトリ配下のファイルでテストをコントロールする。pub run testはこちらに移行。 |
気になったコマンドをいくつか試してみる。
createコマンド
createコマンドのヘルプを見てみる。
% dart create --help
Create a new Dart project.
Usage: dart create [arguments] <directory>
-h, --help Print this usage information.
-t, --template The project template to use.
[console] (default) A command-line application.
[package] A package containing shared Dart libraries.
[server-shelf] A server app using package:shelf.
[web] A web app that uses only core Dart libraries.
--[no-]pub Whether to run 'pub get' after the project has been created.
(defaults to on)
--force Force project generation, even if the target directory already exists.
Run "dart help" to see global options.
-tオプションでどのテンプレートを使用するか指定できる。テンプレートはコマンドライン(デフォルト)、共有ライブラリ、shelfパッケージを使用したサーバーアプリ、Dartコアライブラリだけを使ったWEBアプリがある。
コマンドラインのプロジェクトを作成してみる。
% dart create -t console dev1
Creating dev1 using template console...
.gitignore
analysis_options.yaml
CHANGELOG.md
pubspec.yaml
README.md
bin/dev1.dart
lib/dev1.dart
test/dev1_test.dart
Running pub get... 2.0s
Resolving dependencies...
Changed 46 dependencies!
Created project dev1 in dev1! In order to get started, run the following commands:
cd dev1
dart run
dev1プロジェクトの構成を確認。
% tree -a dev1
dev1
├── .dart_tool
│ └── package_config.json
├── .gitignore
├── CHANGELOG.md
├── README.md
├── analysis_options.yaml
├── bin
│ └── dev1.dart
├── lib
│ └── dev1.dart
├── pubspec.lock
├── pubspec.yaml
└── test
└── dev1_test.dart
以下のファイルが生成される。
binディレクトリ配下に実行ファイル本体が作成されている。
ファイル | 説明 |
---|---|
test/dev1_test.dart | 単体テスト用の設定ファイル。 |
bin/dev1.dart | 実行ファイル本体。ライブラリファイルを読み込む。 |
CHANGELOG.md | 変更履歴管理ファイル。 |
README.md | 使用方法を記載。 |
pubspec.lock | パッケージバージョン管理用。 |
pubspec.yaml | パッケージ依存関係管理用。 |
.gitignore | Gitの管理対象から除外するファイルを記述。 |
lib/dev1.dart | ライブラリファイル。 |
analysis_options.yaml | 静的解析設定ファイル。 |
.dart_tool/package_config.json | Dartパッケージの名前解決に使用。 |
analyzeコマンド
analyzeコマンドを実行してみる。
- ソースコードに問題なし
% dart analyze
Analyzing dev1... 0.6s
No issues found!
- ソースコードに問題あり
行末のセミコロン(;)を取る。
import 'package:dev1/dev1.dart' as dev1;
void main(List<String> arguments) {
print('Hello world: ${dev1.calculate()}!') //←末尾の";"を取る。
}
analyzeコマンドを実行。エラーが表示される。
% dart analyze
Analyzing dev1... 0.5s
error • bin/dev1.dart:4:44 • Expected to find ';'. • expected_token
1 issue found.
compileコマンド
compileコマンドのヘルプを表示。
% dart compile -h
Compile Dart to various formats.
Usage: dart compile <subcommand> [arguments]
-h, --help Print this usage information.
Available subcommands:
aot-snapshot Compile Dart to an AOT snapshot.
exe Compile Dart to a self-contained executable.
jit-snapshot Compile Dart to a JIT snapshot.
js Compile Dart to JavaScript.
kernel Compile Dart to a kernel snapshot.
Run "dart help" to see global options.
コンパイル形式がいくつかある。
js(JavaScript)は良いとして、aot-snapshot、exe、jit-snapshot、kernelの違いがよく分からない。本家サイトで調べる。
前提としてDartコンパイルには以下区分がある。
プラットフォーム | compileオプション | 説明 |
---|---|---|
Native Platform | aot-snapshot exe jit-snapshot kernel | モバイル、デスクトップ用のコンパイル。 iOS、android、mac、Windows、Linux用。 |
Web Platform | js | JavaScriptへのコンパイル。 Web用。 |
Native Platformのコンパイルの違いはこういう事らしい。
compile サブコマンド | 用途 | 説明 |
---|---|---|
jit-snapshot | デバッグ用 | JIT(Just In Time)スナップショットには中間表現、Dartランタイム、コンパイル済みのコード等が含まれる。プラットフォームに依存。 |
exe | 本番デプロイ用 | 自己完結型の実行ファイルを生成する。Dartランタイムを含む。 プラットフォームに依存。 |
aot-snapshot | 本番デプロイ用 | AOT(Ahead Of Time)スナップショットはDartランタイムを含まないためファイルサイズが小さい。プラットフォームに依存。dartaotruntime コマンドで実行する。 |
kernel | 本番デプロイ用 | プラットフォームに依存しない中間表現で実行ファイルを生成。 |
JITは実行時にコンパイルする形式だけど、JITスナップショットにはコンパイル後のコードが入る。場合によってはAOTスナップショットより実行速度が上がると公式サイトに書いてある。
dev1.dartのコードを更新。ループ処理を追加。
import 'package:dev1/dev1.dart' as dev1;
void main(List<String> arguments) {
int i;
for (i = 0; i < 1000000; i++) {
i = i + i;
}
print('i=$i');
print('Hello world: ${dev1.calculate()}!');
}
それぞれの形式でコンパイルする。
% dart compile aot-snapshot dev1.dart
Info: Compiling with sound null safety.
Generated: /Users/********/app/dart/dev1/bin/dev1.aot
% dart compile jit-snapshot dev1.dart
Compiling dev1.dart to jit-snapshot file dev1.jit.
Info: Compiling with sound null safety.
i=1048575
Hello world: 42!
% dart compile exe dev1.dart
Info: Compiling with sound null safety.
Generated: /Users/********/app/dart/dev1/bin/dev1.exe
% dart compile kernel dev1.dart
Compiling dev1.dart to kernel file dev1.dill.
Info: Compiling with sound null safety.
ファイルサイズを確認。
昇順でソートする。
% du -hs * | sort -h | grep -v dev1.dart
4.0K dev1.dill
864K dev1.aot
4.4M dev1.exe
4.7M dev1.jit
これを見るとサブコマンドの違いがよく分かる。
ファイルサイズはプラットフォーム固有の情報が入っていないkernel(dev1.dill)が一番小さい。
次に小さいのはDartランタイムが含まれていないAOTスナップショット(dev1.aot)。
Dartランタイムが含まれているexe(dev1.exe)はファイルサイズが大分大きくなる。
情報量が多いJITスナップショット(dev1.jit)のファイルサイズが一番大きい。
次に実行速度を確認。数回実行し、平均的な実行結果を記載する。
まずはソースコードに対してdart runコマンドを実行。これはJITで実行前に都度コンパイルする。
% /usr/bin/time dart run dev1.dart
i=1048575
Hello world: 42!
0.72 real 0.44 user 0.16 sys
トータル0.72秒。
次はJITスナップショットに対して実行。
% /usr/bin/time dart run dev1.jit
i=1048575
Hello world: 42!
0.10 real 0.09 user 0.03 sys
トータル0.10秒。
次はAOTスナップショットに対して実行。
% /usr/bin/time dartaotruntime dev1.aot
i=1048575
Hello world: 42!
0.04 real 0.01 user 0.01 sys
トータル0.04秒。
次はexeファイルを実行。
% /usr/bin/time ./dev1.exe
i=1048575
Hello world: 42!
0.01 real 0.00 user 0.00 sys
トータル0.01秒。
最後はkernelファイルに対して実行。
% /usr/bin/time dart run dev1.dill
i=1048575
Hello world: 42!
0.08 real 0.09 user 0.02 sys
トータル0.08秒。
実行速度が早い順からexe、AOTスナップショット、kernel、JITスナップショット、JITコンパイルだった。速度については環境やコードによって違いが出ると思う。
infoコマンド
dart infoコマンドを実行。
% dart info
If providing this information as part of reporting a bug, please review the information below to ensure it only contains
things you're comfortable posting publicly.
#### General info
- Dart 2.19.2 (stable) (Tue Feb 7 18:37:17 2023 +0000) on "macos_arm64"
- on macos / Version 12.4 (Build 21F79)
- locale is ja-JP
#### Process info
| Memory | CPU | Elapsed time | Command line |
| -----: | ---: | -----------: | ------------------------------------------------------------------------------- |
~~~~以下省略~~~~~~~
dartのバージョンやOS情報が出力される。バグレポートで実行環境を取得するときに使える。
docコマンド
docコマンドを実行。
% dart doc
Documenting dev1...
Initialized dartdoc with 41 libraries
Generating docs for library dev1 from package:dev1/dev1.dart...
no issues found
Documented 1 public library in 7.8 seconds
Success! Docs generated into /Users/*******/app/dart/dev1/doc/api
apiディレクトリ配下にドキュメントファイルが生成されている。
% ls -1
__404error.html
categories.json
dev1/
index.html
index.json
search.html
static-assets/
index.htmlを開いてみる。
dev1パッケージのマニュアルが自動生成されている。これは便利。
formatコマンド
dev1.dartに対してformatコマンドを試す前作業として、行の先頭スペースを削除する。
import 'package:dev1/dev1.dart' as dev1;
void main(List<String> arguments) {
int i;
for (i = 0; i < 1000000; i++) {
i = i + i;
}
print('i=$i');
print('Hello world: ${dev1.calculate()}!');
}
formatコマンドを実行。
% dart format dev1.dart
Formatted dev1.dart
Formatted 1 file (1 changed) in 0.08 seconds.
dev1.dartを開く。
先頭にスペースが挿入され、ファイルのフォーマットが整っている。
import 'package:dev1/dev1.dart' as dev1;
void main(List<String> arguments) {
int i;
for (i = 0; i < 1000000; i++) {
i = i + i;
}
print('i=$i');
print('Hello world: ${dev1.calculate()}!');
}
devtoolsコマンド
devtoolsコマンドを実行。
% dart devtools
Serving DevTools at http://127.0.0.1:9102.
Hit ctrl-c to terminate the server.
DevToolsが立ち上がる。DevToolsの終了は「Ctrl+c」。
使い方はよく分からないが、名称からFlutter開発で使うサポートツールと同じものかもしれない。
コメント