-
Notifications
You must be signed in to change notification settings - Fork 880
Conventions for Dart Samples
This page describes our conventions for Dart samples on angular.io and in other places that feature Angular 2 & Dart.
Contents
-
Guidelines
- Use the stagehand web-angular template
-
Follow the structure of the TypeScript example (mostly)
- Keep #docregion comments
- Import the same files
- Which files go where?
- web
- test
- lib
-
Follow the guidelines in Effective Dart
- Use alphabetical import order
- Use lowercase_underscore_separation in filenames
- Run dartfmt on all your code
- Readability
- Line length
-
Quote consistently
- Use single quotes in Dart code*
- Use double quotes in HTML
-
Use consistent spacing
- In inline templates
- In HTML & templates
- Tell your reviewers about Dart differences from TS
- TODO
The template-syntax example, complex as it is, is probably a good one to emulate. It’s the only one (as of 3/1) that has a good .analysis_options file.
https://github.com/google/stagehand/tree/master/templates/web-angular
If you use WebStorm, you can choose this template whenever you create a new project.
Has the stagehand template fallen behind the current release? Do you disagree with something it does? Please submit an issue or, better yet, a pull request! The template is used by IDEs such as WebStorm, so improvements to the template benefit a wide audience.
Improvements we should probably make:
- add
<meta name="viewport" ...>
to the index.html header, like angular.io has in all its TS examples- add web/styles.css
TypeScript has it only because of build cruft.
Use the template-syntax .analysis_options file as a template. This file will help the analyzer make sure your example declares return types, annotates overrides, and more.
(To avoid cluttering the published sample, dart-doc-syncer will not put this file in the sample’s repo.)
Your app should look like the equivalent TS app, so you should test with web/styles.css, which you can copy from styles.css.
But don’t add web/styles.css to the angular.io repo. dart-doc-syncer will copy styles.css to the sample’s repo.
They’re already covered by the site license and the docs.
On angular.io, the docs include code from the samples, so writing the docs is hell unless the # of files and the #docregions they contain are exactly the same as the TypeScript versions. We do modify the files’ names and locations, but minimally.
Here’s a comparison of the files for user-input.
TypeScript file | Dart file |
index.html styles.css (none) |
web/index.html (none) pubspec.yaml |
.gitignore example-config.js onplnkr.json |
(none) (none) (none) |
app/app.component.html app/app.component.ts app/click-me.component.ts app/click-me2.component.ts app/keyup.components.ts app/little-tour.component.ts app/loop-back.component.ts app/main.ts |
lib/app_component.dart lib/app_component.html lib/click_me_component.dart lib/click_me_component_2.dart lib/keyup_components.dart lib/little_tour_component.dart lib/loop_back_component.dart web/main.dart |
For details about the TypeScript structure, see Angular 2 Naming Conventions and Structure.
#docregion
and #docplaster
comments are needed for importing the code into the
chapters. Avoid unnecessary changes to code that’s inside a #docregion
.
We used to say import angular2/angular2.dart, not angular2/core.dart or other subsets. Because Dart has tree shaking! But Miško says, “For consistency we should recommend that TS and Dart have the same imports. There are some issues about Mirrors, and code gen which will be easier with more fine grained imports.”
Don’t use show
.
For example, say you’re converting a TypeScript file that has these imports:
import {Component, AfterViewInit, ElementRef, OnInit, QueryList, ViewChildren}
from 'angular2/core';
import {NgForm} from 'angular2/common';
import {Hero} from './hero';
import {HeroDetailComponent, BigHeroDetailComponent} from
'./hero-detail.component';
import {MyClickDirective, MyClickDirective2} from './my-click.directive';
The corresponding Dart file should have these imports:
import 'package:angular2/common.dart';
import 'package:angular2/core.dart';
import 'hero.dart';
import 'hero_detail_component.dart';
import 'my_click_directive.dart';
The application entry-point and its assets: main.dart, index.html, styles.css
Testing code. We don’t have much yet.
Everything else. (Keeping the majority of files under lib/ makes apps more testable.)
- Don’t use subdirectories unless the TS version does. Components, services, and directives have suffixes instead of being in their own subdirectories. Examples: blah_component.dart, blab_service.dart, blob_directive.dart
- Share names between related Dart, HTML, & CSS files. E.g.: blah_component.dart, blah_component.html, blah_component.css.
Also: Don’t use library
directives. We don’t need ‘em any more! More info: Creating Library Packages.
https://www.dartlang.org/effective-dart/style/#ordering
In Atom, you can do this using Ctrl+Shift+o (https://github.com/dart-atom/dartlang/blob/master/keymaps/atom-dart.cson#L57).
In WebStorm or IntelliJ, you can alphabetize everything in the file, but there’s no way to alphabetize just the imports. [PENDING: We should file and link to a feature request to allow alphabetizing imports.]
Also, use relative paths when importing from lib to lib.
Example:
import 'dart:libname';
import 'dart:libname_thats_alphabetically_later';
import 'package:packagename/filename.dart';
import 'package:packagename/filename_thats_alphabetically_later.dart';
import 'package:packagename_thats_alphabetically_later/filename.dart';
import '../superdir/path/to/filename.dart';
import '../superdir2/path/to/filename.dart';
import 'filename.dart';
import 'some_other_filename.dart';
import 'subdir/filename.dart';
import 'yet_another_filename.dart';
File (and directory) names should be lowercase (a-z0-9) and use only underscores (_) to separate words, up until the final suffix (which is dot-separated, as usual). Don’t use spaces in filenames.
Examples:
- app.component.html -> app_component.html
- hero-detail.component.ts -> hero_detail_component.dart
Run dartfmt on all your code
Don’t modify dartfmt’s output unless it’s unreadable or expands the sample too much vertically.
angular.io uses the default 80-character line length. dartlang.org uses 70 characters/line.
Here’s an example of running dartfmt when you want 70 characters/line:
dartfmt -w -l 70 path/to/file.dart # formats file.dart (70 chars/line)
Alternatively, specify a directory path, which makes dartfmt format all the .dart files under that directory.
dartfmt -w path # formats every .dart file in path, path/to, etc.
# (without -l, this has 80 chars/line)
If dartfmt’s output is hard to read or uses too much space vertically, fix it in your code. Then tell Kathy about the problem and where it occurred, so she knows not to use dartfmt on that file.
[PENDING: put example here]
Reduce string length, if necessary, to reduce the length of included lines to 80 (or less). dartfmt can’t do this for you. Here’s an example of a line that I reduced from 90 (not counting indentation) to 62.
// OLD
drive() => '$description car with ${engine.cylinders} cylinders and ${tires.make} tires.';
// NEW
drive() => '$description car with '
'${engine.cylinders} cylinders and ${tires.make} tires.';
main() {
print('Hello Angular!');
}
*The exception: It’s OK to use double quotes in strings that contain single
quotes, to avoid escaping the single quote. Example: "I'm OK"
In both Dart and HTML files, use double quotes for HTML.
@Component(
selector: 'my-app',
template: '''
<h2>My favorite hero is: {{myHero.name}}</h2>
<p *ngIf="heroes.length > 3">There are many heroes!</p>''')
We haven’t done this consistently before, but let’s indent inline templates 2
spaces, compared to the template: '''
line above them. For example:
@Component(
selector: 'my-app',
template: '''
<h1>{{title}}</h1>
<h2>My favorite hero is: {{myHero}}</h2>''')
Do this | NOT this | Explanation |
{{something}} |
{{ something }} |
Don’t put spaces between the moustaches and their contents. |
<div> 2-space indent </div> |
<div> 4 spaces or tab </div> |
Use 2-space indents in HTML (4 spaces for continuations), just as in Dart. Don’t use tab characters. To set this up in WebStorm, use Preferences > Editor > Code Style > HTML. |
It’s important that we (1) use Dart well and (2) tell Dart developers about any gotchas and differences from TS.
Please make notes about:
- What surprised you when you wrote/translated the app?
- What was really awkward in Dart but not in TS, or vice versa?
- What code/techniques did you use that were especially cool or horrible?
- What did you want/have to change when translating from TS, and why?
- Edit the web-angular template, so that it perfectly adheres to these guidelines.
- Ditto with user-input.
- Ditto with the rest of the existing samples.