Chuyển đến nội dung chính

Bài đăng

Hiển thị các bài đăng có nhãn CI

Viết một lint tuỳ chỉnh cho codebase Dart của bạn

Nhóm nào cũng có một quy tắc cứ bị phá vỡ hoài. “Đừng dùng context sau một await.” “Repository trả về Result , không bao giờ ném lỗi.” “Không print trong lib/ .” Chúng sống trong một bình luận review, được giải thích lại cho từng người mới, rồi tuần sau lại bị vi phạm. Một luật của analyzer thì không bao giờ mệt khi phải nhắc đi nhắc lại. Trước hết, dùng cạn các luật có sẵn Trước khi viết bất cứ thứ gì, hãy kiểm tra xem luật đó đã tồn tại chưa. Linter đi kèm hơn hai trăm luật, và phần lớn quy ước của nhóm nằm trong số đó. Một cấu hình đáng để bắt đầu: # analysis_options.yaml include : package:flutter_lints/flutter.yaml analyzer : language : strict-casts : true strict-raw-types : true errors : invalid_annotation_target : ignore unused_import : error dead_code : error exclude : - "**/*.g.dart" - "**/*.freezed.dart" linter : rules : - always_declare_return_types - avoid_print - prefer_final_locals...

Sinh mã trong Dart: build_runner mà không bực mình

Bạn thêm json_serializable , chạy dart run build_runner build , và nhận được: Conflicting outputs were detected and the build will be terminated. Bạn chạy lại với --delete-conflicting-outputs , nó chạy được, và từ đó bạn gõ cờ này mãi mãi mà không biết nó đã xoá gì. Đó là mối quan hệ điển hình giữa lập trình viên và build_runner, và nó đáng được sửa, vì công cụ này dễ đoán hơn vẻ ngoài của nó. Mô hình: một asset vào, một asset ra build_runner không phải bộ chạy script. Nó là một hệ thống build trên asset — những file được định danh theo dạng package:name|path . Mỗi builder khai báo nó tiêu thụ phần mở rộng nào và sinh ra phần mở rộng nào, và build_runner dựng một đồ thị từ đó. json_serializable nói: với mỗi .dart , có thể sinh ra một .g.dart . freezed nói: với mỗi .dart , có thể sinh ra một .freezed.dart . Vì đầu ra được đánh khoá theo đường dẫn, hai builder cùng nhận một đường dẫn đầu ra sẽ xung đột — và một builder cũng xung đột với chính đầu ra cũ của nó còn nằm trên đĩa từ...

Writing a custom lint for your Dart codebase

Every team has a rule that keeps getting broken. “Don’t call context after an await.” “Repositories return Result , never throw.” “No print in lib/ .” These live in a code review comment, get re-explained to each new joiner, and get violated again the week after. An analyzer rule does not get tired of saying it. First, exhaust the built-in rules Before writing anything, check whether the rule already exists. The linter ships with well over two hundred rules, and most team conventions are among them. A configuration worth starting from: # analysis_options.yaml include : package:flutter_lints/flutter.yaml analyzer : language : strict-casts : true strict-raw-types : true errors : invalid_annotation_target : ignore unused_import : error dead_code : error exclude : - "**/*.g.dart" - "**/*.freezed.dart" linter : rules : - always_declare_return_types - avoid_print - prefer_final_locals - unawaite...

Code generation in Dart: build_runner without the frustration

You add json_serializable , run dart run build_runner build , and get: Conflicting outputs were detected and the build will be terminated. You run it with --delete-conflicting-outputs , it works, and you type that flag forever afterwards without knowing what it deleted. That is the typical relationship developers have with build_runner, and it is worth fixing, because the tool is more predictable than it looks. The model: one asset in, one asset out build_runner is not a script runner. It is a build system over assets — files identified as package:name|path . Every builder declares which extensions it consumes and which it produces, and build_runner constructs a graph from that. json_serializable says: for every .dart , maybe produce a .g.dart . freezed says: for every .dart , maybe produce a .freezed.dart . Because outputs are keyed by path, two builders that claim the same output path conflict — and so does one builder whose previous output is still on disk from a run with d...

Writing a custom lint for your Dart codebase

Every team has a rule that keeps getting broken. “Don’t call context after an await.” “Repositories return Result , never throw.” “No print in lib/ .” These live in a code review comment, get re-explained to each new joiner, and get violated again the week after. An analyzer rule does not get tired of saying it. First, exhaust the built-in rules Before writing anything, check whether the rule already exists. The linter ships with well over two hundred rules, and most team conventions are among them. A configuration worth starting from: # analysis_options.yaml include : package:flutter_lints/flutter.yaml analyzer : language : strict-casts : true strict-raw-types : true errors : invalid_annotation_target : ignore unused_import : error dead_code : error exclude : - "**/*.g.dart" - "**/*.freezed.dart" linter : rules : - always_declare_return_types - avoid_print - prefer_final_locals - unawaite...

Code generation in Dart: build_runner without the frustration

You add json_serializable , run dart run build_runner build , and get: Conflicting outputs were detected and the build will be terminated. You run it with --delete-conflicting-outputs , it works, and you type that flag forever afterwards without knowing what it deleted. That is the typical relationship developers have with build_runner, and it is worth fixing, because the tool is more predictable than it looks. The model: one asset in, one asset out build_runner is not a script runner. It is a build system over assets — files identified as package:name|path . Every builder declares which extensions it consumes and which it produces, and build_runner constructs a graph from that. json_serializable says: for every .dart , maybe produce a .g.dart . freezed says: for every .dart , maybe produce a .freezed.dart . Because outputs are keyed by path, two builders that claim the same output path conflict — and so does one builder whose previous output is still on disk from a run with d...