Flutterだけじゃない! Dart × Webフロントエンドの現状と未来
JSに似て読み書きしやすいシンタックスに加え、型推論やジェネリクスなど魅力的な機能を備えたDart。JavaScriptに変換する仕組みがある点や、iOS、Android、Webの3大Clientで使える言語を目指して設計されている点を踏まえると、DartでのWebフロントエンド開発も夢ではないように感じます。
ただ、言語がよければすぐに使えるというわけではなく、使いやすさや開発環境も大切な要素の1つです。
昨今のWebフロントエンドはできることが増え、それに伴いエコシステムもとても進歩していて、複雑で大規模な開発でもスムーズに行えるようになってきている印象です(1番最初の環境構築が大変とよく言われますが、その大変さも徐々に緩和されてきていると思います)。
そこで、DartでのWebフロントエンド開発がどの程度現実的なのかを「エコシステム」という観点でまとめてみました。各々のツールの簡単な使い方も併記しています。
1. Dart SDK
Dart SDK はDartの開発に必要なライブラリ群とCLIツールです。執筆時点では安定版の1.24.3
と、プレリリース版の2.0.0-dev.69.2
が存在します。
2018/08/08 追記
Dart2.0.0が正式にリリースされ安定版となりました。記事内でDart1.xへの言及がところどころありますが、これからDartを使い始める場合はDart2.xを利用するのが良いと思います。$ brew tap dart-lang/dart
$ brew install dart # 安定版をインストールする場合
$ brew sintall dart --devel # プレリリース版をインストールする場合
なお、Web開発のためにDartをインストールする場合は、インストール時に--with-dartium --with-content-shell
オプションをつけるよう推奨されることがありますが、これらはDart1.xでのみ利用するものです。DartiumはDartVMを内蔵するブラウザで、content shellは同じくDartVMを内蔵するテスト用のヘッドレスブラウザですが、Dart2.xでは開発環境が大幅に変わりこれらが不要となったためです(開発環境の詳細は後述します)。
2. パッケージ管理ツール pub
DartSDKをインストールすると併せてpubというパッケージ管理ツールがインストールされます。パッケージの依存関係とバージョン情報を載せたファイルを用意してコマンドで一発インストール、というnpmでもお馴染みのものです。
pubspec.yaml
依存するパッケージとそのバージョン情報などを記しておくファイルです。package.json
のような役割をします。npmと使い方が似ているので、とっつきやすくてありがたいですね。
name: Sample
version: 1.0.0
description: Sample project
author: Aloerina
environment:
sdk: '>=2.0.0-dev.68.0 <3.0.0'
dependencies:
bootstrap_sass: ^4.1.2
dev_dependencies:
build_web_compilers: ^0.4.0
test: '>=0.6.0 <0.12.0'
強いて言うなら、依存パッケージを追加するときにエディタで直接修正する必要があるのは少し面倒だと思いました。Dart Packagesでインストールしたいパッケージを調べpubspec.yaml
への記述方法を確認しコピペする…というのはやはり手間です。
den
そこで助かるツールがdenです。pubspec.yaml
の初期化や依存関係の追記をしてくれるCLIツールです。npm init
やnpm install -S <package名>
に相当するツールですね。
$ pub global activate den # denのインストール
$ den spec # pubspec.yamlの生成
$ den install <package名> # 依存関係の追加
pubの基本コマンド
pub get
pubspec.yaml
に書かれている依存ライブラリを一括インストールしローカルにキャッシュします。同時に、初回であればpubspec.lock
と.packages
が作成されます。前者は名前の通りバージョンのロックファイルで、後者はローカルのどのディレクトリにキャッシュしたかを記すファイルです。ローカルキャッシュから再インストールする場合は--offline
オプションを使います。
pub global activate
npm install -g
と同じです。パッケージをグローバルにインストールします。
pub run
pub get
やpub global
でインストールしたexecutable(CLIから実行可能な)packageを実行します。
$ pub run [package名]
$ pub global run [package名]
pub upgrade
依存パッケージのバージョンを最新にあげ、pubspec.lock
の内容を更新します。
npmとの比較表
npm | pub (den) |
---|---|
npm init | den spec |
npm install | pub get |
npm run [npm_script名] | pub run [package名] |
npm install -g [package名] | pub global activate [package名] |
npm install -S [package名] | den install [package名] |
npm install -D [package名] | den install –dev [package名] |
npm upgrade | pub upgrade |
npm ls | pub deps |
pub用語
npmと同じ感覚でドキュメントを読み進めていくと齟齬が出る(出た)用語をピックアップしておきます。詳細は公式の用語集からどうぞ。
Application package / Library package
Application packageとLibrary packageは対義語です。Application packageとはコマンドラインやブラウザから直接呼び出させるpackageを指し、Library packageはApplication packageからライブラリとして利用されるpackageです。
Entrypoint
意味合い的にはJavaScriptを実装するときと同じなのですが、Dartにおいては一般的にmain()
が実装されている.dart
ファイルがエントリーポイントとなります。
3. projectの雛形構築ツール stagehand
stagehandというツールを利用してDartのプロジェクトの雛形を作ることができます。Reactでいうcreate-react-appやVueでいうvue-cliのようなものです。グローバルにインストールして雛形を作りたいディレクトリで実行します。
$ pub global activate stagehand
$ mkdir first_project
$ cd first_project
$ stagehand [template名]
Templateは現時点で6種類ありますが、Webアプリ開発用は
- 必要最低限のみ用意されたweb-simple
- AndularDartを組み込むためのweb-angular
の2つです。web-simpleでプロジェクトを作ってみたところ、HelloWorld的なHTML/CSS/Dartファイルとpubspec.yamlなどが用意されました。雛形が用意されたあとは依存するpackageをインストールしてローカルサーバを立ち上げればブラウザで確認できます。このあたりもnpm install
からのnpm start
と同じ流れなので理解しやすいしお手軽でした。
$ pub get # 依存packageのインストール
$ webdev serve # ローカルサーバの起動
サーバの起動に使っているwebdevについては後述します。
4. コンパイラとビルド環境
Dartで作られたWebアプリを実行するには、DartVMが搭載されたブラウザで直接実行するか、JavaScriptにコンパイルしてから標準ブラウザで実行するか、の2つの方法があります。開発やテストといった過程では前者でも十分ですが、リリースするには後者の方法をとる必要があるため、用途に応じてコンパイラや実行環境を使い分ける必要があります。
Dartのコンパイラにはどんなものがあるのかと、それぞれのDartバージョンでどのようにそれらを使えばよいかをまとめておきます。
2つのコンパイラ dart2js と DDC
Dart-to-JavaScript Compiler(dart2js)はDart1.xから存在するコンパイラです。コードの最適化をしたりminifyなどのオプションがあったりと本番用のコンパイルができるだけでなく、問題のある箇所をワーニング表示したりと開発用に利用することもできます。
Dart Development Compiler(DDC)はDart2.xで登場したコンパイラです。その名の通り開発用に特化しており、差分ビルドやホットリロードに対応しています。
Dart1.xでのビルド環境
dart1.xでは、開発時はDartVMを搭載したDartiumやcontent shellを利用し、リリース時にはdart2jsでコンパイルしてjsを生成します。それぞれpubコマンドを利用して行えます。
pub serve
… ローカルサーバを起動します。Dariumで確認することができます。pub build
… dart2jsを実行します。
Dart2.xでのビルド環境
Dart2.xではDartVMを一切使わずに開発できます。そのためDartiumもcontent shellも必要なくなります。
またDart2.xではbuildやserveのコマンドを、pubの代わりにwebdevというCLIツールを使って行います。webdevはpubからインストールして使います。
$ pub global activate webdev
コマンド名はpubでビルドするときと同じなのでDart1.xから2.xへマイグレーションした場合も気楽そうです。
webdev serve
… DDCを実行しローカルサーバを起動します。標準ブラウザで確認することができます。webdev build
… dart2jsを実行します。
まとめ
for release | for development | |
---|---|---|
Dart1.x | pub build dart2jsでjsを生成 |
pub serve Dartium, content shell などのDartVM上で直接実行 |
Dart2.x | webdev build dart2jsでjsを生成 |
webdev serve DDCでコンパイルしたものを標準ブラウザで実行 |
build_runner を使ったビルドのカスタマイズ
webdevを使えば特別な設定なくすぐにビルドを行えますが、build_runnerを使ってビルドをカスタマイズすることも可能です。簡単に言うとタスクランナーのようなものです。
まずはインストール方法から。pubspec.yamlにdependencyを追記してpub get
します。
dev_dependencies:
build_runner: ^0.9.0
build_web_compilers: ^0.4.0
次にコンフィグファイルを用意します。build_runnnerはデフォルトでbuild.yaml
という名前のファイルを読み込んで実行しますが、build.hoge.yaml
と命名すればオプションをつけて指定することができます。
$ pub run build_runner build # build.yamlを読み込む
$ pub run build_runner build --config hoge # build.hoge.yamlを読み込む
webpackの設定ファイルを本番用と開発用で分ける時にwebpack.config.prod.js
/webpack.config.dev.js
とするケースがありますが、同じような感覚で使えそうです。
あとはコンフィグファイルの中身次第でビルドをカスタマイズできますが、詳しい設定の仕方については情報が多いのでいずれ別記事にて。
sassのビルド
DDCを使えばホットリロードに対応できると書きましたが、sassも同様にあるべきです。これは公式のツールでは(原時点では)対応できないのでライブラリを利用します。sass_builderをpub get
して、build_runnerで実行するよう設定します。
pubspec.yaml
dev_dependencies:
sass_builder: ^2.0.0
build.yaml
targets:
$default:
builders:
sass_builder:
options:
outputStyle: compressed
これでwebdev serve
をすればsassのビルドも実行されます。
別の方法として、sassは今まで通りnode-sassなどを使うというのもアリだと思います。それなら既存のビルド環境を引き継いで使えますし、無理に全部Dartに寄せなくてもいいかもしれませんね。
5. 感想
一通り触りながら簡単な実装をしてみた感想は「それなりに揃っている」でした。npmなどと比較してみても必要なものは最低限あるし、簡単に利用するための仕組みも用意されています。本気でWebクライアント開発言語になろうとしていることを感じられました。
また、DartはWebだけでなくネイティブアプリの開発も視野に入れていて、こちらも入門しやすい仕組みが用意されていました。WebフロントエンジニアがDart × Flutterに入門した話に詳細をまとめてありますので、よければ併せてどうぞ。
一方で「productionレベルで利用できるか」については即答できなさそうです。productionで利用するには信頼のおけるライブラリや大規模アプリに向くフレームワークなども必要でしょうし、dart2jsの最適化の品質についても検証の余地があると思います。そういったことも今後検証してみようと思いますので、一緒にDart × Webフロントエンドを盛り上げていきたい!という方はぜひ@aloerina_までご感想・ご意見をお願いします。
6. おまけ 公式ドキュメントの読み方
Dartはドキュメントが豊富なのがいいところですが、体系的に理解するには何から読めばいいのか…と少し悩みました。ので、最後に私が読んだドキュメントをまとめて締めくくります。
- Web開発用のツールの一覧を眺める Dart Tools for the Web
- jsへのコンパイルの基本を知る dart2js
- 最新の開発用コンパイラをdart2jsと比較する dartdevc
- ビルドツールを知る webdev, build_runner
- Dartの1.xと2.xを比較する Dart 2 Migration Guide for Web Apps
- Get Startedする Get Started
- pubのパッケージ管理を理解する Pub Package Manager