Skip to main content

Usando Plugins

⏱ Dedicación recomendada: 0 minutos
Esto considera el contenido visible y relevante, e ignora texto colapsado o marcado como opcional.


r8vnhill/echo-app-kt
r8vnhill/echo-app-groovy

Aplicación de plugins

Gradle ofrece varias formas de aplicar plugins en el bloque plugins. A continuación, se presentan los métodos más comunes:

Aplicación directa

Aplicación por ID con versión

Esta es la forma más habitual de aplicar un plugin, especificando su ID y versión:

plugins {
id("some.plugin") version "1.0.0"
}

Aplicación por ID sin versión

Si gestionas las versiones de los plugins en un archivo centralizado como libs.versions.toml, puedes omitir la versión directamente en el bloque plugins. Este es el método recomendado para proyectos que usan una gestión centralizada de versiones:

plugins {
id("some.plugin")
}

Uso de alias para plugins (desde un catálogo de versiones)

Gradle permite definir alias en un archivo libs.versions.toml (u otro catálogo de versiones) para simplificar la declaración de plugins en los scripts de construcción. Un alias es un nombre corto y descriptivo que hace referencia a un plugin específico, lo que facilita su gestión y reutilización en múltiples subproyectos.

Definiendo un alias en libs.versions.toml

Primero, definimos el alias para el plugin en el catálogo de versiones. Esto centraliza la configuración y facilita futuras actualizaciones de versiones.

gradle/libs.versions.toml
[plugins]
some-plugin = { id = "org.example.some-plugin", version = "1.2.3" }
Aplicando el alias en los scripts de construcción

Una vez definido el alias, podemos utilizarlo en nuestros scripts de construcción para aplicar el plugin de manera concisa y consistente.

build.gradle.kts
plugins {
alias(libs.plugins.some.plugin)
}
Beneficios de usar alias
  • Centralización de versiones: Facilita la actualización de versiones de plugins desde un único lugar, evitando inconsistencias.
  • Mayor legibilidad: Los alias descriptivos hacen que los scripts de construcción sean más fáciles de leer y mantener.
  • Reutilización: Permite aplicar fácilmente el mismo plugin en múltiples subproyectos sin redundancia.

Aplicación por nombre "simple"

Algunos plugins integrados de Gradle, como java-library o application, pueden aplicarse de manera más concisa utilizando su nombre directamente. Si el nombre del plugin contiene caracteres especiales, como guiones (-), usa comillas invertidas:

plugins {
`java-library` // Con comillas invertidas debido al guion
application // Sin comillas porque no contiene caracteres especiales
}

Aplicación mediante funciones específicas (Kotlin DSL)

Algunos plugins, como el de Kotlin, tienen funciones específicas en Kotlin DSL, lo que mejora la legibilidad y facilita el uso de diferentes configuraciones dentro del mismo bloque:

plugins {
kotlin("jvm") version "2.0.20"
kotlin("js") version "2.0.20"
// En lugar de utilizar 2 plataformas diferentes, puedes usar una sola función
// kotlin("multiplatform") version "2.0.20"
}

Estas son las principales formas de aplicar plugins en Gradle usando el bloque plugins. El uso de alias y la gestión centralizada de versiones en libs.versions.toml es recomendable para mantener una consistencia en la versión de los plugins en proyectos grandes.

Aplicación mediante apply

El método apply permite aplicar plugins de forma dinámica en cualquier parte del script de construcción de Gradle. A diferencia de la aplicación directa en el bloque plugins, donde los plugins se aplican durante la fase de inicialización del proyecto, apply se ejecuta durante la fase de configuración.

Esto es especialmente útil cuando necesitas aplicar un plugin de manera condicional o basándote en cierta lógica específica dentro del script de construcción. Por ejemplo, podrías querer aplicar un plugin solo si se detecta un entorno particular o si se cumple una determinada condición.

apply(plugin = "some.plugin")   // Aplicación por ID
apply<SomePlugin>() // Aplicación por tipo

Si bien el método apply es más flexible, se recomienda utilizar el bloque plugins para aplicar plugins en la mayoría de los casos, ya que proporciona una forma más segura y declarativa de gestionar las dependencias del proyecto.

Diferencias entre plugins y apply

CaracterísticaBloque pluginsMétodo apply
Validación en tiempo de configuraciónSí. Detecta errores de configuración al inicio.No. La validación ocurre en tiempo de ejecución.
Compatibilidad con repositorios de pluginsSí. Se integra directamente con el portal de plugins de Gradle.No. Requiere que los plugins ya estén disponibles.
Aplicación condicionalNo. Es más declarativo y estático.Sí. Permite lógica condicional dentro del script.
Soporte para plugins personalizadosSí, si el plugin está en un archivo de convención.Necesario para plugins definidos como clases.
Gestión de versionesCentralizada a través de libs.versions.toml.Puede necesitar lógica adicional para gestionar versiones.

¿Cuándo usar plugins y apply?

  • Usar plugins:

    • Cuando trabajes con plugins estándar de Gradle que están disponibles en repositorios de plugins.
    • Para aprovechar la validación en tiempo de configuración, lo que mejora la detección temprana de errores.
    • Si deseas tener una configuración más declarativa y estática, especialmente en proyectos modernos.
  • Usar apply:

    • Cuando necesites aplicar un plugin condicionalmente basado en una propiedad o lógica del proyecto.
    • Cuando estés migrando un proyecto antiguo que ya utiliza apply, o para manejar casos donde plugins no puede ser utilizado (por ejemplo, ciertos proyectos multiproyecto).

Recuerda que, para la mayoría de los casos, el bloque plugins es la opción recomendada por su simplicidad, seguridad y mejor integración con el ecosistema de Gradle. Sin embargo, si necesitas mayor flexibilidad, apply sigue siendo una herramienta útil para personalizar y condicionar la aplicación de plugins.

Aplicación de plugins en sub-módulos

Cuando trabajas con proyectos multi-módulo en Gradle, es común que necesites aplicar un mismo plugin a varios submódulos. En lugar de duplicar la configuración del plugin en cada submódulo, Gradle permite aplicar plugins de manera centralizada a todos los subproyectos. Esto ayuda a mantener una configuración coherente y fácil de mantener.

En este caso, estamos aplicando el plugin jvm.conventions en todos los subproyectos. Para evitar aplicar el plugin individualmente en cada subproyecto, podemos centralizar esta tarea utilizando el bloque subprojects dentro del archivo build.gradle.kts o build.gradle.

Aplicación centralizada del plugin en todos los subproyectos

build.gradle.kts
subprojects {
apply(plugin = "jvm.conventions")
}

De esta forma, el plugin jvm.conventions se aplicará automáticamente en todos los subproyectos del proyecto principal, eliminando la necesidad de repetir la misma configuración en cada uno de ellos.

Usando apply false

Cuando trabajas en un proyecto multi-módulo en Gradle, es posible que quieras declarar un plugin de forma centralizada sin aplicarlo automáticamente en todos los subproyectos. Aquí es donde entra en juego apply false. Esta opción es útil para centralizar versiones de plugins y gestionarlas en un único lugar, pero dejando la aplicación del plugin a nivel de subproyecto cuando sea necesario.

¿Por qué usar apply false?

  1. Centralización de versiones: Si gestionas todas las versiones de los plugins en un solo lugar, puedes declarar un plugin en el proyecto raíz y aplicarlo manualmente en los subproyectos que lo requieran.
  2. Evitar la duplicación: Puedes evitar declarar la versión del plugin en cada subproyecto, lo que facilita su mantenimiento y actualización.
  3. Flexibilidad: Permite que ciertos subproyectos apliquen el plugin y otros no, dándote mayor control sobre qué módulos requieren el plugin y cuáles no.

Ejemplo de uso

Supongamos que tenemos varios subproyectos, pero solo algunos de ellos requieren el plugin kotlin. Podemos declarar el plugin kotlin en el bloque plugins del proyecto raíz, pero usando apply false para no aplicarlo inmediatamente.

plugins {
kotlin("jvm") version "2.0.20" apply false // Declaramos el plugin 'kotlin' sin aplicarlo inmediatamente
}

Con esta configuración, el plugin kotlin no se aplicará a ningún subproyecto por defecto. Sin embargo, puedes aplicarlo manualmente en los subproyectos que lo necesiten:

subproject/build.gradle.kts
plugins {
kotlin("jvm")
}

Flexibilidad con subprojects

Si en algún submódulo no deseas aplicar el plugin SomePlugin u otros plugins de manera centralizada, puedes excluir ciertos submódulos de la aplicación de plugins usando condiciones dentro del bloque subprojects. Por ejemplo:

subprojects {
if (name != "js") {
apply<SomePlugin>()
}
}

Esto excluye al submódulo js de aplicar el plugin SomePlugin, mientras que todos los demás subproyectos seguirán aplicándolo.

Ejemplos de aplicaciones de plugins en diferentes lenguajes

Maven (para proyectos Java)

En Maven, los plugins se configuran en el archivo pom.xml. A continuación se muestra un ejemplo de cómo agregar el plugin maven-compiler-plugin:

pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

npm/yarn (Node.js)

Tanto npm como yarn son sistemas de gestión de paquetes para proyectos JavaScript, y aunque no son "build systems" en el sentido clásico, utilizan plugins o paquetes adicionales para ejecutar scripts, automatizar tareas y manejar el ciclo de vida del proyecto.

Ejemplo: Uso de Plugins (Paquetes) en npm/yarn

package.json
{
"scripts": {
"build": "webpack --config webpack.config.js",
"test": "jest"
},
"devDependencies": {
"webpack": "^5.52.0",
"jest": "^27.0.6"
}
}

Aquí, Webpack y Jest son paquetes (plugins) que se agregan como devDependencies y se invocan a través de los scripts de npm/yarn.

Para instalar estos "plugins":

npm install --save-dev webpack jest
# o con Yarn
yarn add --dev webpack jest

2. SBT (Scala Build Tool)

SBT es el sistema de construcción más común para proyectos en Scala, y también permite utilizar plugins para extender sus capacidades, como la integración continua, la gestión de dependencias y la compilación.

Ejemplo: Agregar un plugin en SBT

project/plugins.sbt
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.8.0")

En este caso, el plugin sbt-native-packager permite empaquetar aplicaciones Scala/Java de diversas maneras, incluidas distribuciones Docker.

Cargo (Rust)

Cargo es el sistema de construcción y gestor de paquetes para proyectos Rust. Aunque Cargo no tiene un sistema de plugins tan amplio como Gradle o Maven, hay complementos (como herramientas adicionales) que se pueden integrar en el ciclo de vida de la construcción a través de scripts o dependencias en el archivo Cargo.toml.

Ejemplo: Agregar herramientas de construcción en Cargo

Cargo.toml
[dependencies]
serde = "1.0"
serde_derive = "1.0"

[build-dependencies]
cc = "1.0"

Aquí, serde es una librería que se usa en el código Rust, y cc es un complemento que permite construir código C desde el mismo entorno de Cargo.

CMake

CMake es un sistema de construcción utilizado principalmente en proyectos C/C++. CMake puede extenderse a través de modulos que actúan como plugins para gestionar dependencias, configuraciones de compilación y más.

Ejemplo: Uso de módulos en CMake

CMakeLists.txt
find_package(Boost 1.71.0 REQUIRED)
include_directories(${Boost_INCLUDE_DIR})

Aquí, find_package busca módulos o bibliotecas como Boost, que es un conjunto de bibliotecas C++.

Bazel

Bazel es otro sistema de construcción que permite usar reglas y plugins para definir cómo construir proyectos de gran escala. Los plugins en Bazel suelen ser llamados "reglas", y se pueden cargar desde el repositorio central de reglas de Bazel o definirse dentro del proyecto.

Ejemplo: Agregar una regla (plugin) en Bazel

WORKSPACE
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
name = "rules_docker",
urls = ["https://github.com/bazelbuild/rules_docker/releases/download/v0.14.1/rules_docker-v0.14.1.tar.gz"],
sha256 = "some-sha256-hash",
)

Este ejemplo descarga y usa reglas para trabajar con Docker en Bazel.

Recapitulando

En este artículo, hemos explorado diferentes formas de aplicar plugins en Gradle, tanto en proyectos simples como en proyectos multi-módulo. Hemos visto cómo aplicar plugins de manera directa utilizando el bloque plugins, que es la forma recomendada por Gradle para gestionar versiones y garantizar una configuración declarativa y validada en tiempo de configuración.

También cubrimos el uso del método apply, que ofrece mayor flexibilidad en la aplicación de plugins, permitiendo aplicar plugins de forma condicional o cuando se definen como clases dentro del proyecto.

Finalmente, hemos abordado el uso de apply false, una técnica útil para declarar plugins centralizadamente sin aplicarlos inmediatamente, lo que proporciona un control más preciso en proyectos multi-módulo. Esta técnica, junto con el bloque subprojects, permite gestionar de manera eficiente la configuración de grandes proyectos con múltiples submódulos.

Bibliografías Recomendadas