@Import Annotation
How to import platform-specific libraries in shared components.
Jaspr components can be rendered both on the server and client. The same code will be compiled twice for the server and the web platform. Most of the time this isn't an issue, however sometimes you might want to use a package or library that is only supported on one side, e.g.:
dart:html
is only supported on the client,dart:io
is only supported on the server.
When you want to use such a library in your project, you would have to resort to conditional imports, which are quite cumbersome to use since you have to create multiple files and stub everything you want to use.
Jaspr can do this for you using the @Import
annotation. Say you have the following component:
import 'dart:html' show window;
import 'package:jaspr/jaspr.dart';
class App extends StatelessComponent {
@override
Iterable<Component> build(BuildContext context) sync* {
if (kIsWeb) {
window.alert('Hi Jaspr');
}
yield p([text('Hello World')]);
}
}
This component wants to show an alert when being built, but only on web. We can correctly use the kIsWeb
constant to check the platform during runtime, but this example would still lead to a
compile time error when running on the server - because dart:html
is unsupported there.
With Jasprs platform-specific imports you can change the code to this:
@Import.onWeb('dart:html', show: [#window])
import 'app.imports.dart';
import 'package:jaspr/jaspr.dart';
class App extends StatelessComponent {
@override
Iterable<Component> build(BuildContext context) sync* {
if (kIsWeb) {
window.alert('Hi Jaspr');
}
yield p([text('Hello World')]);
}
}
This will:
- generate the
app.imports.dart
file - setup conditional imports for
dart:html
on the web - write stubs on the server for all imported members.
There is a code-assist available from jaspr_lints
that converts your imports automatically!
See Linting.
You can extend this to multiple imports and mix web and server imports like this:
@Import.onWeb('dart:html', show: [#window])
@Import.onWeb('package:some_package', show: [#someMember])
@Import.onServer('dart:io', show: [#Platform])
import 'app.imports.dart';
The show
list must contain all the variables and types you want to access in your code, similar to
the import ... show ...;
syntax. Here each item in the list must be a symbol starting with #
.