Ionic PWA Toolkit una combinación de herramientas para crear aplicaciones web progresivas con…


Ionic PWA Toolkit una combinación de herramientas para crear aplicaciones web progresivas con IONIC.

Ionic PWA Toolkit es una combinación de herramientas y un proyecto en versión beta para crear fácilmente aplicaciones web progresivas con Ionic.

En este artículo a demás de generar nuestra primera pwa con el nuevo kit de herramientas de ionic, intentaremos hechar un vistazo a la estructura del proyecto y algunos conceptos claves.

Que incluye el proyecto?

  • Ionic
  • Routing
  • Stencil
  • Configuración de Notificaciones Push
  • Mostrar un toast cuando hay una nueva versión de la PWA disponible
  • Pruebas Unitarias
  • Pre-Rendering
  • zero config lazy-loading
  • zero config code-splitting
  • Polyfills cargados selectivamente según el soporte del navegador
  • ES6 por defecto para nuevos navegadores, ES5 para navegadores más antiguos
  • Todo lo necesario para agregar a la pantalla de inicio PWA (trabajador de servicio, manifiesto web y meta tags iOS)
  • Componente lazy-img para mejorar la carga de nuestras imágenes

Lo clave en esta lista:

  • Ionic: Todos los widgets UI predefinidos y prediseñados con los que estamos familiarizados desde Ionic-Angular, pero llevados a Web Components.
  • Stencil: Un compilador que toma archivos TSX ( JSX + TS ) y los convierte en Web components nativos y adicionalmente no importa el framework que utilices Angular, React o VueJs (o incluso ningún framework).Mejora el rendimiento por ser componentes nativos, el tamaño de los componentes lo cual es un requerimiento de las PWA y también la pesadilla de la fragmentación de los frameworks donde uno no es compatible con el otro.
  • Notificaciones Push: Todo el código repetitivo para notificaciones push, incluido el trabajador del servicio, se incluye de fábrica, lo que ahorra tiempo y configuración.
  • Agregar a la pantalla de inicio : Un trabajador de servicio (gracias a Workbox ), un manifiesto web y las metaetiquetas correctas para iOS. Esto significa que la PWA se puede agregar a la pantalla de inicio tanto en dispositivos Android como iOS.

En vista de que el mayor impacto parece venir por Stencil me gustaría agregar lo siguiente: Stencil crea componentes web y el equipo de Ionic ha creado un conjunto de componentes web con Stencil que se han convertido en Ionic Core . Stencil también se puede usar para crear componentes web para cualquier propósito, no solo se usa para crear componentes ionic. El paquete de componentes web de Ionic puede ser utilizado por cualquier framework y también se puede utilizar sin ninguno. Hay una biblioteca especial llamadaionic-angularque es el marco de la biblioteca de ionic específico de Angular (el que hemos estado usando durante mucho tiempo).

Para quienes estamos familiarizados de alguna forma con la construcción de aplicaciones ionic y pwa con ionic puede ser confuso este nuevo ecosistema, por lo que antes de continuar me quiero compartir las siguientes interrogantes que plantea Josh Morony en su artículo “Building a PWA with Stencil: An Introduction to Stencil” con el fin de ayudarnos a despejar algunas dudas:

  • Pensé que Stencil era una herramienta detrás de escena para Ionic 4. Lo es.
  • ¿Vamos a necesitar aprender Stencil para usar Ionic ahora? No.
  • ¿Necesitamos aprender Stencil para construir PWA con Ionic? No.
  • ¿Debo aprender Stencil? Tal vez.
  • ¿Por qué debería construir un PWA con Stencil cuando puedo construir una con Ionic-Angular? Rendimiento, en su mayoría.
  • ¿Eso significa que no debería construir un PWA con Ionic-Angular? No.
  • ¿Se está desaprovechando Ionic-Angular? No.

Desarrollando la aplicacación

  1. Para configurar Ionic PWA Toolkit para un nuevo proyecto, solo necesitamos clonar el repositorio de GitHub:
git clone https://github.com/ionic-team/ionic-pwa-toolkit.git PROJECT-NAME

2. Una vez que ha finalizado la clonación, debemos entrar al proyecto e instalar las dependencias:

cd PROJECT-NAME
npm install

3. Una vez que las dependencias hayan terminado de instalarse, podemos ejecutar la aplicación con:

npm start

El proyecto debería iniciarse en el navegador en localhost:3333y deberíamos ver algo como esto:

Se ve bastante similar a una aplicación Ionic normal. Aunque los componentes web Ionic que se introducen en Ionic 4 se pueden usar fácilmente en cualquier proyecto Stencil, de manera predeterminada no se incluyen en el motor de arranque (está en el kit de herramientas Ionic PWA). Lo que vemos es en realidad elementos básicos de HTML diseñados con algunos SCSS personalizados.

4. Cuando estemos en desarrollo, podemos usar el siguiente comando para habilitar la recarga del navegador cuando realicemos un cambio:

npm run dev

5. También podemos compilar el proyecto para generar una aplicación de producción ejecutando:

npm run build

A continuación, encontraremos la aplicación creada dentro de la carpeta www .

En este punto, la compilación final ya no es realmente un “proyecto stencil”, solo son componentes web vainilla que se compilaron con Stencil. Estos componentes web funcionan directamente en navegadores modernos, no requieren ningún tipo de framework para ejecutarse.


Archivos y carpetas

La estructura de carpetas en el proyecto que acabamos de configurar, es bastante similar a una aplicación Ionic-Angular normal:

Tenemos una carpeta src donde se lleva a cabo la mayor parte de la codificación y también contiene una carpeta de assets para activos estáticos. Tenemos el archivo index.html que contiene la estructura básica del sitio web junto con <my-app>componente raíz de la aplicación. También tenemos una carpeta www que contiene el código creado para el proyecto.

Tenemos los archivos de configuración habituales, como package.json, tsconfig.jsony así sucesivamente. También tenemos un archivo stencil.config.js el compilador usa este archivo para determinar cómo se debe compilar el proyecto y si es necesario incorporar componentes externos.

No hay mucho de lo que preocuparse ahora, haremos casi todo el trabajo dentro de la carpeta components (ya sea creando nuevos componentes o editando los existentes).

Sintaxis

Una gran parte de la sintaxis para los proyectos de Stencil es muy similar a la que estamos acostumbrados en angular. La mayor diferencia es el uso de TSX (que es JSX con la adición de TypeScript).

JSX / TSX

JSX (JavaScript XML) agrega la capacidad de usar sintaxis XML dentro de JavaScript. TSX es lo mismo, excepto que permite el uso de TypeScript y XML .

Lo que nos permite es usar la misma sintaxis que usaríamos para HTML, excepto que podemos agregarlo directamente en nuestro código JavaScript / TypeScript. Si quisiéramos definir algún tipo de plantilla dentro de JavaScript, generalmente haríamos algo como esto:

let myTemplate = '<div><p>Hello</p></div>';

No podemos escribir sintaxis HTML dentro de JavaScript porque no es una sintaxis de JavaScript válida. En cambio, creamos un string como en el ejemplo anterior para mantenerlo. Sin embargo, con JSX / TSX, podemos agregar la sintaxis XML directamente a JavaScript:

let myTemplate = <div><p>Hello</p></div>;

Utilizaremos esto en Stencil a través de la función render()que encontraremos dentro de nuestros componentes:

render() {
if
(this.match && this.match.params.name) {
return
(
<div>
<p>
Hello! My name is {this.match.params.name}.
My name was passed in through a route param!
</p>
</div>
);
}
}

La función render determinará qué se muestra en la pantalla (la plantilla, básicamente). Encontraremos una función render en cada uno de los componentes de ejemplo en Ionic PWA Toolkit.

EL código del ejemplo anterior lo podemos encontrar en app-profile.tsx.

Como JSX/TSX solo agrega la capacidad de usar sintaxis XML dentro de JavaScript significa que se podemos usar la lógica básica de JavaScript if/elsepara controlar cómo se procesa el archivo (en lugar de las directivas de angular como *ngIf). En este caso, el mensaje solo se representaifse cumple la condición.

Estructura básica de componentes

Observando la estructura general de un componente Stencil vemos que es bastante similar a un componente angular:

app-home.tsx

import { Component } from '@stencil/core';

