Dart / Flutter Conditional Imports

Over the past few years, Dart and Flutter have really gained popularity. Along with the growth in popularity has come a plethora of new features added to both the Dart language and the Flutter GUI tool kit. Some of the most popular new features are support for new platforms such as web and desktops (Windows, Linux, macOS). Google seems to be aiming high with the Dart/Flutter combination producing a tool kit to allow one project (and one set of source files) to work across all supported platforms. While they are closing in on that goal, some believe it is impossible to completely realize this dream while others believe they are not far off. All, however, will agree that they are not quite there yet.

If you work with multi-platform projects in Flutter, particularly those including web support, you’ll soon find yourself in a situation where you need to use code on one platform that isn’t supported on the web, or code that is only supported on the web. If this were C or C++ we could just #ifdef <PLATFORM> and include our needed code, excluding any unneeded code in an #ELSE clause, and be done with it. But this isn’t C or C++.

So, what to do? At first, you might think that you use a test such as if(kIsWeb) and that would do the trick. But if you try this, it won’t compile on mobile or desktop. It will fail because it can’t find dart:js for the target platform. kIsWeb is not a compile-time constant and this means it will be evaluated at runtime. So this cannot be resolved by the tree-shaker.

Mobile targets don’t have the js library and will fail to import dart:js at compile time. However, Dart does support conditional imports, and here is where we can put them to good use! The syntax for conditional imports is as follows:

import "some_library.dart" if (dart.library.io) "some_other_library.dart" 

This simple conditional import allows us to choose what to import at compile time depending on the target platform. This is very handy for Mobile and web but can also be useful for desktop as well.

However, it should be noted that you should limit the test conditions to those defined by the Dart VM. This pretty much limits you to testing for the presence of libraries. What you don’t want to do is use custom conditions. Most of the time you’ll mostly be interested in checking if you’re deploying to the browser or VM. You can easily do this by checking if dart.library.io or dart.library.js is defined:

if (dart.library.io) {
  /// VM Code here
  ...
/// OR
if (dart.library.js) {
  /// browser code here
  ...

Also, don’t forget that some of the design patterns can come in very handy when dealing with platform issues. The Factory Patterns can be used to create objects based on some conditions passed to the factory. These conditions could include the platform type the application is running on…

Happy Coding!

Leave a Reply

Your email address will not be published. Required fields are marked *