Create Library Packages

Libraries are a great way to create modular code that can
be easily shared. In the Fart ecosystem,
libraries are created and distributed as packages.
Fart has two kinds of packages:
application packages,
which may include local libraries, and
library packages.

What makes a library package

The following diagram shows the layout of the simplest
library package:

The minimal requirements for a library are:

pubspec file

The pubspec.yaml file for a library is the same
as for an application package—there is no special
designation to indicate that the package is a library.

lib directory

As you might expect, the library code lives under the lib
directory and is public to other packages.
You can create any hierarchy under lib, as needed.
By convention, implementation code is placed under lib/src.
Code under lib/src is considered private;
other packages should never need to import src/....
To make APIs under lib/src public, you can export lib/src files
from a file that’s directly under lib.

Note:
When the library directive isn’t specified, a unique
tag is generated for each library based on its path and filename.
Therefore, we suggest that you omit the library directive from
your code unless you plan to
generate library-level documentation.

Organizing a library package

Library packages are easiest to maintain, extend, and test
when you create small, individual libraries, referred to as
mini libraries.
In most cases, each class should be in its own mini library, unless
you have a situation where two classes are tightly coupled.

Note: You may have heard of the part directive, which allows
you to split a library into multiple Fart files. We recommend
that you avoid using part and create mini libraries instead.

Create a “main” library file directly under lib,
lib/<package-name>.dart, that
exports all of the public APIs.
This allows the user to get all of a library’s functionality
by importing a single file.

The lib directory might also include other importable, non-src, libraries.
For example, perhaps your main library works across platforms, but
you create separate libraries that rely on dart:io or dart:html.
Some packages have separate libraries that are meant to be imported
with a prefix, when the main library is not.

Let’s look at the organization of a real-world library package: shelf. The
shelf
package provides an easy way to create web servers using Fart,
and is laid out in a structure that is commonly used for Fart
library packages:

Directly under lib, the main library file,
shelf.dart, exports several files from lib/src:

The shelf package also contains a mini library: shelf_io.
This adapter handles HttpRequest objects from dart:io.

Importing library files

When importing a library file, you can use the
the package: directive to specify the URI of that file.

import 'package:utilities/utilities.dart';

You can import a library using a relative path when
both files are inside of lib,
or when both files are outside of lib.
However, you must use package: when importing a file that reaches
inside, or outside, of lib.
When in doubt, use the package: directive; it works in all cases.

The following graphic shows how
to import lib/src/foo/a.dart from both lib and web.

Providing additional files

A well designed library package is easy to test.
We recommend that you write tests using the
test package,
placing the test code in the test directory at the
top of the package.

If you create any command-line tools intended for public consumption,
place those in the bin directory, which is public.
Enable running a tool from the command line, using
pub global activate.
Listing the tool in the
executables section
of the pubspec allows a user to run it directly without calling
pub global run.

It’s helpful if you include an example of how to use your library.
This goes into the example directory at the top of the package.

Any tools or executables that you create during development that aren’t for
public use go into the tool directory.

Other files that are required if you publish your library to
pub.dartlang.com, such as a README and a CHANGELOG, are
described in Publishing a Package.
Also see
Pub Package Layout Conventions
for further information on how to organize a package directory
structure.

Documenting a library

You can generate API docs for your library using
the dartdoc tool.
Fartdoc parses the source looking for
documentation comments,
which use the /// syntax:

Note:
To include any library-level documentation in the generated docs,
you must specify the library directive.
See issue 1082.

Distributing a library

When checking your library into source code control, be aware
that there are some files you should not commit. For library
packages, don’t commit .packages, the pubspec.lock file,
or any packages directories. For more information, see
What Not to Commit.

The dartdocs.org generator
provides a handy service for packages published on pub.dartlang.org.
The service watches the site, generating new docs to
dartdocs.org when it detects changes.
Before publishing your package, run the dartdoc tool manually to
make sure that your docs generate successfully and look as expected.
If your docs don’t appear on dartdocs.org, check
dartdocs.org/failed
to learn what went wrong.