Saltar al contenido principal

Dependencias de paquetes

Agrega otros paquetes a tu app. Especifica ubicaciones de paquetes, restricciones de versión y más.

Las dependencias son uno de los conceptos principales del gestor de paquetes pub. Una dependencia es otro paquete que tu paquete necesita para funcionar. Las dependencias se especifican en tu pubspec. Solo enumeras las dependencias inmediatas: el software que tu paquete utiliza directamente. Pub maneja las dependencias transitivasDependencia transitivaUna dependencia que un paquete utiliza indirectamente porque una de sus dependencias la requiere. Obtén más información por ti.

Esta página tiene información detallada sobre cómo especificar dependencias. Al final hay una lista de mejores prácticas para las dependencias de paquetes.

Descripción general

#

Para cada dependencia, especificas el nombre del paquete del que dependes y el rango de versiones de ese paquete que permites. También puedes especificar el origen (source)Origen de dependenciaUn tipo de lugar del que pub puede obtener paquetes. Obtén más información. El origen le indica a pub cómo localizar el paquete.

Como ejemplo, especificas una dependencia en el siguiente formato:

yaml
dependencies:
  transmogrify: ^1.0.0

Este código YAML crea una dependencia en el paquete transmogrify utilizando el repositorio de paquetes predeterminado (pub.dev) y permitiendo cualquier versión desde 1.0.0 hasta 2.0.0 (pero sin incluir 2.0.0). Para obtener información sobre esta sintaxis, consulta las restricciones de versión.

Para especificar un origen distinto de pub.dev, usa sdk, hosted, git o path. Por ejemplo, el siguiente código YAML utiliza path para indicarle a pub que obtenga transmogrify desde un directorio local:

yaml
dependencies:
  transmogrify:
    path: /Users/me/transmogrify

La siguiente sección describe el formato para cada origen de dependencia.

Orígenes de dependencia

#

Pub puede usar los siguientes orígenes para localizar paquetes:

Varios comandos de la herramienta dart también admiten la especificación de orígenes de dependencias directamente en la línea de comandos utilizando descriptores de paquete.

Paquetes alojados

#

Un paquete alojado (hosted) es aquel que se puede descargar desde el sitio pub.dev (u otro servidor HTTP que hable la misma API). Aquí hay un ejemplo de declaración de una dependencia en un paquete alojado:

yaml
dependencies:
  transmogrify: ^1.4.0

Este ejemplo especifica que tu paquete depende de un paquete alojado llamado transmogrify y funciona con cualquier versión desde 1.4.0 hasta 2.0.0 (pero no 2.0.0 en sí).

Si deseas utilizar tu propio repositorio de paquetes, puedes usar hosted para especificar su URL. El siguiente código YAML crea una dependencia en el paquete transmogrify utilizando el origen hosted:

yaml
environment:
  sdk: '^2.19.0'

dependencies:
  transmogrify:
    hosted: https://some-package-server.com
    version: ^1.4.0

La restricción de versión es opcional pero recomendada. Si no se proporciona ninguna restricción de versión, se asume any.

Paquetes Git

#

A veces vives en la vanguardia (bleeding edge) y necesitas usar paquetes que aún no se han lanzado formalmente. Tal vez tu propio paquete todavía está en desarrollo y está usando otros paquetes que se están desarrollando al mismo tiempo. Para facilitar esto, puedes depender directamente de un paquete almacenado en un repositorio Git.

yaml
dependencies:
  kittens:
    git: https://github.com/munificent/kittens.git

El git aquí indica que este paquete se encuentra usando Git, y la URL posterior es la URL de Git que se puede usar para clonar el paquete.

Incluso si el repositorio del paquete es privado, puedes configurar tu instalación de git para acceder al repositorio usando una clave de acceso HTTPS o un par de claves SSH. Luego puedes depender del paquete usando la URL correspondiente al repositorio:

yaml
dependencies:
  kittens:
    # SSH URL:
    git: git@github.com:munificent/kittens.git

El comando dart pub llama a git clone como un subproceso, por lo que todo lo que necesitas proporcionar es una <url> que funcione cuando se ejecute git clone <url>.

Si deseas depender de una confirmación (commit), rama o etiqueta específica, agrega una clave ref a la descripción:

