JavaScript siempre fue un lenguaje de programación importante, ya que es el único lenguaje que se ejecuta de manera confiable en el navegador. Las tendencias recientes en el desarrollo de aplicaciones para usuario así como en el desarrollo de servicios de fondo basado en Node.js han impulsado la escala y la complejidad de las aplicaciones de JavaScript.
Las grandes aplicaciones desarrolladas por grandes equipos pueden beneficiarse de la comprobación de tipos estática, de la que carece JavaScript de vainilla. Flow fue desarrollado por Facebook para abordar este problema. Es un comprobador de tipos estático que se integra en su proceso de desarrollo, detecta muchos problemas al principio y lo ayuda a moverse rápidamente.
Flow es una herramienta que comprueba su código JavaScript anotado y detecta varios problemas que, sin él, se descubrirían solo en tiempo de ejecución (o peor), no descubierto y corromper sus datos). Aquí hay un ejemplo rápido.
// función @flow getGreeting (name: string): string return 'Hi, $ name'; const http = require ("http"); const greeting = getGreeting ("Gigi") const port = 8888 console.log ('Listening on port $ port ...') http.createServer (function (request, response) response.writeHead (200, "Content-Type ":" text / plain "); response.write (saludo); response.end ();). listen (puerto);
Antes de sumergirse en los detalles esenciales de Flow, vale la pena compararlos con otras alternativas, y en particular con TypeScript. TypeScript es un superconjunto estricto de JavaScript desarrollado por Microsoft. Cualquier programa de JavaScript es también un programa de TypeScript.
TypeScript agrega anotaciones de tipo opcionales y en general cumple el mismo propósito que Flow. Sin embargo, hay algunas diferencias importantes. TypeScript es un lenguaje de programación separado que se compila a JavaScript, mientras que las anotaciones de flujo deben eliminarse para volver a JavaScript válido.
TypeScript tiene una gran herramienta y soporte IDE. Flow se está recuperando (por ejemplo, JetBrains WebStorm tiene integración de Flow nativa).
La diferencia filosófica más importante es que Flow pone énfasis en la solidez. TypeScript 1.0 no detectó errores nulos; TypeScript 2.0 con estrictos controles nulos medidos hasta Flow en este sentido. Pero en otros aspectos, como los contenedores genéricos o la escritura, TypeScript es más permisivo y permite varias categorías de errores (solo se comprueba la tipificación estructural, no tipificación nominal).
TypeScript como su propio lenguaje agrega conceptos y características de lenguaje como clases, interfaces, indicadores de visibilidad (públicos, privados, de lectura) y decoradores. Esas características facilitan su comprensión y uso para las personas que vienen de lenguajes orientados a objetos convencionales como C ++, Java y C #.
Dado que las anotaciones de flujo no son JavaScript estándar, deben eliminarse antes de implementar su aplicación. Aquí es cómo instalar el flujo y el flujo-eliminar-tipos a través de hilo: hilo añadir --dev flow-bin flow-remove-types
Puede agregar un par de scripts a su archivo package.json para automatizar el proceso:
"scripts": "build": "flow-remove-types src / -d lib /", "prepublish": "yarn run build"
Debe ejecutar el script de publicación previa antes de publicar su código en el registro npm.
Para otras opciones de instalación (por ejemplo, usando npm o babel), consulte la guía de instalación de Flow.
Para finalizar la instalación, escriba: hilado run flow init
Esto creará el archivo .flowconfig requerido.
El flujo tiene dos objetivos importantes: la precisión y la velocidad. Su sistema tipográfico fue diseñado para apoyar estos objetivos..
La precisión se logra al analizar cómo el código interactúa con los tipos, ya sea anotado o inferido. Cualquier desajuste genera un error de tipo. Los tipos anotados admiten la tipificación nominal, lo que significa que dos tipos diferentes con los mismos atributos se distinguen entre sí y no se pueden sustituir. El tipo de una variable se define como el conjunto de valores de tiempo de ejecución que la variable puede recibir.
El flujo es rápido debido a una combinación de modularidad y procesamiento distribuido. Los archivos se analizan en paralelo y los resultados se combinan más adelante mediante una eficiente memoria compartida para llevar a cabo la verificación de tipo de programa completo.
El flujo soporta muchos tipos. Además de los tipos primitivos, también admite lo siguiente:
Flow le permite declarar tipos, así como restringir variables y parámetros a valores seleccionados:
tipo Two2Four = 2 | 3 | 4 función doubleIt (número: Two2Four) número de retorno * 2 console.log (doubleIt (3)) Salida: 6
Si excede el rango válido, obtendrá un error:
console.log (doubleIt (3)) Salida: Error: src / main.js: 30 30: console.log (doubleIt (5)) // error ^ número. Este tipo es incompatible con el tipo de parámetro esperado de 24: function doubleIt (número: Two2Four) ^^^^^^^^ enumeración del número Encontrado 1 error
También puede definir tipos complejos, incluyendo subtipos. En el siguiente ejemplo de código, el tipo de Guerrero es un subtipo de Persona. Esto significa que está bien devolver un Guerrero como Persona del lucha()
función. Sin embargo, está prohibido devolver nulo..
tipo Persona = nombre: cadena, edad: número tipo Guerrero = nombre: cadena, edad: número, fuerza: número deja redWolf: Guerrero = nombre: "Lobo rojo", edad: 24, fuerza: 10 deja skullCrusher: Warrior = nombre: "Skull Crusher", edad: 27, fuerza: 11 función de lucha (w1: Warrior, w2: Warrior): Person if (w1.strength> w2.strength) return w1 if ( w2.strength> w1.strength) return w2 return null Salida: Encontrado 1 error $ flow Error: src / main.js: 47 47: return null ^^^^ null. Este tipo es incompatible con el tipo de retorno esperado de 39: function fight (w1: Warrior, w2: Warrior): Person ^^^^^^ tipo de objeto Encontrado 1 error
Para solucionarlo, devolvamos al guerrero más joven si ambos guerreros tienen la misma fuerza:
función lucha (w1: Guerrero, w2: Guerrero): Persona if (w1.strength> w2.strength) return w1 if (w2.strength> w1.strength) return w2 return (w1.age < w2.age ? w1 : w2) let winner = fight(redWolf, skullCrusher) console.log(winner.name) Output: Skull Crusher
El flujo permite un control aún más preciso a través de la extensión de clase, la invariancia, la covarianza y la contravarianza. Echa un vistazo a la documentación de flujo en varianza.
Flow utiliza el archivo de configuración .flowconfig en el directorio raíz de sus proyectos. Este archivo contiene varias secciones que le permiten configurar qué archivos debe verificar Flow y los muchos aspectos de su funcionamiento..
los [incluir]
La sección controla qué directorios y archivos deben ser revisados. El directorio raíz siempre se incluye por defecto. Los caminos en el [incluir]
Las secciones son relativas. Una sola estrella es un comodín para cualquier nombre de archivo, extensión o nombre de directorio. Dos estrellas son un comodín para cualquier profundidad de directorio. Aquí hay una muestra. [incluir]
sección:
[incluir] ... /externalFile.js… / externalDir /… /otherProject/*.js… / otherProject / ** / coolStuff /
los [ignorar]
La sección es el complemento de [incluir]
. Los archivos y directorios que especifique aquí no se verifican por flujo. Extrañamente, usa una sintaxis diferente (expresiones regulares OCaml) y requiere rutas absolutas. Cambiar esto está en la hoja de ruta del equipo de Flow.
Hasta entonces, recuerde que la sección de inclusión se procesa primero, seguida de la sección de ignorar. Si incluye e ignora el mismo directorio y / o archivo, se ignorará. Para abordar el problema de la ruta absoluta, es común prefijar cada línea con .*
. Si desea ignorar directorios o archivos debajo de la raíz, puede usar el
marcador de posición en lugar de .*
. Aquí hay una muestra. [ignorar]
sección:
[ignorar]. * / __ prueba __ /. *. * / src / \ (foo \ | bar \) /.*. * \. ignorar \ .js/ignore_me.js
Cualquier aplicación de JavaScript no trivial usa muchas bibliotecas de terceros. Flow puede verificar cómo su aplicación utiliza estas bibliotecas si proporciona archivos libdef especiales que contienen información de tipo sobre estas bibliotecas..
Flow escanea automáticamente el subdirectorio "tipo de flujo" de su proyecto en busca de archivos libdef, pero también puede proporcionar la ruta de los archivos libdef en la sección [libs]. Esto es útil si mantiene un repositorio central de archivos libdef utilizados por varios proyectos.
Importar definiciones de tipos existentes y crear las suyas propias si la biblioteca de destino no proporciona sus propias definiciones de tipos es bastante simple. Ver:
Flow tiene varias reglas de pelusas que puedes controlar y determinar cómo tratarlas. Puede configurar las reglas desde la línea de comandos, en los comentarios de código o en la [lints]
sección de su archivo de configuración. Discutiré sobre linting en la siguiente sección, pero aquí es cómo configurarlo usando el [lints]
sección:
[lints] all = warn untyped-type-import = error sketchy-null-bool = off
los [opciones]
La sección es donde puedes decirle a Flow cómo comportarse en una variedad de casos que no merecen su propia sección, por lo que están agrupados..
Hay demasiadas opciones para enumerarlas todas aquí. Algunos de los más interesantes son:
todos
: configúrelo en verdadero para verificar todos los archivos, no solo aquellos con @flowemoji
: se establece en verdadero para agregar emojis a los mensajes de estadomodule.use_strict
: configúrelo como verdadero si usa un transpiler que agrega "use strict;"suprimir comentario
: una expresión regular que define un comentario para suprimir cualquier error de flujo en la siguiente línea (útil para el código en progreso)Echa un vistazo a todas las opciones en la guía de flujo para configurar opciones.
El flujo y su formato de archivo de configuración evolucionan. los [versión]
La sección le permite especificar para qué versión de Flow está diseñado el archivo de configuración para evitar errores confusos.
Si la versión de Flow no coincide con la versión configurada, Flow mostrará un mensaje de error.
Aquí hay algunas maneras de especificar las versiones compatibles:
[versión] 0.22.0 [versión]> = 0.13.0 <0.14.0 [version] ^1.2.3
La versión caret mantiene fijo el primer componente distinto de cero de la versión. Asi que ^ 1.2.3
se expande al rango> = 1.2.3 < 2.0.0, and ^ 0.4.5
se expande al rango> = 0.4.5 < 0.5.0.
Flow es un programa cliente-servidor. Debe estar ejecutándose un servidor Flow y el cliente se conecta a él (o lo inicia si no se está ejecutando). Flow CLI tiene muchos comandos y opciones que son útiles para fines de mantenimiento e introspección, así como para anular temporalmente la configuración de .flowconfig.
Mecanografía flujo - ayuda
Muestra todos los comandos y opciones. Para obtener ayuda sobre un comando específico, escriba fluir
. Por ejemplo:
$ flow ast - Uso de la ayuda: flow ast [OPCIÓN]… [ARCHIVO], por ejemplo, flujo ast foo.js o flujo ast < foo.js --from Specify client (for use by editor plugins) --help This list of options --pretty Pretty-print JSON output --tokens Include a list of syntax tokens in the output --type Type of input file (js or json)
Los comandos importantes son:
en eso
: generar un archivo .flowconfig vacíocomprobar
: realice una comprobación de flujo completa e imprima los resultados ls
: muestra archivos visibles para Flowestado
(predeterminado): muestra los errores de flujo actuales del servidor de flujosugerir
: sugerir tipos para el archivo de destino
Flow tiene un marco de trabajo que se puede configurar a través del archivo .flowconfig como se vio anteriormente, a través de argumentos de línea de comandos o en archivos de código que utilizan comentarios de flowlint. Todos los métodos de configuración consisten en una lista de pares clave-valor donde la clave es una regla y el valor es la gravedad.
Actualmente hay tres reglas: todas, import-type-import y sketchy-null. La regla "Todos" es realmente el tratamiento predeterminado para cualquier error que no tenga una regla más específica. La regla de "importación de tipo sin tipo" se invoca cuando importa un tipo de un archivo sin tipo. La regla "incompleta-nula" se invoca cuando se verifica la existencia de un valor que puede ser falso o nulo / no definido. Hay más reglas granulares para:
También hay tres niveles de gravedad: apagado, advertencia y error. Como puede imaginar, "off" omite la comprobación de tipo, "warn" genera advertencias, que no hacen que la comprobación de tipo se cierre y no se muestra de forma predeterminada en la salida de la CLI (puede verlas con --incluir advertencias
), y el "error" se maneja como los errores de flujo y hace que la verificación de tipo salga y muestre un mensaje de error.
Utilizar el --pelusas
Argumento de línea de comando para especificar múltiples reglas de pelusa. Por ejemplo:
flujo --lints "all = warn, untyped-type-import = error, sketchy-null-bool = off"
Hay tres tipos de comentarios: flowlint, flowlint-line y flowlint-next-line.
El comentario "flowlint" aplica un conjunto de reglas en un bloque hasta que un comentario coincidente lo invalida:
tipo de importación // flowlint untyped-type-import: off Foo, Bar, Baz, // flowlint untyped-type-import: error de './untyped.js';
Si no hay un comentario coincidente, la configuración simplemente se aplica hasta el final del archivo.
La "línea flowlint" se aplica solo a la línea actual:
function (x:? boolean) if (x) // flowlint-line sketchy-null-bool: off ... else else …
El "flowlint-next-line" se aplica a la línea que sigue al comentario:
function (x:? boolean) // flowlint-next-line sketchy-null-bool: off si (x) ... else …
Los grandes proyectos de JavaScript desarrollados por grandes equipos pueden beneficiarse mucho de la verificación de tipos estática. Existen varias soluciones para introducir la comprobación de tipos estática en una base de código JavaScript.
JavaScript continúa creciendo de varias maneras en la web. No deja de tener sus curvas de aprendizaje, y hay muchos marcos y bibliotecas para mantenerlo ocupado, como puede ver. Si está buscando recursos adicionales para estudiar o usar en su trabajo, vea lo que tenemos disponible en el mercado de Envato.
El flujo de Facebook es una solución reciente y robusta con excelente cobertura, herramientas y documentación. Pruébalo si tienes una base de código JavaScript grande.