¿Qué "compila" el compilador angular?

88

Me preguntaron eso hoy y no pude dar una respuesta adecuada.

El texto mecanografiado se transpila a JS. Luego está el temblor de árboles, "menos" (opcional) y qué más en el proceso de realizar una implementación. Pero nada de eso (afaik) tiene nada que ver con "compilar". Todo se incluye y optimiza en gran medida, pero en realidad no está compilado, ¿verdad?

Incluso hay un compilador "anticipado", que realmente hace un trabajo notable. ¿Qué echo de menos?

Javascript en sí todavía se interpreta, ¿verdad?

codepleb
fuente
6
Estoy de acuerdo con el "no compilar realmente". Esencialmente, es una cuestión de definición de compilación . Algunos prefieren usar la palabra transpilación para marcar la transformación de TypeScript a JavaScript. Pero sí, en esencia, la función del compilador de TypeScript es simplemente generar Javascript a partir de Typecript.
Pac0
6
@ Pac0 Puede que esté malinterpretando algo aquí, pero si TypeScript a JavaScript es transpilación, ¿no sería GCC un transpilador de código C a máquina? ¿Cómo definiría la diferencia entre un transpilador y un compilador?
11684
24
Los transpilers son compiladores
user253751
5
Consulte ¿Qué quiere decir la gente cuando dice "transpilador"? (y el seguimiento "Mis primeros quince compiladores" ) (de alguien que trabaja en el compilador), que argumenta que "compilador" es una buena palabra para este tipo de cosas.
ShreevatsaR
2
Javascript en sí todavía está interpretado, ¿verdad? - ya no, se compila en código de máquina sobre la marcha por motor V8
Max Koretskyi

Respuestas:

91

Está asumiendo que compilar significa tomar el código fuente y producir código de máquina, códigos de bajo nivel, etc. Pero compilar en realidad solo significa tomar un código fuente y convertirlo en otro. Por lo tanto, parece razonable decir que tomar Typescript y producir JavaScript es una forma de compilación. No es diferente a lo que (por ejemplo) hace c # cuando se compila en lenguaje IL.

Dicho esto, diría que una palabra mejor para esto es Transpilar . Sugeriría que el compilador de TypeScript se describa mejor como Transpiler.

La diferencia es sutil y un transpilador puede pensarse como un tipo de compilador; pero un lenguaje compilado (puro) está (normalmente) convirtiendo un lenguaje de alto nivel en un lenguaje de nivel más bajo (más cercano al código de máquina), como el ejemplo de C #. Un transpilador convierte un lenguaje de alto nivel en un lenguaje de nivel similar (de abstracción) (también de alto nivel). *

El resultado del código compilado normalmente no es un lenguaje que escribiría usted mismo . El resultado de un transpilador es otro lenguaje de alto nivel. En teoría, podría escribir IL (como ejemplo) pero en realidad está diseñado para ser producido por un compilador y no hay herramientas o soporte para hacer esto, usted produce IL compilando C # / vb.net, solamente. Considerando que Javascript es un lenguaje de programación utilizable (y usado) por derecho propio.

* Muchas advertencias ya que las definiciones de estas palabras y su uso son bastante vagas

Liam
fuente
12
¿No es JavaScript un nivel estrictamente más bajo que TypeScript?
Bergi
3
Aunque todo en esta respuesta es correcto y útil, especialmente porque la definición de compilación es siempre una cuestión de confusión, no responde a la pregunta del título. Esta respuesta solo habla de TypeScript, mientras que la pregunta es sobre Angular. La diferencia es enorme. Es totalmente posible usar Angular sin siquiera saber que TS es una cosa. Me sorprende que esta respuesta haya sido aceptada.
Pedro A
3
Un compilador necesita comprender esencialmente todo el programa para generar otro programa (que generalmente hace lo mismo pero en otro lenguaje, esto incluye código de máquina).
Thorbjørn Ravn Andersen
8
Lo leí dos veces y no pude encontrar la respuesta a la pregunta aquí. La respuesta está abajo.
kuncevic.dev
5
La pregunta implícita que estaba haciendo el OP, por lo que aceptaron esto, fue "¿es correcto llamar al compilador Angular un compilador?" - y eso es lo que responde esta respuesta. Entonces +1 de mi parte. Consulte también ¿Qué quieren decir las personas cuando dicen "transpiler"? y el seguimiento "Mis primeros quince compiladores" .
ShreevatsaR
70

