El compilador de cierre es una herramienta para descargar y ejecutar JavaScript más rápido. Es un verdadero compilador para JavaScript. En lugar de compilar de un lenguaje de origen a un código de máquina, se compila de JavaScript a Better JavaScript. Analiza su JavaScript, lo analiza, elimina el código muerto y reescribe y minimiza lo que queda. También verifica la sintaxis, las referencias variables y los tipos, y advierte sobre las dificultades comunes de JavaScript.
Los modos de compilación distintos de ADVANCED
siempre fueron una ocurrencia tardía y hemos desaprobado esos modos. Creemos que otras herramientas funcionan comparablemente para modos no ADVANCED
y están mejor integrados en el ecosistema JS más amplio.
El compilador de cierre no es adecuado para JavaScript arbitrario. Para que el modo ADVANCED
genere JavaScript en funcionamiento, el código de entrada JS debe escribirse con el compilador de cierre en mente.
El compilador de cierre es un optimizador del "mundo entero". Espera ver directamente o al menos recibir información sobre cada uso posible de cada variable global o exportada y cada nombre de propiedad.
Eliminará y cambiará el nombre de variables y propiedades para que el código de salida sea lo más pequeño posible. Esto dará como resultado una salida rota JS, si los usos de las variables o propiedades globales se ocultan.
Aunque se puede escribir archivos externs personalizados para decirle al compilador que deje algunos nombres sin cambios para que se pueda acceder de manera segura por código que no forme parte de la compilación, esto a menudo es tedioso de mantener.
El cambio de nombre del compilador de cierre requiere que acceda constantemente a una propiedad con obj[p]
u obj.propName
, pero no ambos.
Cuando accede a una propiedad con soportes cuadrados (por ejemplo, obj[p]
) o usa algún otro método indirecto como let {p} = obj;
Esto oculta el nombre literal de la propiedad que se hace referencia desde el compilador. No puede saber si obj.propName
se refiere a la misma propiedad que obj[p]
. En algunos casos, notará este problema y detendrá la compilación con un error. En otros casos, cambiará el nombre propName
a algo más corto, sin notar este problema, lo que dará como resultado un código JS de salida roto.
El compilador de cierre incorpora agresivamente las variables globales y aplana las cadenas de los nombres de las propiedades en las variables globales (por ejemplo, myFoo.some.sub.property
-> myFoo$some$sub$property
), para facilitar el razonamiento sobre ellas para detectar el código no utilizado.
Intenta retroceder de hacer esto o detenerse con un error al hacerlo generará salida de JS rota, pero hay casos en los que no reconocerá el problema y simplemente generará JS roto sin previo aviso. Es mucho más probable que esto suceda en un código que no fue escrito explícitamente con el compilador de cierre en mente.
El compilador de cierre y los externos que utiliza por defecto supone que el entorno de destino es una ventana del navegador web.
Los trabajadores web también son compatibles, pero el compilador probablemente no le advertirá si intenta usar características que realmente no están disponibles para un trabajo web.
Se han agregado algunos archivos y características externs al compilador de cierre para admitir el entorno NodeJS, pero no son compatibles activamente y nunca funcionan muy bien.
JavaScript que no usa goog.module()
y goog.require()
de base.js
para declarar y usar módulos no es bien compatible.
La sintaxis import
y export
de ECMAScript no existió hasta 2015. El compilador de cierre y closure-library
desarrollaron sus propios medios para declarar y usar módulos, y esta sigue siendo la única forma bien soportada de definir módulos.
El compilador implementa cierta comprensión de los módulos de ECMAScript, pero cambiar los proyectos de Google para usar la sintaxis más nueva nunca ha ofrecido un beneficio que valiera el costo del cambio. El código TypeScript de Google usa módulos ECMAScript, pero se convierten en sintaxis goog.module()
antes de que el compilador de cierre los ve. Entonces, efectivamente, el soporte de módulos ECMAScript no se usa en Google. Esto significa que es poco probable que notemos o corrigamos errores en los módulos de soporte para ECMAScript.
El soporte para los módulos CommonJS como entrada se agregó en el pasado, pero no se usa en Google, y es probable que se elimine por completo en algún momento de 2024.
El compilador de cierre es utilizado por Google Projects para:
Reducir drásticamente el tamaño del código de aplicaciones JavaScript muy grandes
Consulte el código JS en busca de errores y conformidad con las mejores prácticas generales y/o específicas del proyecto.
Definir mensajes visibles del usuario de una manera que haga posible reemplazarlos con versiones traducidas para crear versiones localizadas de una aplicación.
Transpile JS más nuevo aparece en un formulario que se ejecutará en navegadores que carecen de soporte para esas características.
Romper la aplicación de salida en fragmentos que pueden cargarse individualmente según sea necesario.
Nota: estos trozos son scripts de JavaScript simples. No usan la sintaxis import
y export
de ECMAScript.
Para lograr estos objetivos, el compilador de cierre impone muchas restricciones a su entrada:
Use goog.module()
y goog.require()
para declarar y usar módulos.
El soporte para la sintaxis import
y export
agregada en ES6 no se mantiene activamente.
Use anotaciones en comentarios para declarar información de tipo y proporcionar información que el compilador necesita para evitar romper algunos patrones de código (por ejemplo, @nocollapse
y @noinline
).
Use solo DOT-Access (por ejemplo, object.property
) o solo use acceso dinámico (por ejemplo, object[propertyName]
u Object.keys(object)
) para acceder a las propiedades de un tipo de objeto particular.
Mezclar estos ocultará algunos usos de una propiedad del compilador, lo que resulta en un código de salida roto cuando renombre la propiedad.
En general, el compilador espera ver una aplicación completa como una sola compilación. Las interfaces deben construirse cuidadosamente y explícitamente para permitir la interoperación con código fuera de la unidad de compilación.
El compilador supone que puede ver todos los usos de todas las variables y propiedades y los cambiará libremente o los eliminará si parecen no usarlos.
Use archivos externs para informar al compilador de cualquier variable o propiedad que no debe eliminar ni cambiar el nombre.
Hay archivos externos predeterminados que declaran las API estándar JS y DOM Global. Se necesitan más archivos externs si está utilizando API menos comunes o espera que algún código JavaScript externo acceda a una API en el código que está compilando.
La forma más fácil de instalar el compilador es con npm o hilo:
yarn global add google-closure-compiler
# OR
npm i -g google-closure-compiler
El Administrador de paquetes vinculará el binario para usted y puede acceder al compilador con:
google-closure-compiler
Esto inicia el compilador en modo interactivo. Tipo:
var x = 17 + 25 ;
Presione Enter
, luego Ctrl+Z
(en Windows) o Ctrl+D
(en Mac/Linux), luego Enter
nuevamente. El compilador responderá con la salida compilada (usando el modo SIMPLE
de forma predeterminada):
var x = 42 ;
Una versión precompilada del compilador también está disponible a través de Maven.
El compilador de cierre tiene muchas opciones para leer la entrada de un archivo, escribir salida a un archivo, verificar su código y ejecutar optimizaciones. Aquí hay un ejemplo simple de comprimir un programa JS:
google-closure-compiler --js file.js --js_output_file file.out.js
Obtenemos el mayor beneficio del compilador si le damos todo nuestro código fuente (consulte Compilar múltiples scripts), lo que nos permite usar optimizaciones ADVANCED
:
google-closure-compiler -O ADVANCED rollup.js --js_output_file rollup.min.js
Nota: La siguiente salida es solo un ejemplo y no se mantiene actualizado. La página Wiki Flags and Opciones se actualiza durante cada versión.
Para ver todas las opciones del compilador, escriba:
google-closure-compiler --help
--flag | Descripción |
---|---|
--compilation_level (-O) | Especifica el nivel de compilación para usar. Opciones: BUNDLE , WHITESPACE_ONLY , SIMPLE (predeterminado), ADVANCED |
--env | Determina el conjunto de externas incorporados para cargar. Opciones: BROWSER , CUSTOM . El valor predeterminado al BROWSER . |
--externs | El archivo que contiene JavaScript Externs. Puede especificar múltiples |
--js | El nombre de archivo JavaScript. Puede especificar múltiples. El nombre del indicador es opcional, porque los ARG se interpretan como archivos de forma predeterminada. También puede usar patrones de globas de estilo minimatch. Por ejemplo, use --js='**.js' --js='!**_test.js' para incluir recursivamente todos los archivos JS que no terminan en _test.js |
--js_output_file | Nombre de archivo de salida principal. Si no se especifica, la salida se escribe en stdout. |
--language_in | Establece la especificación del lenguaje a la que deben cumplir las fuentes de entrada. Opciones: ECMASCRIPT3 , ECMASCRIPT5 , ECMASCRIPT5_STRICT , ECMASCRIPT_2015 , ECMASCRIPT_2016 , ECMASCRIPT_2017 , ECMASCRIPT_2018 , ECMASCRIPT_2019 , STABLE , ECMASCRIPT_NEXT |
--language_out | Establece la especificación del lenguaje a la que debe cumplir la salida. Opciones: ECMASCRIPT3 , ECMASCRIPT5 , ECMASCRIPT5_STRICT , ECMASCRIPT_2015 , ECMASCRIPT_2016 , ECMASCRIPT_2017 , ECMASCRIPT_2018 , ECMASCRIPT_2019 , STABLE |
--warning_level (-W) | Especifica el nivel de advertencia para usar. Opciones: QUIET , DEFAULT , VERBOSE |
Puede acceder al compilador en un programa JS importando google-closure-compiler
:
import closureCompiler from 'google-closure-compiler' ;
const { compiler } = closureCompiler ;
new compiler ( {
js : 'file-one.js' ,
compilation_level : 'ADVANCED'
} ) ;
Este paquete proporcionará acceso programático al binario de Graal nativo en la mayoría de los casos, y volverá a la versión Java de lo contrario.
Si tiene múltiples scripts, debe compilarlos todos junto con un comando de compilación.
google-closure-compiler in1.js in2.js in3.js --js_output_file out.js
También puede usar globos de estilo minimatch.
# Recursively include all js files in subdirs
google-closure-compiler ' src/**.js ' --js_output_file out.js
# Recursively include all js files in subdirs, excluding test files.
# Use single-quotes, so that bash doesn't try to expand the '!'
google-closure-compiler ' src/**.js ' ' !**_test.js ' --js_output_file out.js
El compilador de cierre concatenará los archivos en el orden que se pasan en la línea de comandos.
Si está utilizando globos o muchos archivos, puede comenzar a tener problemas para administrar dependencias entre scripts. En este caso, debe usar el Lib/Base.js incluido que proporcione funciones para hacer cumplir las dependencias entre scripts (a saber, goog.module
y goog.require
). El compilador de cierre volverá a ordenar las entradas automáticamente.
El compilador de cierre se libera con lib/base.js que proporciona funciones y variables de JavaScript que sirven como primitivas que permiten ciertas características del compilador de cierre. Este archivo es un derivado de la Base.js de Base.js en la biblioteca de cierre desagradable. Este base.js
será compatible con el compilador de cierre en el futuro y puede recibir nuevas características. Fue diseñado para conservar solo sus piezas centrales percibidas.
Para construir el compilador usted mismo, necesitará lo siguiente:
Requisito previo | Descripción |
---|---|
Java 11 o posterior | Utilizado para compilar el código fuente del compilador. |
Nodejs | Utilizado para generar recursos utilizados por Java Compilation |
Git | Utilizado por Bazel para descargar dependencias. |
Bazelisco | Se utiliza para construir los diversos objetivos del compilador. |
Bazelisk es un envoltorio alrededor de Bazel que carga dinámicamente la versión apropiada de Bazel para un repositorio determinado. Usarlo evita errores espurios que resulten del uso de la versión incorrecta de Bazel para construir el compilador, así como facilita el uso de diferentes versiones de bazel para otros proyectos.
Bazelisk está disponible a través de muchos administradores de paquetes. Siéntase libre de usar con lo que se sienta más cómodo.
Instrucciones para instalar Bazelisk.
$ bazelisk build //:compiler_uberjar_deploy.jar
# OR to build everything
$ bazelisk build //:all
Las pruebas se pueden ejecutar de manera similar. El siguiente comando ejecutará todas las pruebas en el repositorio.
$ bazelisk test //:all
Hay cientos de objetivos de prueba individuales, por lo que tomará unos minutos ejecutarlos todos. Mientras se desarrolla, generalmente es mejor especificar las pruebas exactas que le interesan.
bazelisk test //: $path_to_test_file
Ver integraciones BAZEL IDE.
Una vez que se haya construido el compilador, el frasco compilado estará en el bazel-bin/
directorio. Puede acceder a él con una llamada a java -jar ...
o utilizando el script paquete.json:
# java -jar bazel-bin/compiler_uberjar_deploy.jar [...args]
yarn compile [...args]
src/com/google/javascript/jscomp/CommandLineRunner.java
o cree su propia versión extendida de la clase.Sin embargo, usted elige contribuir, por favor, cumpla con nuestro Código de Conducta para mantener a nuestra comunidad un lugar saludable y acogedor.
Copyright 2009 Los autores del compilador de cierre.
Licenciado bajo la licencia Apache, versión 2.0 (la "licencia"); No puede usar este archivo, excepto de conformidad con la licencia. Puede obtener una copia de la licencia en http://www.apache.org/licenses/license-2.0.
A menos que la ley aplicable sea requerida o acordado por escrito, el software distribuido bajo la licencia se distribuye de manera "como es", sin garantías o condiciones de ningún tipo, ya sea expresas o implícitas. Consulte la licencia para los permisos y limitaciones de rigor de idioma específico bajo la licencia.
Ruta de código | src/com/google/javascript/rhino , test/com/google/javascript/rhino |
Url | https://developer.mozilla.org/en-us/docs/mozilla/projects/rhino |
Versión | 1.5R3, con grandes modificaciones |
Licencia | Licencia pública NetScape y Licencia Dual MPL / GPL |
Descripción | Una copia parcial de Mozilla Rhino. Mozilla Rhino es una implementación de JavaScript para el JVM. Las estructuras de datos del árbol de análisis de JavaScript fueron extraídas y modificadas significativamente para su uso por el compilador JavaScript de Google. |
Modificaciones locales | Los paquetes se han apagado. Se ha eliminado todo el código no relevante para el árbol de análisis. Se ha agregado un analizador JSDOC y un sistema de tipificación estática. |
Url | http://args4j.kohsuke.org/ |
Versión | 2.33 |
Licencia | MIT |
Descripción | Args4J es una pequeña biblioteca de clase Java que facilita el análisis de las opciones/argumentos de línea de comandos en su aplicación CUI. |
Modificaciones locales | Ninguno |
Url | https://github.com/google/guava |
Versión | 31.0.1 |
Licencia | Licencia de Apache 2.0 |
Descripción | Bibliotecas Java principales de Google. |
Modificaciones locales | Ninguno |
Url | https://github.com/findbugsproject/findbugs |
Versión | 3.0.1 |
Licencia | Licencia BSD |
Descripción | Anotaciones para la detección de defectos del software. |
Modificaciones locales | Ninguno |
Url | http://junit.org/junit4/ |
Versión | 4.13 |
Licencia | Licencia pública común 1.0 |
Descripción | Un marco para escribir y ejecutar pruebas automatizadas en Java. |
Modificaciones locales | Ninguno |
Url | https://github.com/google/protobuf |
Versión | 3.0.2 |
Licencia | Nueva licencia BSD |
Descripción | Soporte de bibliotecas para buffers de protocolo, una codificación de datos estructurados. |
Modificaciones locales | Ninguno |
Url | https://github.com/google/re2j |
Versión | 1.3 |
Licencia | Nueva licencia BSD |
Descripción | Tiempo lineal de expresión regular coincidencia en Java. |
Modificaciones locales | Ninguno |
Url | https://github.com/google/truth |
Versión | 1.1 |
Licencia | Licencia de Apache 2.0 |
Descripción | Marco de afirmación/proposición para pruebas unitarias de Java |
Modificaciones locales | Ninguno |
Url | https://ant.apache.org/bindownload.cgi |
Versión | 1.10.11 |
Licencia | Licencia de Apache 2.0 |
Descripción | ANT es una herramienta de construcción basada en Java. En teoría, es como "Make" sin arrugas de Make y con la portabilidad completa del código Java puro. |
Modificaciones locales | Ninguno |
Url | https://github.com/google/gson |
Versión | 2.9.1 |
Licencia | Licencia de Apache 2.0 |
Descripción | Una biblioteca de Java para convertir JSON a Java Objects y Viceversa |
Modificaciones locales | Ninguno |
Ruta de código | contrib/nodejs |
Url | https://github.com/dcodeio/node.js-closure-compiler-externs |
Versión | E891B4FBCF5F466CC4307B0FA842A7D8163A073A |
Licencia | Licencia Apache 2.0 |
Descripción | Escriba contratos para las API de NodeJS |
Modificaciones locales | Cambios sustanciales para hacerlos compatibles con NPMCommandlinerunner. |