Dart2.19コマンドラインツール

Dar言語StreamクラスtoSet()メソッドDart

Dart2.19コマンドラインツールについてメモ書き。

概要

DartはWEBアプリ、cliツール、Windowsアプリ等々いろいろと作れる。Flutterで使う言語だし、今後Dartを採用するプロジェクトは増えると思う。
そんなDartのコマンドラインツールについて調査。
Dartのバージョンは2.19.2 (stable)。

  • dartコマンド
コマンド説明
create新しいDartプロジェクトを生成。
analyze静的解析(コードを実行せずに解析)を行う。
compileDartファイルをコンパイル。dart2jsとdart2nativeはこちらに移行。
infoツールの診断情報を表示。
docDartプロジェクトのHTMLドキュメントを生成。
fixDartソースコードを自動修正する。ただし、全ての問題に対して対応している訳ではないらしい。
formatDartガイドラインに沿ったフォーマットで空白を設定。
devtools開発ツールを起動。
migrateNullセイフティへの移行をサポート。
pubFlutter、dartのパッケージ管理ツール。pubspec.yamlでパッケージの依存関係を設定。pubspec.lock ファイルがある場合には、ファイルにリストされているバージョンを取得する。
runDartファイルを実行する。
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パッケージ依存関係管理用。
.gitignoreGitの管理対象から除外するファイルを記述。
lib/dev1.dartライブラリファイル。
analysis_options.yaml静的解析設定ファイル。
.dart_tool/package_config.jsonDartパッケージの名前解決に使用。

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 Platformaot-snapshot
exe
jit-snapshot
kernel
モバイル、デスクトップ用のコンパイル。
iOS、android、mac、Windows、Linux用。
Web PlatformjsJavaScriptへのコンパイル。
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開発で使うサポートツールと同じものかもしれない。

コメント

タイトルとURLをコピーしました