blob: aa2301518873d6561226d752c08912a3bd2c5d9f [file] [view]
# Jaspr Component Trees record_use
Jaspr is a web framework. The goal is to generate a minimal CSS file containing
only the styles used in a Jaspr application. This is achieved by using
`record_use` to extract information about which components are used and what
styles they apply. This enables a "Tailwind-like" experience where developers
use style utilities and the final CSS is tree-shaken.
For example, a `Column` component might have styling options passed to its
constructor:
<!-- no-source-file -->
```dart
class Column extends Component {
@RecordUse()
const Column({this.spacing = 0, this.crossAxisAlignment = 'start'});
@override
Iterable<Component> build(BuildContext context) {
// ...
}
}
```
When this component is used, we want to record the constructor call, including
the arguments:
<!-- no-source-file -->
```dart
class MyComponent extends Component {
@override
Iterable<Component> build(BuildContext context) {
return [
Column(spacing: 42, crossAxisAlignment: 'center'),
];
}
}
```
A link-time hook can then process all recorded uses of `Column`. From the
`spacing` and `crossAxisAlignment` arguments, it can generate the required CSS
rules and emit them into a single CSS file for the application:
```css
.column-spacing-42 {
padding: 42px;
}
.column-cross-axis-center {
align-items: center;
}
```
## Information required for CSS generation
To generate the CSS, the link hook needs to know about all constructor calls to
components that are annotated with `@RecordUse`.
* **`const` constructor calls**:
These are the most common in component trees. We need to record the static
calls to these `const` constructors and the values of their arguments.
See: https://github.com/dart-lang/native/issues/2911
* **`const` instances**:
`const` instances of components are also common. The hook needs to be aware
of these instances and their field values.
(We are _not_ interested in any of these const instances occurring in
annotations, such as https://github.com/dart-lang/native/issues/2719.)
* **Non-`const` constructor calls**:
Component trees are not always `const`. To ensure all styles are captured, we
also need to record non-`const` constructor calls.
See: https://github.com/dart-lang/native/issues/2907
By collecting this information, a tool can build a complete picture of which
styling primitives are used in an application and generate an optimized CSS file.
## Links
* https://github.com/schultek/jaspr
* https://github.com/schultek/universal_widgets