Parece que estás haciendo tres preguntas en una:

  • ¿Cuál es la diferencia entre un compilador y un transpilador?
  • ¿Angular y TypeScript implementan compiladores o transpiladores?
  • ¿Existe un compilador angular separado? ¿Qué compila?

¿Cuál es la diferencia entre un compilador y un transpilador?

@ JörgWMittag proporcionó una muy buena respuesta a esta pregunta.

¿Angular y TypeScript implementan compiladores o transpiladores?

Tanto TS como Angular implementan compiladores reales . Siguen las mismas etapas de análisis léxico, análisis sintáctico, análisis semántico y generación de código que los compiladores C / C ++ que producen código ensamblador (excepto probablemente para optimización). Puede ver que la clase / carpeta se denomina "compilador" tanto en Angular como en TS .

El compilador angular no está realmente relacionado con el compilador de TypeScript. Estos son compiladores muy diferentes.

¿Existe un compilador angular separado? ¿Qué compila?

Angular tiene dos compiladores:

  • Ver compilador
  • Compilador de módulos

El trabajo del compilador de vistas es transformar la plantilla que especifique para la plantilla de componente en la representación interna de un componente que es una fábrica de vistas que luego se utiliza para crear una instancia de vista .

Además de transformar la plantilla, el compilador de vistas también compila diversa información de metadatos en forma de decoradores como @HostBinding, @ViewChildetc.

Suponga que define un componente y su plantilla así:

@Component({
  selector: 'a-comp',
  template: '<span>A Component</span>'
})
class AComponent {}

Con estos datos, el compilador genera la siguiente fábrica de componentes ligeramente simplificada:

