Dartのディレクティブたち
ディレクティブという単語がそれらのみを指しているのかわかりませんが、importやexportなどのライブラリの読み込みに関する単語のまとめです。
普段importとasぐらいしか使わないけど、そういえばいろいろあったよなーと思い、まとめ始めたらなんか知らないのまで出てきました。
ディレクティブたち
- 
library
- ライブラリに名前をつけるために使用します。
 - 後述の
importを用いて読み込むことのできるものはすべてライブラリです。 - 
libraryと明示しなくても、Dartで書かれたアプリケーションは自動的にタグがつけられて一つのライブラリとして扱われます。[1] - ライブラリレベルでドキュメントを書かないのであれば
libraryは省略することが推奨されています。[2]Note: When the
librarydirective isn’t specified, a unique tag is generated for each library based on its path and filename. Therefore, we suggest that you omit thelibrarydirective from your code unless you plan to generate library-level documentation. 
library my_library; // 省略可 - 
import
- ライブラリを読み込むために使用します。
 - 同じパッケージ内のライブラリ(自身がいる
lib内にある別のライブラリ)を読み込む時はpackage:で始まる明示的なパスで指定せず、相対パスを使用する。[3] 
lib/my_library.dartimport 'package:my_package/src/other_library.dart'; // Bad import 'src/other_library.dart'; // Good - 
export
- 外部に公開するライブラリを指定するために使用します。メインのライブラリに
exportを記述することで、メインのライブラリを読み込むだけでexportで指定されたライブラリにもアクセスできます。 
lib/my_library.dartexport 'src/foo.dart'; export 'src/bar.dart';someones_library.dartimport 'package:my_library/my_library.dart'; void main() { foo(); // foo.dart内にある関数 bar(); // bar.dart内にある関数 } - 外部に公開するライブラリを指定するために使用します。メインのライブラリに
 - 
part
- 後述の
part ofとセットで使用されます。 - 一つのライブラリを複数のファイルに分割するために使用します。
 - 公式からは
partとpart ofでのファイル分割よりも、個別のライブラリとして分割してimportでアクセスすることが推奨されています。[4]Note: You may have heard of the
partdirective, which allows you to split a library into multiple Dart files. We recommend that you avoid usingpartand create mini libraries instead. 
my_library.dartlibrary my_library; part 'src/part_a.dart'; part 'src/part_b.dart'; - 後述の
 - 
part of
- 先述の
partとセットで使用されます。 - 一つのライブラリを複数のファイルに分割するために使用します。
 - 
part ofディレクティブはDartの歴史的理由でそれ自身が属している(part ofである)ライブラリの名前を使用できるようですが、他のディレクティブと同様にそのライブラリへのパスを文字列で指定することが推奨されています。[5] 
part of my_library; // Bad part of '../../my_library.dart'; // Goodpart_a.dartpart of '../../my_library.dart';part_b.dartpart of '../../my_library.dart'; - 先述の
 
オプション的なものたち
- 
show
- 指定したクラスや関数のみを参照します。
 
import 'package:other_package/other_package.dart' show SomeClass; - 
hide
- 指定したクラスや関数を参照しないようにします。
 
import 'package:other_package/other_package.dart' hide SomeClass; - 
as
- 読み込むパッケージに名前をつけて呼び出す際のプレフィックスとし、クラス名や関数名の競合を避けます。
 
import 'package:other_package/other_package.dart' as otherPackage ;たとえば
これまでFirebase Authenticationのプラグインでは認証ユーザーをFirebaseUserとしていましたが、最近のアップデートでUserに変更されました。認証機能を使うようなアプリであればUserクラスは自身で作成することになると思います。そうすると、自身のアプリで使用されるUserクラスとFirebase Authenticationプラグインで提供されるUserクラスが競合してしまいます。そこでasを用いてFirebase Authenticationのプラグインに名前をつけて参照することでコンフリクトを解消することができます。import 'package:firebase_auth/firebase_auth.dart' as firebase_auth;firebase_auth.User firebaseUser = firebase_auth.User(); User user = User(); 
- 
deferred
はじめまして。すみません、この記事書くまで知りませんでした。- 必要になるまで対象ライブラリの読み込みを後回しにします。
 - 
loadLibrary()で対象ライブラリを読み込みます。 - 
loadLibrary()を実行するためにasで名前をつける必要があります。deferredというよりdeferred asかもしれません。 
library_a.dartimport 'package:library_b/library_b.dart' deffered as library_b; void main() { // library_b.bar(); foo(); } Future foo() async { // ここでやっと読み込み await library_b.loadLibrary(); library_b.bar(); }library_a.dartimport 'package:library_b/library_b.dart' deferred as library_b; void main() { library_b.bar(); // ここで呼び出してしまうとエラー foo(); } Future foo() async { await library_b.loadLibrary(); library_b.bar(); }Unhandled exception: Deferred library library_b was not loaded. - 
組み合わせ
library import export part part of show ✕ ○ ○ ✕ ✕ hide ✕ ○ ○ ✕ ✕ as ✕ ○ ✕ ✕ ✕ deferred ✕ ○ ✕ ✕ ✕  
記述スタイル
- 
ライブラリ、パッケージ、ディレクトリ、ソースファイル名はスネークケースで命名する[6]
// Good library peg_parser.source_scanner; import 'file_system.dart'; import 'slider_menu.dart';// Bad library pegparser.SourceScanner; import 'file-system.dart'; import 'SliderMenu.dart'; - 
プレフィックスを指定して
importする際はスネークケースを用いる[7]// Good import 'dart:math' as math; import 'package:angular_components/angular_components' as angular_components; import 'package:js/js.dart' as js;// Bad import 'dart:math' as Math; import 'package:angular_components/angular_components' as angularComponents; import 'package:js/js.dart' as JS; 
順番
- 
dart:で始まるライブラリはその他のライブラリより前に記述する[8]import 'dart:async'; import 'dart:html'; import 'package:bar/bar.dart'; import 'package:foo/foo.dart'; - 
package:で始まるライブラリは相対パスで記述するライブラリより前に記述する[9]import 'package:bar/bar.dart'; import 'package:foo/foo.dart'; import 'util.dart'; - 
exportはimportのセクションより後に切り離して記述する[10]// Good import 'src/error.dart'; import 'src/foo_bar.dart'; export 'src/error.dart';// Bad import 'src/error.dart'; export 'src/error.dart'; import 'src/foo_bar.dart'; - 
それぞれのセクション内はアルファベット順に並べる[11]
// Good import 'package:bar/bar.dart'; import 'package:foo/foo.dart'; import 'foo.dart'; import 'foo/foo.dart';// Bad import 'package:foo/foo.dart'; import 'package:bar/bar.dart'; import 'foo/foo.dart'; import 'foo.dart'; - 
asはshowとhideより前に記述する// Good import 'package:foo/foo.dart' as foo show Hoge hide Fuga;// Bad import 'package:foo/foo.dart' show Hoge hide Fuga as foo; 
Effective Dart
各ディレクティブの解説の多くは公式ドキュメント内のEffective Dartからの引用です。
Dartに関する様々なガイドが提供されていますのでぜひ読んでみてください。
参考
- 
Effective Dart: DO use relative paths when importing libraries within your own package’s lib directory. ↩︎
 - 
Effective Dart: DO name import prefixes using lowercase_with_underscores.
↩︎ - 
Effective Dart: DO name libraries, packages, directories, and source files using lowercase_with_underscores. ↩︎
 - 
Effective Dart: DO name import prefixes using lowercase_with_underscores.
↩︎ - 
Effective Dart: DO place “dart:” imports before other imports. ↩︎
 - 
Effective Dart: DO place “package:” imports before relative imports. ↩︎
 - 
Effective Dart: DO specify exports in a separate section after all imports. ↩︎
 
Discussion