yaml
dependencies:
  kittens:
    git:
      url: git@github.com:munificent/kittens.git
      ref: some-branch

La ref puede ser cualquier cosa que Git permita para identificar una confirmación (commit).

Si el paquete del que dependes ha etiquetado la revisión de cada versión del paquete, puedes usar tag_pattern en lugar de ref, junto con una restricción de versión.

Pub luego consultará a Git por todas las etiquetas coincidentes y proporcionará esas versiones al solucionador de versiones.

yaml
dependencies:
  kittens:
    git:
      url: git@github.com:munificent/kittens.git
      tag_pattern: v{{version}} # Find version-tag prefixed by 'v'.
    version: ^2.0.1

Pub asume que el paquete está en la raíz del repositorio Git. Para especificar una ubicación diferente en el repositorio, especifica una ruta (path) relativa a la raíz del repositorio:

yaml
dependencies:
  kittens:
    git:
      url: git@github.com:munificent/cats.git
      path: path/to/kittens

La ruta es relativa a la raíz del repositorio Git.

Las dependencias de Git no se permiten como dependencias para los paquetes cargados en pub.dev.

Paquetes de ruta (path)

#

A veces te encuentras trabajando en múltiples paquetes relacionados al mismo tiempo. Tal vez estés creando un framework mientras compilas una app que lo usa. En esos casos, durante el desarrollo realmente deseas depender de la versión en vivo (live) de ese paquete en tu sistema de archivos local. De esa manera, los cambios en un paquete se reflejan instantáneamente en el que depende de él.

Para manejar eso, pub admite dependencias de ruta (path dependencies).

yaml
dependencies:
  transmogrify:
    path: /Users/me/transmogrify

Esto indica que el directorio raíz para transmogrify es /Users/me/transmogrify. Para esta dependencia, pub genera un enlace simbólico (symlink) directamente al directorio lib del directorio del paquete referenciado. Cualquier cambio que realices en el paquete dependiente se verá de inmediato. No necesitas ejecutar pub cada vez que cambies el paquete dependiente.

Se permiten rutas relativas y se consideran relativas al directorio que contiene tu pubspec.

Las dependencias de ruta (path) son útiles para el desarrollo local, pero no funcionan al compartir código con el mundo exterior: no todos pueden acceder a tu sistema de archivos. Debido a esto, no puedes cargar un paquete al sitio pub.dev si tiene dependencias de ruta en su pubspec.

En su lugar, el flujo de trabajo típico es:

  1. Edita tu pubspec localmente para usar una dependencia de ruta (path).
  2. Trabaja en el paquete principal y en el paquete del que depende.
  3. Una vez que ambos estén funcionando, publica el paquete dependiente.
  4. Cambia tu pubspec para apuntar a la versión ahora alojada de su dependiente.
  5. Publica tu paquete principal también, si quieres.

Paquetes del SDK

#

El origen SDK se utiliza para cualquier SDK que se envíe junto con paquetes, los cuales a su vez podrían ser dependencias. Actualmente, Flutter es el único SDK compatible.

La sintaxis se ve así:

yaml
dependencies:
  flutter_driver:
    sdk: flutter

El identificador después de sdk: indica de qué SDK proviene el paquete. Si es flutter, la dependencia se puede satisfacer siempre que:

  • Pub se está ejecutando en el contexto del ejecutable flutter
  • El SDK de Flutter contiene un paquete con el nombre dado

Si es un identificador desconocido, la dependencia siempre se considera insatisfecha.

Descriptores de paquete

#

Varios comandos de la herramienta dart, como dart pub add y dart pub unpack, aceptan un descriptor de paquete después del nombre del paquete para especificar la versión o el origen de la dependencia de un paquete.

La forma más simple de un descriptor de paquete es una restricción de versión, asumiendo el origen predeterminado del sitio pub.dev. Por ejemplo, el siguiente comando usa un descriptor de ^1.2.3 para agregar una dependencia a package:foo con una restricción de ^1.2.3.

dart pub add foo:^1.2.3

Para especificar un origen de dependencia personalizado, usa la misma estructura que en pubspec.yaml, pero utilizando YAML de estilo flujo (flow-style YAML):

{<source>: <descriptor>, [version: <constraint>]}

Las siguientes subsecciones muestran la sintaxis del descriptor de paquete para cada tipo de origen de dependencia de pub.

