Library Splitting in Dart

The part/part of keywords

Introduction

part:This keyword is used within a Dart file to indicate that the file is part of another file. The purpose is to include this file's contents into a single library, alongside the contents of the other file(s) designated as part of the same library.

part of: It is used in the Dart files that are included as parts of another file. It indicates that the file is not standalone and should be considered as part of the library defined in another file. The file that uses part of must be included by the main library file using the part directive.

Use case example

Let's use the example of building a car using part/part of directives. You're designing and building all parts of the car in-house (engine, tires, etc.), and you want to organize the design files for better manageability.

CarLib.dart

// This is the main library file that declares all parts of the car.
part 'EnginePart.dart';
part 'TiresPart.dart';

class Car {
  void startCar() {
    Engine().start();
    Tires().roll();
  }
}

EnginePart.dart:

part of 'CarLib.dart';

class Engine {
  void start() => print("Engine started");
}

TiresPart.dart:

part of 'CarLib.dart';

class Tires {
  void roll() => print("Tires rolling");
}

EnginePart.dart and TiresPart.dart are parts of the whole CarLib.dart. They can share private members among themselves because they're considered a single library (CarLibrary.dart). If Engine had a private method _privateStart, it could be called from TiresPart.dart or any other part of the same library.

The import keyword

Introduction

Used to include code from one file into another. This is like getting a tool from another toolbox to use in your current project. When you import a file, you're bringing in its public interfaces (such as classes, functions, and variables marked as public) so you can use them in your file. Ideal for reusing code and libraries without sharing the internal workings.

Use case example

When building a car, you might need parts from different manufacturers: the engine from one company, the tires from another, and so on. Each of these parts has its own specifications and functionalities, and you integrate them into your car.

Engine.dart

class Engine {
  void start() => print("Engine started");
}

Tires.dart

class Tires {
  void roll() => print("Tires rolling");
}

CarLib.dart

import 'Engine.dart';
import 'Tires.dart';

class Car {
  Engine engine = Engine();
  Tires tires = Tires();

  void startCar() {
    engine.start();
    tires.roll();
  }
}

import allows your Car.dart to use functionalities (like starting the engine or the tires rolling) from other files (Engine.dart and Tires.dart). However, if there are private methods or properties in Engine or Tires , you can't access them directly in Car.dart because they are encapsulated within their respective files

Summary

  • import is like sourcing car parts from different companies. Each part (file) is independent, and you can only use what is publicly available.

  • part/part of is like designing and building every part of the car in-house, where all designs (files) are part of a single project, and every detail (including private ones) is accessible within the project.