
DartでのWeb開発は超簡単
Flutter Web が安定版になり、今では「Dart で Web アプリを書く」と聞けば Flutter を思い浮かべる人が多いと思います。ただ、Flutter なしでも Dart で Web アプリは作れますし、始めるのもかなり簡単です。
準備
まだ Dart SDK が入っていないなら、こちらから手に入ります。自分の OS 向けの手順どおりに入れて、終わったらここに戻ってきてください。
次に、webdevとstagehandをターミナルのどこからでも呼べるようにしておきます。下の 2 つのコマンドを実行してください。
pub global activate webdev
pub global activate stagehand
stagehandを入れると Dart プロジェクトの立ち上げが楽になります。webdevのほうは、開発中の Web アプリをローカルで動かしたり、本番用にビルドしたりといった作業を任せられるツールです。
プロジェクトの生成
Stagehand には、コンソールアプリ、パッケージ、Web サーバー、Web アプリ用のジェネレーターがそろっています。ここで欲しいのはシンプルな Web アプリのひな形だけなので、プロジェクト用のフォルダを作り、そのフォルダの中でstagehand web-simpleを実行します。
mkdir my_new_project
cd my_new_project
stagehand web-simple
生成が済んだらpub getを実行して、必要な依存関係を取ってきてください。こんな構成のプロジェクトができあがります。

プロジェクトの配信とビルド
さきほど入れたwebdevツールのおかげで、開発中のプロジェクトをローカルで動かすのは簡単です。

webdev serveを実行するだけで、http://127.0.0.1:8080でページが見られます。

本番向けにビルドする段階になったら、webdev buildを実行します。できあがった静的サイトのコードはbuildフォルダに入ります。あとはこのフォルダを、静的サイトを置ける場所(Github Pages や S3 など)にアップロードするだけです。
Sass でスタイリッシュに
小さくてシンプルなサイトをこの作り方で組むとき、私が気に入っているのはscssがほとんど手間なしで使えるところです。
まず、sass_builderパッケージをプロジェクトに追加します。リンク先で最新バージョンを確認して、pubspec.yamlのdev_dependenciesにこう書き足してください。
dev_dependencies:
build_runner: ^1.10.0
build_web_compilers: ^2.11.0
pedantic: ^1.9.0
sass_builder: ^2.1.3
こうしておけば、scssやsassのファイルは同じ名前のcssファイルにビルドされます。webフォルダにstyle.scssを置いておくと、ビルド後にはbuildフォルダにstyle.cssができるわけです。
HTML の中では、スタイルファイルをcssの名前で参照してください。web/style.scssがあるなら、web/index.htmlにはこう書きます。
<link rel="stylesheet" href="style.css" />
参照するのは元のscssではなく、ビルドされたあとのファイルだからです。
では、スタイルを当てられる HTML を用意しましょう。あとで HTTP リクエストの例にも使います。
<div id="app">
<main>
<img id="good-boy" />
<button id="get-good-boy">Good Boy!</button>
</main>
</div>
styles.scssにもSCSSを少し足します。
#app {
min-height: 100vh;
width: 100vw;
display: flex;
align-items: center;
justify-content: center;
main {
max-width: 500px;
width: 100%;
display: flex;
flex-direction: column;
img,
button {
width: 100%;
}
}
}
Dio でフェッチリクエストを処理
この書き方でシンプルな Web アプリを作るもう一つの利点は、数多くある Dart のライブラリをそのまま使えることです。
たとえば Flutter で Dio を使い慣れているなら、ここでも通信処理は Dio に任せられます。
まず、pubspec.yamlにDioを依存関係として追加します。
dependencies:
dio: ^3.0.10
main.dartの先頭には、次の import を書いておきます。
import 'dart:html';
import 'dart:convert';
import 'package:dio/dio.dart';
dart:htmlがquerySelectorメソッドと各種要素の型をくれます。dart:convertは JSON のレスポンスをマップに変換するのに使い、dioはもちろんDioのためです。
ではmain関数の中で必要な要素を取ってきて、ボタンにイベントリスナーを付けましょう。
void main() async {
ImageElement dogImage = querySelector('#good-boy');
ButtonElement dogButton = querySelector('#get-good-boy');
dogButton.addEventListener('click', (Event event) async {
dogImage.src = await getGoodBoy();
});
}
ここまでは特に難しいところはないでしょう。あとは、いちばんいい子の写真を無料の犬画像 API から取ってくるgetGoodBoyボタンを作るだけです。
Future<String> getGoodBoy() async {
final uri = 'https://dog.ceo/api/breed/akita/images/random';
final response = await Dio().get(uri);
Map<String, dynamic> body = jsonDecode(response.toString());
return body['message'];
}
これで完成です!うまく動いていれば、"Get Good Boy"ボタンを押すとこんな画面が出てくるはずです!

この記事は元々 dev.to に掲載されています。