Descriptor de dependencia alojada

#

Para especificar un paquete alojado (hosted):

{hosted: my-pub.dev}

También puedes especificar una restricción de versión:

{hosted: my-pub.dev, version: ^1.2.3}

Descriptor de dependencia de Git

#

Para especificar un paquete git:

{git: https://github.com/foo/foo}

Puedes especificar la URL del repositorio, una referencia de rama o confirmación (commit), y la ruta al paquete dentro del repositorio:

{git: {url: ../foo.git, ref: branch, path: subdir}}

Descriptor de paquete de ruta (path)

#

Para especificar un paquete de ruta (path):

{path: ../foo}

Descriptor de paquete del SDK

#

Para especificar un paquete del SDK:

{sdk: flutter}

Restricciones de versión

#

Supongamos que tu Paquete A depende del Paquete B. ¿Cómo puedes comunicar a otros desarrolladores qué versión del Paquete B sigue siendo compatible con una versión determinada del Paquete A?

Para que los desarrolladores conozcan la compatibilidad de versiones, especifica restricciones de versión. Querrás permitir el rango de versiones más amplio posible para dar flexibilidad a los usuarios de tu paquete. El rango debe excluir versiones que no funcionen o que no se hayan probado.

La comunidad de Dart utiliza el versionamiento semántico1.

Puedes expresar restricciones de versión usando tanto la sintaxis tradicional como la sintaxis de circunflejo (caret) a partir de Dart 2.19. Ambas sintaxis especifican un rango de versiones compatibles.

La sintaxis tradicional proporciona un rango explícito como '>=1.2.3 <2.0.0'. La sintaxis de intercalación (caret) proporciona una versión inicial explícita ^1.2.3

yaml
environment:
  # This package must use a 3.x version of the Dart SDK starting with 3.2.
  sdk: ^3.2.0

dependencies:
  transmogrify:
    hosted:
      name: transmogrify
      url: https://some-package-server.com
    # This package must use a 1.x version of transmogrify starting with 1.4.
    version: ^1.4.0

Para obtener más información sobre el sistema de versiones de pub, consulta la página de versionamiento de paquetes.

Sintaxis tradicional

#

Una restricción de versión que utiliza la sintaxis tradicional puede usar cualquiera de los siguientes valores:

Value Allows Use? Notes
any Todas las versiones No Sirve como una declaración explícita de restricción de versión vacía.
1.2.3 Solo la versión dada No Limita la adopción de tu paquete debido a los límites adicionales que impone a las apps que usan tu paquete.
>=1.2.3 Versión dada o posterior
>1.2.3 Versiones posteriores a la versión dada No
<=1.2.3 Versión dada o anterior No
<1.2.3 Versiones anteriores a la versión dada No Usa esto cuando conozcas una versión de límite superior que no funcione con tu paquete. Esta versión podría ser la primera en introducir algún cambio disruptivo.

Puedes especificar cualquier combinación de valores de versión a medida que sus rangos se intersecan. Por ejemplo, si estableces el valor de versión como '>=1.2.3 <2.0.0', esto combina ambas limitaciones, de modo que la dependencia puede ser cualquier versión desde la 1.2.3 hasta la 2.0.0 excluyendo la 2.0.0 en sí.

Sintaxis de intercalación (caret)

#

La sintaxis de intercalación (caret) expresa la restricción de versión de forma compacta. ^version significa el rango de todas las versiones garantizadas para ser compatibles con versiones anteriores con la versión dada. Este rango incluiría todas las versiones hasta la siguiente que introduzca un cambio disruptivo (breaking change). Como Dart utiliza el versionamiento semántico, esta sería la siguiente versión mayor para cualquier versión de paquete 1.0 o posterior o la siguiente versión menor para cualquier versión de paquete anterior a 1.0.

Valor de versión El rango cubre hasta Sintaxis de intercalación (caret) Sintaxis tradicional
>=1.0 Siguiente versión mayor ^1.3.0 '>=1.3.0 <2.0.0'
<1.0 Siguiente versión menor ^0.1.2 '>=0.1.2 <0.2.0'

El siguiente ejemplo muestra la sintaxis de intercalación (caret):

yaml
dependencies:
  # Covers all versions from 1.3.0 to 1.y.z, not including 2.0.0
  path: ^1.3.0
  # Covers all versions from 1.1.0 to 1.y.z, not including 2.0.0
  collection: ^1.1.0
  # Covers all versions from 0.1.2 to 0.1.z, not including 0.2.0
  string_scanner: ^0.1.2

Dependencias de desarrollo (dev)

#

Pub admite dos tipos de dependencias: dependencias regulares y dependencias de desarrollo (dev dependencies). Las dependencias de desarrollo se diferencian de las regulares en que las dependencias de desarrollo de los paquetes de los que dependes son ignoradas. Aquí hay un ejemplo:

Supongamos que el paquete transmogrify utiliza el paquete test en sus pruebas y únicamente en sus pruebas. Si alguien solo quiere usar transmogrify (importar sus bibliotecas), en realidad no necesita test. En este caso, especifica test como una dependencia de desarrollo. Su pubspec tendrá algo como:

yaml
dev_dependencies:
  test: ^1.25.0

Pub obtiene de forma transitiva cada paquete del que depende tu paquete, y todo aquello de lo que dependen esos paquetes. También obtiene las dependencias de desarrollo de tu paquete, pero ignora las dependencias de desarrollo de cualquier paquete dependiente. Pub solo obtiene las dependencias de desarrollo de tu paquete. Por lo tanto, cuando tu paquete depende de transmogrify, obtendrá transmogrify pero no test.

La regla para decidir entre una dependencia regular o de desarrollo es simple: si la dependencia se importa desde algo en tus directorios lib o bin, debe ser una dependencia regular. Si solo se importa desde test, example, etc., puede y debe ser una dependencia de desarrollo.

El uso de dependencias de desarrollo reduce el tamaño de los gráficos de dependencias. Esto hace que pub se ejecute más rápido y facilita la búsqueda de un conjunto de versiones de paquetes que satisfaga todas las restricciones.

Anulaciones de dependencias

#

Puedes usar dependency_overrides para anular temporalmente todas las referencias a una dependencia.

Por ejemplo, tal vez estés actualizando una copia local de transmogrify, un paquete publicado. Transmogrify es utilizado por otros paquetes en tu gráfico de dependencias, pero no deseas clonar cada paquete localmente y cambiar cada pubspec para probar tu copia local de transmogrify.

En esta situación, puedes anular la dependencia utilizando dependency_overrides para especificar el directorio que contiene la copia local del paquete.

El pubspec se vería algo así como lo siguiente:

yaml
name: my_app
dependencies:
  transmogrify: ^1.2.0
dependency_overrides:
  transmogrify:
    path: ../transmogrify_patch/

Cuando ejecutas dart pub get o dart pub upgrade, el archivo de bloqueo (lockfile) del pubspec se actualiza para reflejar la nueva ruta a tu dependencia y, dondequiera que se use transmogrify, pub usa la versión local en su lugar.

También puedes usar dependency_overrides para especificar una versión particular de un paquete:

yaml
name: my_app
dependencies:
  transmogrify: ^1.2.0
dependency_overrides:
  transmogrify: '3.2.1'

Solo se consideran las anulaciones de dependencias (dependency overrides en el propio pubspec de un paquete) durante la resolución del paquete. Las anulaciones de dependencias dentro de cualquier paquete del que se dependa son ignoradas.

Como resultado, si publicas un paquete en pub.dev, ten en cuenta que las anulaciones de dependencias de tu paquete serán ignoradas por todos los usuarios de tu paquete.

Si estás utilizando un pub workspace, puedes tener dependency_overrides en cada paquete del espacio de trabajo, pero un solo paquete solo se puede anular una vez en el espacio de trabajo.

pubspec_overrides.yaml

#

Si deseas cambiar ciertos aspectos de la resolución de tu archivo pubspec.yaml, pero no deseas cambiar el archivo real, puedes colocar un archivo llamado pubspec_overrides.yaml al lado del pubspec.yaml.

Los atributos de ese archivo anularán a los de pubspec.yaml.

Las propiedades que se pueden anular son:

  • dependency_overrides
  • workspace
  • resolution

Esto puede ser útil para evitar registrar accidentalmente anulaciones temporales en el control de versiones. También puede facilitar la generación de anulaciones a partir de un script.

En un pub workspace, cada paquete del espacio de trabajo puede tener un archivo pubspec_overrides.yaml.

Mejores prácticas

#

Sé proactivo al gestionar tus dependencias. Asegúrate de que tus paquetes dependan de las versiones más recientes de los paquetes cuando sea posible. Si tu paquete depende de un paquete desactualizado, ese paquete desactualizado podría depender de otros paquetes desactualizados en su árbol de dependencias. Las versiones desactualizadas de los paquetes pueden tener un impacto negativo en la estabilidad, el rendimiento y la calidad de tu app.

Recomendamos las siguientes mejores prácticas para las dependencias de paquetes.

Usar la sintaxis de intercalación (caret)

#

Especifica las dependencias usando la sintaxis de intercalación (caret). Esto permite que la herramienta pub seleccione versiones más nuevas del paquete cuando estén disponibles. Además, coloca un límite superior en la versión permitida.

Depender de las últimas versiones estables de los paquetes

#

Usa dart pub upgrade para actualizar a las últimas versiones de paquetes que permita tu pubspec. Para identificar dependencias en tu app o paquete que no estén en las últimas versiones estables, usa dart pub outdated.

Ajustar las restricciones de versión para las dependencias de desarrollo

#

Una dependencia de desarrollo (dev) define un paquete que necesitas únicamente al desarrollar. Una app terminada no necesitará estos paquetes. Ejemplos de estos paquetes incluyen pruebas o herramientas de generación de código. Establece las restricciones de versión de los paquetes en dev_dependencies para que tengan un límite inferior de la última versión de la que depende tu paquete.

Ajustar las restricciones de versión de tus dependencias de desarrollo podría parecerse a lo siguiente:

yaml
dev_dependencies:
  build_runner: ^2.14.1
  lints: ^6.1.0
  test: ^1.31.1

Este YAML establece las dev_dependencies a las últimas versiones de parches.

Probar cada vez que actualices las dependencias de paquetes

#

Si ejecutas dart pub upgrade sin actualizar tu pubspec, la API debería seguir siendo la misma y tu código debería ejecutarse como antes, pero pruébalo para asegurarte. Si modificas el pubspec y lo actualizas a una nueva versión mayor, entonces podrías encontrar cambios disruptivos, por lo que debes probar de manera aún más exhaustiva.

Probar con dependencias degradadas

#

Al desarrollar paquetes para su publicación, a menudo es preferible permitir las restricciones de dependencia más amplias posibles. Una restricción de dependencia amplia reduce la probabilidad de que los consumidores de paquetes se enfrenten a un conflicto de resolución de versiones.

Por ejemplo, si tienes una dependencia en foo: ^1.2.3 y se lanza la versión 1.3.0 de foo, podría ser razonable mantener la restricción de dependencia existente (^1.2.3). Pero si tu paquete comienza a usar características que se agregaron en la versión 1.3.0, entonces necesitarás aumentar tu restricción a ^1.3.0.

Sin embargo, es fácil olvidar aumentar una restricción de dependencia cuando se vuelve necesario. Por lo tanto, es una mejor práctica probar tu paquete contra dependencias degradadas antes de publicar.

Para probar contra dependencias degradadas, ejecuta dart pub downgrade y verifica que tu paquete aún se analice sin errores y pase todas las pruebas:

dart pub downgrade
dart analyze
dart test

Las pruebas con dependencias degradadas deben ocurrir junto con las pruebas normales con las dependencias más recientes. Si es necesario aumentar las restricciones de dependencia, cámbialas tú mismo o usa dart pub upgrade --tighten para actualizar las dependencias a las últimas versiones.

Verificar la integridad de los paquetes descargados

#

Al recuperar nuevas dependencias, usa la opción --enforce-lockfile para garantizar que el contenido extraído del paquete coincida con el contenido del archivo original. Sin modificar el archivo de bloqueo (lockfile)LockfileUn archivo llamado pubspec.lock que especifica las versiones de cada dependencia. Obtén más información, esta bandera solo resuelve nuevas dependencias si:

  • pubspec.yaml está satisfecho
  • pubspec.lock no falta
  • Los hashes de contenidoHash de contenido de PubHashes SHA256 mantenidos por pub.dev para validar la integridad del paquete. Obtén más información de los paquetes coinciden