Saltar al contenido principal

Creación de paquetes

Aprende a crear paquetes en Dart.

El ecosistema de Dart utiliza paquetes para compartir software como bibliotecas y herramientas. Esta página te explica cómo crear un paquetePaqueteUn directorio con una colección de bibliotecas Dart, recursos y un archivo pubspec.yaml que los describe. Obtén más información estándar compartido.

Crear un nuevo paquete

#

Para crear el directorio y la estructura iniciales de un paquete, utiliza el comando dart create y la plantilla package:

dart create -t package <PACKAGE_NAME>

Para obtener más información sobre las plantillas disponibles y cómo utilizar la flag -t, consulta la documentación de dart create.

Qué conforma un paquete

#

El siguiente diagrama muestra la estructura más simple de un paquete:

el directorio raíz contiene pubspec.yaml y lib/file.dart

Los requisitos mínimos para una biblioteca son:

archivo pubspec

El archivo pubspec.yaml de una biblioteca es idéntico al de un paquete de aplicación (application package)Paquete de aplicaciónUn paquete Dart que contiene una aplicación ejecutable. Obtén más información; no existe ninguna designación especial que indique que el paquete es una biblioteca.

directorio lib

Como es de esperar, el código de la biblioteca reside en el directorio lib y es público para otros paquetes. Puedes crear cualquier jerarquía bajo lib según lo necesites. Por convención, el código de implementación se coloca bajo lib/src. El código bajo lib/src se considera privado; otros paquetes nunca deberían necesitar importar src/.... Para hacer públicas las APIs bajo lib/src, puedes exportar los archivos de lib/src desde un archivo que esté directamente bajo lib.

Organizar un paquete

#

Los paquetes son más fáciles de mantener, extender y probar cuando creas bibliotecas pequeñas e individuales, denominadas mini bibliotecas (mini libraries). En la mayoría de los casos, cada clase debería estar en su propia mini biblioteca, a menos que tengas una situación en la que dos clases estén estrechamente acopladas.

Crea un archivo de biblioteca "principal" directamente bajo lib, lib/<nombre-del-paquete>.dart, que exporte todas las APIs públicas. Esto permite al usuario obtener toda la funcionalidad de la biblioteca importando un único archivo.

El directorio lib también podría incluir otras bibliotecas importables que no pertenezcan a src. Por ejemplo, tal vez tu biblioteca principal funcione en múltiples plataformas, pero creas bibliotecas separadas que dependen de dart:io o dart:js_interop. Algunos paquetes tienen bibliotecas separadas destinadas a ser importadas con un prefijo, mientras que la biblioteca principal no lo requiere.

Echemos un vistazo a la organización de un paquete del mundo real: shelf. El paquete shelf proporciona una forma sencilla de crear servidores web usando Dart, y está estructurado de una manera que se utiliza comúnmente en los paquetes Dart:

el directorio raíz de shelf contiene los subdirectorios example, lib, test y tool

Directamente bajo lib, el archivo de biblioteca principal, shelf.dart, exporta APIs de varios archivos en lib/src. Para evitar exponer más API de la prevista—y para ofrecer a los desarrolladores una visión general de toda la API pública del paquete—shelf.dart utiliza show para especificar exactamente qué símbolos exportar:

lib/shelf.dart
dart
export 'src/cascade.dart' show Cascade;
export 'src/handler.dart' show Handler;
export 'src/hijack_exception.dart' show HijackException;
export 'src/middleware.dart' show Middleware, createMiddleware;
export 'src/middleware/add_chunked_encoding.dart' show addChunkedEncoding;
export 'src/middleware/logger.dart' show logRequests;
export 'src/middleware_extensions.dart' show MiddlewareExtensions;
export 'src/pipeline.dart' show Pipeline;
export 'src/request.dart' show Request;
export 'src/response.dart' show Response;
export 'src/server.dart' show Server;
export 'src/server_handler.dart' show ServerHandler;

El paquete shelf también contiene una mini biblioteca: shelf_io. Este adaptador maneja objetos HttpRequest de dart:io.

Importar archivos de biblioteca

#

Al importar un archivo de biblioteca de otro paquete, utiliza la directiva package: para especificar la URI de ese archivo.

dart
import 'package:utilities/utilities.dart';

Al importar un archivo de biblioteca de tu propio paquete, utiliza una ruta relativa cuando ambos archivos estén dentro de lib, o cuando ambos archivos estén fuera de lib. Usa package: cuando el archivo importado esté en lib y el importador esté fuera.

El siguiente gráfico muestra cómo importar lib/foo/a.dart tanto desde lib como desde web.

lib/bar/b.dart utiliza una importación relativa; web/main.dart utiliza una importación de paquete

Importar y exportar archivos de biblioteca de forma condicional

#

Si tu biblioteca es compatible con múltiples plataformas, entonces es posible que necesites importar o exportar archivos de biblioteca de forma condicional. Un caso de uso común es una biblioteca que admite tanto la web como las plataformas nativas.

