Pada bagian pertama, kami menemukan mengapa pembuatan kode diperlukan dan mendaftar alat yang diperlukan untuk pembuatan kode di Dart. Pada bagian kedua, kita akan belajar cara membuat dan menggunakan anotasi di Dart, serta cara menggunakan source_gen dan build_runner untuk memulai pembuatan kode.

Penjelasan Dart
Anotasi adalah metadata sintaksis yang dapat ditambahkan ke kode. Dengan kata lain, ini adalah kesempatan untuk menambahkan informasi tambahan ke komponen kode apa pun, misalnya, ke kelas atau metode. Anotasi banyak digunakan dalam kode Dart: kami menggunakan @required
untuk menunjukkan bahwa parameter bernama diperlukan, dan kode kami tidak akan dikompilasi jika parameter anotasi tidak ditentukan. Kami juga menggunakan @override
untuk menunjukkan bahwa API tertentu yang ditentukan dalam kelas induk diimplementasikan dalam kelas anak. Anotasi selalu dimulai dengan simbol @
.
Bagaimana cara membuat anotasi Anda sendiri?
Meskipun gagasan menambahkan metadata ke kode terdengar agak eksotis dan rumit, penjelasan adalah salah satu hal paling sederhana dalam bahasa Dart. Sebelumnya dikatakan bahwa anotasi hanya membawa informasi tambahan . Mereka mirip dengan PODO (Plain Old Dart Objects). Dan setiap kelas dapat berfungsi sebagai anotasi jika konstruktor const
didefinisikan di dalamnya :
class { final String name; final String todoUrl; const Todo(this.name, {this.todoUrl}) : assert(name != null); } @Todo('hello first annotation', todoUrl: 'https://www.google.com') class HelloAnnotations {}
Seperti yang Anda lihat, anotasi sangat sederhana. Dan yang penting adalah apa yang akan kita lakukan dengan anotasi ini. Ini akan membantu kami source_gen
dan build_runner
.
Bagaimana cara menggunakan build_runner?
build_runner
adalah paket Dart yang akan membantu kami menghasilkan file menggunakan kode Dart. Kami akan mengonfigurasi file Builder
menggunakan build.yaml
. Ketika dikonfigurasi, Builder
akan dipanggil pada setiap perintah build
atau ketika file diubah. Kami juga memiliki peluang untuk mem-parsing kode yang telah dimodifikasi atau memenuhi kriteria tertentu.
source_gen untuk memahami kode Dart
Dalam arti tertentu, build_runner
adalah mekanisme yang menjawab pertanyaan " Kapan saya perlu membuat kode?" Pada saat yang sama, source_gen
menjawab pertanyaan "Kode apa yang harus dihasilkan?". source_gen
menyediakan kerangka kerja untuk membuat Builder agar build_runner
berfungsi. source_gen
juga menyediakan API yang mudah digunakan untuk parsing dan menghasilkan kode.
Menyatukan semuanya: Laporan TODO
Di sisa artikel ini, kami akan membongkar proyek todo_reporter.dart , yang dapat ditemukan di sini .
Ada aturan tidak tertulis yang diikuti oleh semua proyek yang menggunakan pembuatan kode: Anda perlu membuat paket yang berisi anotasi , dan paket terpisah untuk generator yang menggunakan anotasi ini. Informasi tentang cara membuat pustaka paket di Dart / Flutter dapat ditemukan di sini .
Pertama, Anda perlu membuat direktori todo_reporter.dart
. Di dalam direktori ini Anda perlu membuat direktori todo_reporter
, yang akan berisi anotasi, direktori todo_reporter_generator
untuk memproses anotasi, dan, akhirnya, direktori example
berisi demonstrasi kemampuan perpustakaan yang sedang dibuat.
Sufiks .dart
ditambahkan ke nama direktori root untuk kejelasan. Tentu saja, ini tidak perlu, tetapi saya ingin mengikuti aturan ini untuk secara akurat menunjukkan fakta bahwa paket ini dapat digunakan dalam proyek Dart apa pun. Sebaliknya, jika saya ingin menunjukkan bahwa paket ini hanya untuk Flutter (seperti ozzie.flutter ), saya akan menggunakan akhiran yang berbeda. Ini tidak perlu, itu hanya konvensi penamaan yang saya coba patuhi.
Membuat todo_reporter, paket penjelasan sederhana kami
Kita akan membuat todo_reporter
di dalam todo_reporter.dart
. Untuk melakukan ini, buat file pubspec.yaml
dan direktori lib
.
pubspec.yaml
sangat sederhana:
name: todo_reporter description: Keep track of all your TODOs. version: 1.0.0 author: Jorge Coca <jcocaramos@gmail.com> homepage: https://github.com/jorgecoca/todo_reporter.dart environment: sdk: ">=2.0.0 <3.0.0" dependencies: dev_dependencies: test: 1.3.4
Tidak ada dependensi kecuali untuk paket test
yang digunakan dalam proses pengembangan.
Di direktori lib
, lakukan hal berikut:
- Anda perlu membuat file
todo_reporter.dart
, di mana, menggunakan export
, semua kelas yang memiliki API publik akan ditentukan. Ini adalah praktik yang baik, karena setiap kelas dalam paket kami dapat diimpor menggunakan import 'package:todo_reporter/todo_reporter.dart';
. Anda dapat melihat kelas ini di sini . - Di dalam direktori
lib
, kita akan membuat direktori src
berisi semua kode - publik dan non-publik.
Dalam kasus kami, semua yang perlu kami tambahkan adalah anotasi. Mari kita buat file todo.dart
dengan anotasi kami:
class Todo { final String name; final String todoUrl; const Todo(this.name, {this.todoUrl}) : assert(name != null); }
Jadi hanya itu yang diperlukan untuk membuat catatan. Saya mengatakan bahwa itu akan sederhana. Tapi itu belum semuanya. Mari menambahkan tes unit ke direktori test
:
todo_test.dart import 'package:test/test.dart'; import 'package:todo_reporter/todo_reporter.dart'; void main() { group('Todo annotation', () { test('must have a non-null name', () { expect(() => Todo(null), throwsA(TypeMatcher<AssertionError>())); }); test('does not need to have a todoUrl', () { final todo = Todo('name'); expect(todo.todoUrl, null); }); test('if it is a given a todoUrl, it will be part of the model', () { final givenUrl = 'http://url.com'; final todo = Todo('name', todoUrl: givenUrl); expect(todo.todoUrl, givenUrl); }); }); }
Ini yang kita butuhkan untuk membuat anotasi. Anda dapat menemukan kode di sini . Sekarang kita bisa pergi ke generator.
Membuat pekerjaan keren: todo_reporter_generator
Sekarang kita tahu cara membuat paket, mari kita buat paket todo_reporter_generator
. Di dalam paket ini harus ada build.yaml
dan build.yaml
dan direktori lib
. Direktori lib
harus memiliki direktori src
dan file builder.dart
. todo_reporter_generator
kami dianggap sebagai paket terpisah yang akan ditambahkan sebagai dev_dependency
ke proyek lain. Ini karena pembuatan kode hanya diperlukan pada tahap pengembangan, dan tidak perlu ditambahkan ke aplikasi yang sudah selesai.
pubspec.yaml
sebagai berikut:
name: todo_reporter_generator description: An annotation processor for @Todo annotations. version: 1.0.0 author: Jorge Coca <jcocaramos@gmail.com> homepage: https://github.com/jorgecoca/todo_reporter.dart environment: sdk: ">=2.0.0 <3.0.0" dependencies: build: '>=0.12.0 <2.0.0' source_gen: ^0.9.0 todo_reporter: path: ../todo_reporter/ dev_dependencies: build_test: ^0.10.0 build_runner: '>=0.9.0 <0.11.0' test: ^1.0.0
Sekarang mari kita buat build.yaml
. File ini berisi konfigurasi yang diperlukan untuk Pembangun kami. Rincian lebih lanjut dapat ditemukan di sini . build.yaml
sebagai berikut:
targets: $default: builders: todo_reporter_generator|todo_reporter: enabled: true builders: todo_reporter: target: ":todo_reporter_generator" import: "package:todo_reporter_generator/builder.dart" builder_factories: ["todoReporter"] build_extensions: {".dart": [".todo_reporter.g.part"]} auto_apply: dependents build_to: cache applies_builders: ["source_gen|combining_builder"]
Properti import
menunjuk ke file yang berisi Builder
, dan properti builder_factories
menunjuk ke metode yang akan menghasilkan kode.
Sekarang kita dapat membuat file builder.dart
di direktori lib
:
import 'package:build/build.dart'; import 'package:source_gen/source_gen.dart'; import 'package:todo_reporter_generator/src/todo_reporter_generator.dart'; Builder todoReporter(BuilderOptions options) => SharedPartBuilder([TodoReporterGenerator()], 'todo_reporter');
Dan file todo_reporter_generator.dart
di direktori src
:
import 'dart:async'; import 'package:analyzer/dart/element/element.dart'; import 'package:build/src/builder/build_step.dart'; import 'package:source_gen/source_gen.dart'; import 'package:todo_reporter/todo_reporter.dart'; class TodoReporterGenerator extends GeneratorForAnnotation<Todo> { @override FutureOr<String> generateForAnnotatedElement( Element element, ConstantReader annotation, BuildStep buildStep) { return "// Hey! Annotation found!"; } }
Seperti yang Anda lihat, dalam file builder.dart
kami mendefinisikan metode todoReporter
yang dibuat oleh Builder
. Builder
dibuat menggunakan SharedPartBuilder
, yang menggunakan TodoReporterGenerator
kami. Jadi build_runner
dan source_gen
bekerja bersama.
TodoReporterGenerator
kami adalah subkelas dari GeneratorForAnnotation
, jadi metode generateForAnnotatedElement
hanya akan dieksekusi ketika anotasi ini ( @Todo
dalam kasus kami) ditemukan dalam kode.
Metode generateForAnnotatedElement
mengembalikan string yang berisi kode yang kami hasilkan. Jika kode yang dihasilkan tidak dikompilasi, maka seluruh fase build akan gagal . Ini sangat berguna karena menghindari kesalahan di masa depan.
Jadi, dengan setiap pembuatan kode, todo_repoter_generator
kami akan membuat file part
, dengan komentar // Hey! Annotation found!
// Hey! Annotation found!
Pada artikel selanjutnya, kita akan belajar cara memproses anotasi.
Menyatukan semuanya: menggunakan todo_reporter
Sekarang Anda dapat mendemonstrasikan cara todo_reporter.dart
. Merupakan praktik yang baik untuk menambahkan example
proyek saat bekerja dengan paket. Jadi pengembang lain akan dapat melihat bagaimana API dapat digunakan dalam proyek nyata.
Mari kita membuat proyek dan menambahkan dependensi yang diperlukan ke pubspec.yaml
. Dalam kasus kami, kami akan membuat proyek Flutter di dalam direktori example
dan menambahkan dependensi:
dependencies: flutter: sdk: flutter todo_reporter: path: ../todo_reporter/ dev_dependencies: build_runner: 1.0.0 flutter_test: sdk: flutter todo_reporter_generator: path: ../todo_reporter_generator/
Setelah menerima paket (paket flutter packages get
) kita dapat menggunakan anotasi kami:
import 'package:todo_reporter/todo_reporter.dart'; @Todo('Complete implementation of TestClass') class TestClass {}
Sekarang semuanya sudah di tempat, jalankan generator kami:
$ flutter packages pub run build_runner build
Setelah perintah selesai, Anda akan melihat file baru di proyek kami: todo.g.dart
. Ini akan berisi yang berikut:
Kami mencapai apa yang kami inginkan! Sekarang kita dapat menghasilkan file Dart yang benar untuk setiap anotasi @Todo
dalam kode kita. Coba dan buat sebanyak yang Anda butuhkan.
Di artikel selanjutnya
Sekarang kami memiliki pengaturan yang benar untuk menghasilkan file. Pada artikel selanjutnya, kita akan belajar cara menggunakan anotasi sehingga kode yang dihasilkan dapat melakukan hal-hal yang sangat keren. Bagaimanapun, kode yang sedang dibuat sekarang tidak masuk akal.