function View_AComponent {
  return jit_viewDef1(0,[
      elementDef2(0,null,null,1,'span',...),
      jit_textDef3(null,['My name is ',...])
    ]

Describe la estructura de una vista de componente y se utiliza al crear una instancia del componente. El primer nodo es la definición del elemento y el segundo es la definición del texto. Puede ver que cada nodo obtiene la información que necesita cuando se crea una instancia a través de la lista de parámetros. Es un trabajo de un compilador resolver todas las dependencias requeridas y proporcionarlas en el tiempo de ejecución.

Recomiendo encarecidamente leer estos artículos:

Además, vea la respuesta a ¿Cuál es la diferencia entre el compilador Angular AOT y JIT?

El trabajo del compilador de módulos es crear una fábrica de módulos que básicamente contiene definiciones fusionadas de los proveedores.

Para obtener más información, lea:

Max Koretskyi
fuente
1
@codepleb, vea esta respuesta de Bergi
Max Koretskyi
1
@codepleb Tenga en cuenta que GCC y muchos otros compiladores no producen código de máquina en absoluto. En la práctica, GCC llama automáticamente a los sistemas para que produzcan código de máquina, pero el código que produce sin ayuda externa es simplemente ensamblaje, que luego se entrega a un ensamblador externo.
prosfilaes
7
@codepleb Esta respuesta es muy superior y realmente responde a su pregunta. Todavía hay tiempo para reconsiderar su juicio original.
async
3
@codepleb no hay una buena razón para que el término "transpiler" exista o alguna vez haya existido, todo lo que hace es engañar.
Leushenko
2
@stom, lo siento, esa pregunta es demasiado amplia. Sin embargo, la respuesta más votada es bastante buena
Max Koretskyi
54

Mecanografiado transpira a JS. Luego está el temblor de árboles, "menos" (opcional) y qué más en el proceso de realizar una implementación. Pero nada de eso (afaik) tiene nada que ver con "compilar". Todo se incluye y optimiza en gran medida, pero en realidad no está compilado, ¿verdad?

La compilación significa transformar un programa escrito en un lenguaje A en un programa semánticamente equivalente escrito en el lenguaje B de tal manera que evaluar el programa compilado de acuerdo con las reglas del lenguaje B (por ejemplo, interpretarlo con un intérprete para B ) produce el mismo resultado y tiene la los mismos efectos secundarios que evaluar el programa original de acuerdo con las reglas del lenguaje A (por ejemplo, interpretarlo con un intérprete para A ).

Compilación significa simplemente traducir un programa de lenguaje A a la lengua B . Eso es todo lo que significa. (Tenga en cuenta también que es perfectamente posible que A y B sean el mismo idioma).

En algunos casos, tenemos nombres más especializados para ciertos tipos de compiladores, dependiendo de qué son A y B , y qué hace el compilador:

  • si A se percibe como lenguaje ensamblador y B se percibe como lenguaje máquina, entonces lo llamamos ensamblador ,
  • si se percibe que A es lenguaje de máquina y B se percibe como lenguaje ensamblador, entonces lo llamamos desensamblador ,
  • si se percibe que A es de un nivel más bajo que B , entonces lo llamamos descompilador ,
  • si A y B son el mismo lenguaje, y el programa resultante es de alguna manera más rápido o más ligero, entonces lo llamamos optimizador ,
  • si A y B son los mismos lenguajes, y el programa resultante es más pequeño, lo llamamos minificador ,
  • si A y B son los mismos lenguajes y el programa resultante es menos legible, entonces lo llamamos ofuscador ,
  • si se percibe que A y B se encuentran aproximadamente en el mismo nivel de abstracción, entonces lo llamamos transpilador , y
  • si se percibe que A y B se encuentran aproximadamente en el mismo nivel de abstracción y el programa resultante conserva el formato, los comentarios y la intención del programador de manera que sea posible mantener el programa resultante de la misma manera que el programa original, entonces llamamos es una herramienta de reingeniería .

Además, tenga en cuenta que las fuentes más antiguas pueden utilizar los términos "traducción" y "traductor" en lugar de "compilación" y "compilador". Por ejemplo, C habla de "unidades de traducción".

También puede tropezar con el término "procesador de idiomas". Esto puede significar un compilador, un intérprete o tanto compiladores como intérpretes, según la definición.

Javascript en sí todavía se interpreta, ¿verdad?

JavaScript es un idioma. Los idiomas son un conjunto de reglas y restricciones lógicas. Los idiomas no se interpretan ni compilan. Los idiomas simplemente son .

La compilación y la interpretación son características de un compilador o intérprete (¡obvio!). Cada idioma se puede implementar con un compilador y cada idioma se puede implementar con un intérprete. Muchos lenguajes tienen compiladores e intérpretes. Muchos motores de ejecución modernos de alto rendimiento tienen al menos un compilador y al menos un intérprete.

Estos dos términos pertenecen a diferentes capas de abstracción. Si el inglés fuera un idioma escrito, "interpreted-language" sería un error de tipo.

Tenga en cuenta también que algunos lenguajes no tienen ni un intérprete ni un compilador. Hay lenguajes que no tienen implementación alguna. Aún así, son idiomas y puedes escribir programas en ellos. Simplemente no puedes ejecutarlos.

Además, ten en cuenta que todo se interpreta en algún momento : si quieres ejecutar algo, debes interpretarlo. La compilación simplemente traduce el código de un idioma a otro. No lo ejecuta. La interpretación lo ejecuta. (A veces, cuando se implementa un intérprete en hardware, lo llamamos "CPU", pero sigue siendo un intérprete).

Caso en cuestión: cada implementación de JavaScript convencional existente actualmente tiene un compilador.

V8 comenzó como un compilador puro: compilaba JavaScript directamente en código de máquina nativo moderadamente optimizado. Posteriormente, se agregó un segundo compilador. Ahora, hay dos compiladores: un compilador liviano que produce código moderadamente optimizado pero el compilador en sí es muy rápido y usa poca RAM. Este compilador también inyecta código de creación de perfiles en el código compilado. El segundo compilador es un compilador más pesado, más lento y más caro, que, sin embargo, produce un código mucho más ajustado y mucho más rápido. También utiliza los resultados del código de generación de perfiles inyectado por el primer compilador para tomar decisiones de optimización dinámica. Además, la decisión de qué código volver a compilar utilizando el segundo compilador se toma en función de esa información de perfil. Tenga en cuenta que en ningún momento hay un intérprete involucrado. V8 nunca interpreta, siempre compila. No lo hace Incluso contiene un intérprete. (En realidad, creo que hoy en día sí, estoy describiendo las dos primeras iteraciones).

SpiderMonkey compila JavaScript en el código de bytes de SpiderMonkey, que luego interpreta. El intérprete también perfila el código, y luego el código que se ejecuta con más frecuencia es compilado por un compilador en código de máquina nativo. Entonces, SpiderMonkey contiene dos compiladores: uno de JavaScript al código de bytes de SpiderMonkey y otro del código de bytes de SpiderMonkey al código de máquina nativo.

Casi todos los motores de ejecución de JavaScript (con la excepción de V8) siguen este modelo de un compilador AOT que compila JavaScript en código de bytes, y un motor de modo mixto que cambia entre interpretar y compilar ese código de bytes.

Escribiste en un comentario:

Realmente estaba pensando que el código de máquina está involucrado en algún lugar.

¿Qué significa "código máquina"?

¿Qué es el lenguaje de máquina de un hombre? ¿El lenguaje intermedio de otro hombre y viceversa? Por ejemplo, hay CPU que pueden ejecutar de forma nativa el código de bytes de JVM, en tal CPU, el código de bytes de JVM es un código de máquina nativo. Y hay intérpretes para el código de máquina x86, cuando se ejecuta ese código de máquina x86 se interpreta el código de bytes.

Hay un intérprete x86 llamado JPC escrito en Java. Si ejecuto código de máquina x86 en JPC que se ejecuta en una CPU JVM nativa ... ¿cuál es el código de bytes y cuál es el código nativo? Si compilo código de máquina x86 en JavaScript (sí, hay herramientas que pueden hacer eso) y lo ejecuto en un navegador en mi teléfono (que tiene una CPU ARM), ¿cuál es el código de bytes y cuál es el código de máquina nativo? ¿Qué pasa si el programa que estoy compilando es un emulador SPARC y lo uso para ejecutar código SPARC?

Tenga en cuenta que cada lenguaje induce una máquina abstracta y es lenguaje de máquina para esa máquina. Entonces, todos los idiomas (incluidos los de muy alto nivel) son códigos de máquina nativos. Además, puede escribir un intérprete para cada idioma. Por lo tanto, todos los idiomas (incluido el código de máquina x86) no son nativos.

Jörg W Mittag
fuente
4
+1 por la explicación profunda del concepto de compilación, y si pudiera, otro +1 por esos puntos. Muy útil.
Pedro A
1
Aunque, tengo que decirlo, técnicamente esto no responde a la pregunta del título ... ¡Aún así, un +1 merecido de mi parte!
Pedro A
Estoy de acuerdo en que está implícito, pero la respuesta a la pregunta del título es "todo lo que el OP enumera como no compilación es lo que es la compilación angular".
Jörg W Mittag
Muy buena explicación de cómo esto se trata en realidad de convenciones de nombres en lugar de diferencias sustanciales. Quizás podría mejorarse mencionando el microcódigo, para señalar que incluso a nivel de código de máquina, no estás 'en el metal' ...
AakashM
1
De alguna manera recuerdo haber aprendido qué es un compilador. Si alguien me hubiera dicho en ese entonces que "compilador" es sinónimo de "traductor de código", hubiera sido mucho más fácil obtener para qué sirve o por qué lo necesitamos. Claro, esto suena ridículo desde el punto de vista de hoy en día, pero esto solo me dice una vez más cuánto se puede beneficiar uno con solo tener a la persona adecuada para enseñarle algo. Gracias. :)
codepleb
18

Obtener el código que ha escrito para que se ejecute en un navegador implica dos cosas:

1) Transpilar el Typecript a JavaScript . Este es un problema resuelto. Creo que solo usan webpack.

2) Compilar las abstracciones angulares en JavaScript . Me refiero a cosas como componentes, tuberías, directivas, plantillas, etc. Esto es en lo que trabaja el equipo de núcleo angular.

En caso de que esté realmente interesado en ese segundo bit, el compilador angular, observe al autor del compilador Tobias Bosch explicar el compilador angular en AngularConnect 2016 .

Creo que hay un poco de confusión entre transpilar y compilar. De alguna manera no importa y es una cuestión de gusto personal, ambos son simplemente transformaciones entre representaciones de código. Pero la definición que utilizo personalmente es que la transpilación es entre dos lenguajes diferentes en un nivel de abstracción similar (por ejemplo, mecanografiado a javascript), mientras que la compilación requiere un paso hacia abajo en el nivel de abstracción. Creo que desde plantillas, componentes, tuberías, directivas, etc., hasta solo javascript es un paso hacia abajo en la escalera de abstracción, y por eso se llama compilador.

Nathan Cooper
fuente
1

Compilador angular

Uno de los cambios más importantes de Angular 4 a 5 es que el compilador ha sido reescrito para ser más rápido y completo. En el pasado, las aplicaciones de Angular usaban lo que llamamos compilación Just-in-Time (JIT), donde la aplicación se compilaba en tiempo de ejecución en el navegador antes de ejecutarse. Las actualizaciones del compilador en Angular 5 avanzaron el cambio a AOT, lo que hizo que la aplicación se ejecutara más rápido ya que realiza menos compilación al ejecutar la aplicación. AOT se habilita de forma predeterminada en cualquier compilación de producción desde la versión 1.5 de Angular CLI.

Digamos que queremos crear una aplicación para la implementación y ejecutar el siguiente comando:

ng build --prod

Suceden algunas cosas: versión de producción, minificación, activos de paquetes, hash de nombre de archivo, agitación de árbol, AOT ... (podemos habilitar / deshabilitar esto usando banderas, por ejemplo, aot = false). En resumen, el indicador prod crea un paquete optimizado de la aplicación haciendo la compilación AOT usando el ngc (el compilador angular) para crear código optimizado listo para el navegador ( Sí, precompila las plantillas ).

Compilador TypeScript

El compilador de TypeScript, tsc , es responsable de compilar archivos de TypeScript. Es el compilador el responsable de implementar las funciones de TypeScript, como los tipos estáticos, y el resultado es JavaScript puro del que se han eliminado las palabras clave y expresiones de TypeScript.

El compilador de TypeScript tiene dos características principales: es un transpilador y un verificador de tipos. El compilador transpila TypeScript a JavaScript. Realiza las siguientes transformaciones en su código fuente:

  • Elimina todo tipo de anotaciones.
  • Compile nuevas funciones de JavaScript para versiones antiguas de JavaScript.
  • Compile funciones de TypeScript que no sean JavaScript estándar.

Invocándolo, el compilador busca configuraciones cargadas en tsconfig.json ( aquí se puede encontrar una lista detallada de todas las opciones del compilador, junto con los valores predeterminados ).

En la mayoría de los aspectos, el compilador de TypeScript funciona como cualquier compilador. Pero hay una diferencia que puede sorprender a los desprevenidos: de forma predeterminada, el compilador continúa emitiendo código JavaScript incluso cuando encuentra un error. Afortunadamente, este comportamiento se puede desactivar estableciendo el noEmitOnErrorvalor de configuración en verdadero en el archivo tsconfig.json.

Nota : tsc y ngc tienen diferentes propósitos y no se trata de seleccionar uno sobre el otro. Esta respuesta puede ser de interés .

Esta respuesta se elaboró ​​en función del contenido de los siguientes libros

  • Cloe, M. (2018). "Proyectos de Angular 5: aprenda a crear aplicaciones web de una sola página con más de 70 proyectos".

  • Dewey, B., Grossnicklaus, K., Japikse, P. (2017). "Creación de aplicaciones web con Visual Studio 2017: uso de .NET Core y marcos de JavaScript modernos".

  • Freeman, A. (2019). "TypeScript esencial: de principiante a profesional".

  • Ghiya, P. (2018). "Microservicios TypeScript".

  • Iskandar, A., Chivukulu, S. (2019). "Desarrollo Web con Angular y Bootstrap - Tercera Edición".

  • Hennessy, K., Arora, C. (2018). "Angular 6 por ejemplo".

  • Jansen, R., Wolf, I., Vane, V. (2016). "TypeScript: desarrollo JavaScript moderno".

  • Mohammed, Z. (2019). "Proyectos Angulares".

  • Seshadri, S. (2018). "Angular: en funcionamiento".

  • Wilken, J. (2018). "Angular en acción".

Tiago Martins Peres 李大仁
fuente