VOLVER

Primera semana de codificación

5 min de lectura

La primera semana del periodo de codificación de GSoC 2016 ha terminado. Empecé la actualización de Jangouts de Angular 1.x a Angular 2. Completé todas las tareas dentro del plazo y espero mantener este ritmo la próxima semana.

Estoy siguiendo la guía de actualización de la documentación oficial de Angular, que tiene dos bloques principales:

  • Preparación
  • Actualización con el Adaptador de Actualización

Acabo de terminar el bloque de preparación. Afortunadamente, el código de Jangouts es claro y ya sigue dos requisitos clave de preparación: la guía de estilo de Angular y directivas de componentes. Esto me dejó solo dos tareas: cambiar de etiquetas <script> a un cargador de módulos, y migrar de JavaScript a TypeScript. Invertí el orden, migrando a TypeScript primero y luego cambiando al cargador de módulos. Esta secuencia me pareció más natural para este proyecto.

Migrando a TypeScript

Jangouts tiene un sistema de construcción gulp funcionando, así que no necesité preocuparme por la carga de scripts. Me enfoqué primero en migrar archivos a TypeScript, luego aproveché la sintaxis import de TypeScript/ES6.

Migrar código de JavaScript a TypeScript es sencillo: cambia la extensión de .js a .ts. El sistema gulp existente no funciona con estos cambios, así que ejecuta tsc --watch src/**/*.ts junto con gulp. Este comando muestra muchos errores, pero si el código JavaScript es correcto, estos errores solo se relacionan con la comprobación de tipos de TypeScript.

Durante esta migración, también hice el código más modular. Jangouts tenía todos los componentes registrados en un único módulo Angular janusHangouts. De proyectos anteriores, aprendí que esto causa problemas con pruebas unitarias. Ahora defino un módulo separado para cada componente (janusHangouts.componentName) y lo hago dependencia del módulo principal. Esto tiene dos ventajas: testing más fácil, y potencialmente cargar componentes bajo demanda con un cargador de módulos.

Como mencioné antes, compilar código JavaScript con tsc muestra muchos errores. Un error común es:

error TS7006: Parameter '$state' implicitly has an 'any' type.

El compilador TypeScript requiere un tipo para todas las variables. Para permitir tipos any implícitos en variables sin tipo, deshabilita noImplicitAny en tsconfig.json.

Otro error que podemos encontrar al trabajar con elementos HTML es:

error TS2339: Property 'muted' does not exist on type 'HTMLElement'.

Este error se produce por un código como este:

var video = $("video", element)[0];
video.muted = true;

TypeScript es seguro en tipos: $('video', element)[0] devuelve HTMLElement, que no tiene la propiedad muted. El subtipo HTMLVideoElement sí contiene muted. Castea el resultado a HTMLVideoElement:

var video = <HTMLVideoElement>$('video', element)[0];
video.muted = true;

Finalmente, otro error común es:

error TS2339: Property 'id' does not exist on type '{}'.

La validación de tipos de TypeScript causa este error en código como:

var room = {};
// Algún código aquí...
function isRoom(room) {
return room.id == roomId;
}

Define una interfaz para el objeto room para solucionar esto y reducir errores:

interface Room {
id?: number; // ? hace el atributo opcional
}
// Algún código aquí ...
var room: Room = {};
// Algún código aquí...
function isRoom(room: Room) {
return room.id == roomId;
}

Usando un Cargador de Módulos

¿Por qué usar un cargador de módulos? El sitio de Angular explica:

Usar un cargador de módulos como SystemJS, Webpack, o Browserify nos permite usar los sistemas de módulos integrados de los lenguajes TypeScript o ES2015 en nuestras aplicaciones. Podemos usar las características de import y export que explícitamente especifican qué código puede y será compartido entre diferentes partes de la aplicación. [...]

Cuando luego llevamos nuestras aplicaciones a producción, los cargadores de módulos también hacen más fácil empaquetarlas todas en paquetes de producción con baterías incluidas.

Descarté Browserify por malas experiencias pasadas y solo probé SystemJS y Webpack.

SystemJS

SystemJS parece limpio y simple. Define un punto de entrada (típicamente el archivo principal de la aplicación) y la sintaxis import hace el resto. Con declaraciones import correctas, todo funciona.

Sin embargo, esta solución requiere conservar gulp ya que SystemJS solo maneja importaciones. Esto significa añadir el compilador TypeScript a gulp y deshabilitar la auto inyección de scripts en HTML.

Antes de reescribir la configuración de gulp, quería probar Webpack primero.

Webpack

La configuración de Webpack es más compleja que SystemJS, pero reemplaza gulp completamente. Como SystemJS, definimos un punto de entrada y especificamos dónde está index.html para la inclusión de archivos JavaScript.

Tuve problemas iniciales, pero tras estudiar ejemplos, conseguí una versión funcional. Explorando Webpack más a fondo, encontré lo que me hizo elegirlo: podemos hacer import o require de archivos no JavaScript. Podemos requerir la plantilla de una directiva Angular, y el proceso de construcción la incluye como variable string dentro del componente. Los estilos funcionan igual. Esto mejora el rendimiento empaquetando todos los archivos que un componente necesita en su archivo JavaScript, sin complicar el desarrollo.

Una cosa más

Este verano parece emocionante con todo lo que aprenderé a través de GSoC. Sigue mi progreso en este blog o a través de mis contribuciones en GitHub. También publiqué un tablero de Trello con la planificación y tareas del proyecto (aún actualizándose).