Para importar o exportar condicionalmente, necesitas verificar la presencia de bibliotecas dart:*. Aquí tienes un ejemplo de código de exportación condicional que verifica la presencia de dart:io y dart:js_interop:

lib/hw_mp.dart
dart
export 'src/hw_none.dart' // Stub implementation
    if (dart.library.io) 'src/hw_io.dart' // dart:io implementation
    if (dart.library.js_interop) 'src/hw_web.dart'; // package:web implementation

Esto es lo que hace ese código:

  • En una aplicación que puede usar dart:io (por ejemplo, una aplicación de línea de comandos), exporta src/hw_io.dart.
  • En una aplicación que puede usar dart:js_interop (una aplicación web), exporta src/hw_web.dart.
  • De lo contrario, exporta src/hw_none.dart.

Para importar un archivo de forma condicional, utiliza el mismo código que arriba, pero cambia export por import.

Todas las bibliotecas exportadas condicionalmente deben implementar la misma API. Por ejemplo, aquí está la implementación de dart:io:

lib/src/hw_io.dart
dart
import 'dart:io';

void alarm([String? text]) {
  stderr.writeln(text ?? message);
}

String get message => 'Hello World from the VM!';

Y aquí está la implementación por defecto, que utiliza stubs que lanzan UnsupportedError:

lib/src/hw_none.dart
dart
void alarm([String? text]) => throw UnsupportedError('hw_none alarm');

String get message => throw UnsupportedError('hw_none message');

En cualquier plataforma, puedes importar la biblioteca que contiene el código de exportación condicional:

dart
import 'package:hw_mp/hw_mp.dart';

void main() {
  print(message);
}

Proporcionar archivos adicionales

#

Un paquete bien diseñado es fácil de probar. Recomendamos que escribas pruebas utilizando el paquete test, colocando el código de prueba en el directorio test en la raíz del paquete.

Si creas herramientas de línea de comandos destinadas al uso público, colócalas en el directorio bin, que es público. Permite ejecutar una herramienta desde la línea de comandos utilizando dart pub global activate. Listar la herramienta en la sección executables del pubspec permite a un usuario ejecutarla directamente sin llamar a dart pub global run.

Es de gran ayuda incluir un ejemplo de cómo utilizar tu biblioteca. Este va en el directorio example en la raíz del paquete.

Cualquier herramienta o ejecutable que crees durante el desarrollo y que no sea para uso público va en el directorio tool.

Otros archivos requeridos si publicas tu biblioteca en el sitio pub.dev, como README.md y CHANGELOG.md, se describen en la sección de Publicación de un paquete. Para obtener más información sobre cómo organizar el directorio de un paquete, consulta las convenciones de diseño de paquetes de pub (pub package layout conventions).

Documentar una biblioteca

#

Puedes generar la documentación de la API para tu biblioteca utilizando la herramienta dart doc. dart doc analiza el código fuente buscando comentarios de documentación, los cuales utilizan la sintaxis ///:

dart
/// The event handler responsible for updating the badge in the UI.
void updateBadge() {
  ...
}

Para ver un ejemplo de documentación generada, consulta la documentación de shelf.

Para incluir documentación a nivel de biblioteca (library-level) en los documentos generados, añade una directiva library y adjunta el comentario directamente encima de ella. Para conocer el cómo y el porqué de la documentación de bibliotecas, consulta Effective Dart: Documentación.

Distribuir una biblioteca de código abierto

#

Si tu biblioteca es de código abierto, te recomendamos compartirla en el sitio de pub.dev. Para publicar o actualizar la biblioteca, utiliza pub publish, que sube tu paquete y crea o actualiza su página. Por ejemplo, consulta la página para el paquete shelf. Consulta la sección de Publicación de un paquete para obtener detalles sobre cómo preparar tu paquete para la publicación.

El sitio pub.dev no solo aloja tu paquete, sino que también genera y aloja la documentación de referencia de la API de tu paquete. Un enlace a la última documentación generada se encuentra en el cuadro About del paquete; por ejemplo, consulta los documentos de la API (API docs) del paquete shelf. Los enlaces a los documentos de las versiones anteriores se encuentran en la pestaña Versions de la página del paquete.

Para asegurarte de que los documentos de la API de tu paquete se vean bien en el sitio pub.dev, sigue estos pasos:

  • Antes de publicar tu paquete, ejecuta la herramienta dart doc para asegurarte de que tus documentos se generen correctamente y se vean como se espera.
  • Después de publicar tu paquete, revisa la pestaña Versions para asegurarte de que los documentos se hayan generado correctamente.
  • Si los documentos no se generaron en absoluto, haz clic en failed en la pestaña Versions para ver la salida de dart doc.

Recursos

#

Utiliza los siguientes recursos para aprender más sobre paquetes: