Tabla de Contenidos

3. Automatización del proyecto

En el tema anterior hemos visto como se estructura de carpetas del proyecto. En este tema vamos a automatizar todos los procesos de la estructura de carpetas . Automatizar tareas es fundamental ya que se minimizan los errores que se cometen. Por otro lado el despliegue puede llegar a hacerse decenas de veces al día, por lo que obviamente debe estar automatizado.

Podemos pensar que instalar (desplegar) decenas de veces al día una aplicación es un poco exagerado pero en sitios web como Amazon ésto si que tiene sentido. Si en la aplicación de amazón hay un error que suele afectar al 0,1% de sus ventas. ¿Cuanto dinero pierden diariamente por tener ese error? Y en este tipo de aplicaciones se suelen estar constantemente realizando cambios y corrección de error , así que ¿porque no desplegarla en cuanto está corregido un error o añadida la nueva funcionalidad? Esto en la literatura informática se llama Continuous delivery

Proyecto de Spring Boot

Para crear un proyecto de Spring Boot usar https://start.spring.io/

mvn clean install

java -jar miapp.jar

Automatizar Maven

Vamos ahora a ver como podemos automatizar cosas en un proyecto Java con maven.

Para realizar tareas definidas en maven debemos usar pluings que hacen esas tareas.

Vamos a ver 2 plugins:

Para usar cada plugin hay que añadirlos al pom.xml dentro del tag:

<plugins>
</plugins>

exec-maven-plugin

<plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>exec-maven-plugin</artifactId>
   <version>3.0.0</version>
   <executions>
      <execution>
         <id>build-cliente</id>
         <phase>compile</phase>
         <goals>
            <goal>exec</goal>
         </goals>
         <configuration>
            <executable>NOMBRE_DEL_EJECUTABLE_A_EJECUTAR</executable>
            <workingDirectory>${project.basedir}</workingDirectory>
            <arguments>
               <argument>ARGUMENTO_1</argument>
               <argument>ARGUMENTO_n</argument>
            </arguments>
         </configuration>
      </execution>
   </executions>
</plugin>

plantuml-maven-plugin


            <plugin>
                <groupId>com.github.davidmoten</groupId>
                <artifactId>plantuml-maven-plugin</artifactId>
                <version>0.2.14</version>
                <executions>
                    <execution>
                        <id>generate-diagrams</id>
                        <phase>generate-resources</phase>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <sources>
                        <directory>${basedir}/src</directory>
                        <includes>
                            <include>**/*.puml</include>
                        </includes>
                    </sources>
                    <outputDirectory>${basedir}/src</outputDirectory>
                    <formats>
                        <format>png</format>
                    </formats>
                    <preserveDirectoryStructure>true</preserveDirectoryStructure>
                    <generateMarkdownIndex>false</generateMarkdownIndex>
                </configuration>
            </plugin>

Más información:

Angular

Para generar un proyecto en Angular se usa ng build:

ng build

Que genera una carpeta dist con el código compilado del proyecto.

Una vez compilado el proyecto necesitamos un servidor web, ese servidor HTTP puede ser:

Nosotros vamos a usar un script de NodeJS

Para ello vamos a crear un proyecto Node:

npm init
npm install express

Crear el fichero index.js:

#!/usr/bin/env node


const express = require('express')
const path = require('path')
const app = express()
const port = 8080
const indexFolder = 'browser'

const distPath = path.join(__dirname, indexFolder)

app.use('/', express.static(distPath))

app.use((req, res, next) => {
  const indexPath = path.join(distPath, 'index.html');
  res.sendFile(indexPath);
});

app.listen(port, (err) => {
  console.log(`server is listening on ${port}`)
  console.log(`serving from ${distPath}`)
})

Ahora copiaremos la carpeta browser que creó Angular dentro de dist y la copiaremos en la raiz de nuestro proyecto Node.

Por último ejecutaremos la aplicación con

node ./index.js

Automatizar NodeJS

Al igual que existe en java mvn en aplicaciones de NodeJS podemos usar npm run que ejecutará nuestros scripts.

En los siguientes artículos se explican los scripts npm:

Veamos ahora un ejemplo de Script de transformar SASS a CSS.

"scripts": {
  "compile-scss": "sass  ./scss/main.scss ./css/main.css"
}

npm run compile-scss

¿Que hemos ganado con ésto? Que ahora todas las "tareas" que tenemos que hacer en el proyecto se pueden ver en el package.json y siempre se ejecutarán como "npm run nombre-tarea"

Si vemos el package.json en un proyecto de Angular:

  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test"
  }

npm run start

npm run build

¿Que ganaríamos con eso? Que si siempre usamos por ejemplo npm run build podríamos modificar el package.json y en el proceso de build añadir más cosas:

  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build && miscript.sh",
    "watch": "ng build --watch --configuration development",
    "test": "ng test"
  }

En ese caso en la linea 4 hacemos que además de crear en build se ejecute nuestro script miscript.sh.

O cosas como:

  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "build:production": "ng build --configuration production--define SOME_NUMBER=5 --define "ANOTHER='these will overwrite existing'"",    
    "watch": "ng build --watch --configuration development",
    "test": "ng test"
  }

En este caso al ejecutar:

npm run build:production

no tenemos que preocuparnos se saber que opciones hay que pasar a ng build

Así que realmente para encapsular Ancular CLI y que todo sea más standard de cara a cambios es mejor usar npm run