@Component({
tag: 'app-home',
styleUrl: 'app-home.scss'
})
export class AppHome {

componentDidLoad() {
console.log('The component has been rendered');
}

someCustomFunction() {
console.log('Watch out!... Radioactive man');
}

render() {
return (
<div>
<p>
Welcome to the Stencil App Starter.
You can use this starter to build entire apps all with
web components using Stencil!
Check out our docs on <a href='https://stenciljs.com'>stenciljs.com to get started.
</p>

<stencil-route-link url='/profile/stencil'>
<button>
Profile page
</button>
</stencil-route-link>
</div>
);
}

}

ImportamosComponent de la biblioteca @stencil/core y luego usamos el decorador@Component para definir algunos metadatos para el componente. Suministramos una propiedadtagque define la etiqueta para el elemento, por ejemplo <app-home>, y una styleUrlque define el archivo SCSS que este componente utilizará para el diseño.

Exportamos una clase que define el componente. Lo más importante es que esta clase contiene la funciónrender que determina qué se mostrará al usuario. Sin embargo, también podemos definir nuestras propias funciones personalizadas como lo hacemos en Ionic-Angular, e incluso tenemos eventos de ciclo de vida similares (por ejemplo, en componentDidLoaden lugar de ionViewDidLoad).


Ahora veamos rápidamente alguna sintaxis común y cómo se compara con Ionic-Angular.

Interpolaciones

En Angular, una interpolación es cuando calculamos algo y presentamos su valor en la pantalla. Haríamos interpolaciones como esta:

{{ name }}

Este concepto es casi idéntico en Stencil, excepto que usamos una sola llave y debemos incluir la referencia a this:

{this.name}

@Prop y @State

Definir un@Propnos permite pasar un dato a un componente. Si tuviéramos que configurar el siguiente @Prop:

import { Component, Prop } from '@stencil/core';

@Component({
tag: 'my-first-component',
styleUrl: 'my-first-component.scss'
})
export class MyComponent {

// El nombre debe ser una propiedad pública del componente
@Prop() name: string;

render() {
return (
<p>
My name is {this.name}
</p>
);
}
}

Entonces podríamos pasarle un nombre al componente cuando lo usemos, así:

<my-first-component name="Max"></my-first-component>

Podemos acceder a ese valor dentro de nuestro componente utilizando this.name. Esto es idéntico en concepto a Angular @Input. @Statees similar, excepto que lo usamos para definir valores que van a cambiar dentro de nuestro componente. Usando otro ejemplo de la documentación:

export class TodoList {

@State() completedTodos: Todo[];

...
}

Este componente necesita un seguimiento completedTodos, que cambiará con el tiempo. En lugar de simplemente definirlo como un miembro de la clase como lo haríamos en Ionic / Angular.

export class TodoList {

completedTodos: Todo[];

...

}

Anteponemos @Statepara que Stencil sepa que este valor cambiará. Cada vez que una @Propo @Statese actualiza, la funciónrender se ejecutará y actualizará lo que el usuario ve en la pantalla.

@Event y @Listen

Podemos definir un @Eventcon un EventEmitterpara activar un evento:

import { Event, EventEmitter } from '@stencil/core';

...
export class TodoList {

@Event() todoCompleted: EventEmitter;

todoCompletedHandler(todo: Todo) {
this.todoCompleted.emit(todo);
}
}

De nuevo, esto es exactamente lo mismo que haríamos en una aplicación Ionic-Angular (excepto que la usaríamos en @Outputlugar de @Event). Creamos todoCompletedcon @Event()y luego podemos activar ese evento llamando this.todoCompleted.emit().

Para escuchar ese evento en un componente principal, usamos @Listen:

export class TodoApp {

@Listen('todoCompleted');

todoCompletedHandler(event: CustomEvent) {
console.log('Received the custom todoCompleted event');
}

}

Esto es algo diferente de lo que haríamos en Ionic-Angular, porque normalmente configuraríamos un enlace de evento en la plantilla como este:

<todo-list (todoCompleted)="someFunction()">

y configuraríamos el correspondiente someFunction()para manejar el evento.


Hay más sintaxis para recorrer y quienes estamos familiarizados con Angular podemos observar que muchos de los conceptos generales son bastante similares.

Stencil proporciona una API similar a Angular y React, pero se centra en satisfacer las demandas de rendimiento de las aplicaciones web progresivas.

Referencias:

Ionic PWA Toolkit Beta

The magical, reusable web component compiler

Building a PWA with Stencil: An Introduction to Stencil

Building a PWA with Stencil: Project Structure and Syntax

Announcing the Ionic PWA Toolkit Beta