O compilador de fechamento é uma ferramenta para fazer o download do JavaScript e executar mais rápido. É um verdadeiro compilador para JavaScript. Em vez de compilar de um idioma de origem para o código da máquina, ele compila do JavaScript para melhor o JavaScript. Ele analisa o seu JavaScript, o analisa, remove o código morto e reescreve e minimiza o que resta. Ele também verifica a sintaxe, referências e tipos variáveis e alerta sobre armadilhas comuns de JavaScript.
Os modos de compilação que não ADVANCED
sempre foram uma reflexão tardia e pretermos esses modos. Acreditamos que outras ferramentas têm um desempenho comparável para modos não ADVANCED
e são melhor integrados ao ecossistema JS mais amplo.
O compilador de fechamento não é adequado para JavaScript arbitrário. Para que o modo ADVANCED
gerar JavaScript de trabalho, o código JS de entrada deve ser escrito com o compilador de fechamento em mente.
O compilador de fechamento é um otimizador de "mundo inteiro". Ele espera ver diretamente ou pelo menos receber informações sobre todo o uso possível de todas as variáveis globais ou exportadas e cada nome de propriedade.
Ele removerá e renomeará agressivamente variáveis e propriedades para tornar o código de saída o menor possível. Isso resultará em JS de saída quebrada, se os usos de variáveis ou propriedades globais estiverem ocultas.
Embora se possa escrever arquivos externos personalizados para dizer ao compilador para deixar alguns nomes inalterados, para que eles possam ser acessados com segurança pelo código que não faz parte da compilação, isso geralmente é tedioso de manter.
A renomeação da propriedade do compilador de fechamento exige que você acesse consistentemente uma propriedade com obj[p]
ou obj.propName
, mas não ambos.
Quando você acessa uma propriedade com colchetes quadrados (por exemplo, obj[p]
) ou usando algum outro método indireto como let {p} = obj;
Isso esconde o nome literal da propriedade que está sendo referenciada do compilador. Não pode saber se obj.propName
está se referindo à mesma propriedade que obj[p]
. Em alguns casos, ele notará esse problema e interrompe a compilação com um erro. Em outros casos, ele renomeará propName
para algo mais curto, sem perceber esse problema, resultando em código JS de saída quebrado.
O compilador de fechamento abre agressivamente variáveis globais e nomes de nomes de propriedades em variáveis globais (por exemplo, myFoo.some.sub.property
-> myFoo$some$sub$property
), para facilitar o raciocínio sobre eles para detectar código não utilizado.
Ele tenta recuar de fazer isso ou parar com um erro ao fazê -lo gerar saída JS quebrada, mas há casos em que não reconhecerá o problema e simplesmente gerará JS quebrado sem aviso prévio. É muito mais provável que isso aconteça no código que não foi explicitamente escrito com o compilador de fechamento em mente.
O compilador de fechamento e os externos que ele usa por padrão assumem que o ambiente de destino é uma janela do navegador da web.
Os webworkers também são suportados, mas o compilador provavelmente deixará de avisá -lo se você tentar usar recursos que não estão realmente disponíveis para um webworker.
Alguns arquivos e recursos externos foram adicionados ao compilador de fechamento para suportar o ambiente NODEJS, mas não são apoiados ativamente e nunca funcionaram muito bem.
JavaScript que não usa o goog.module()
e goog.require()
do base.js
para declarar e usar módulos não é bem suportado.
A sintaxe import
e export
do ECMAScript não existia até 2015. O compilador de fechamento e closure-library
desenvolveram seus próprios meios para declarar e usar módulos, e essa continua sendo a única maneira bem suportada de definir módulos.
O compilador implementa algum entendimento dos módulos ECMAScript, mas a alteração dos projetos do Google para usar a sintaxe mais recente nunca ofereceu um benefício que valia o custo da mudança. O código TypeScript do Google usa módulos ECMAScript, mas eles são convertidos para goog.module()
Sintaxe antes que o Compiler de fechamento os veja. Portanto, efetivamente o suporte ao ECMAScript Modules não é utilizado no Google. Isso significa que é improvável que notemos ou corrigimos bugs no suporte para módulos ECMAScript.
O suporte aos módulos Commonjs como entrada foi adicionado no passado, mas não é usado no Google e provavelmente será totalmente removido em 2024.
O compilador de fechamento é usado pelo Google Projects para:
Reduza drasticamente o tamanho do código de aplicativos JavaScript muito grandes
Verifique o código JS quanto a erros e a conformidade com as melhores práticas gerais e/ou específicas do projeto.
Defina mensagens visíveis ao usuário de uma maneira que possibilite substituí-las por versões traduzidas para criar versões localizadas de um aplicativo.
Transpilar recursos JS mais recentes em um formulário que será executado em navegadores que não têm suporte para esses recursos.
Quebre o aplicativo de saída em pedaços que podem ser carregados individualmente, conforme necessário.
Nota: esses pedaços são scripts JavaScript simples. Eles não usam a sintaxe import
e export
do ECMAScript.
Para alcançar esses objetivos, o compilador de fechamento coloca muitas restrições em sua entrada:
Use goog.module()
e goog.require()
para declarar e usar módulos.
O suporte à sintaxe import
e export
adicionado no ES6 não é mantido ativamente.
Use anotações nos comentários para declarar informações do tipo e fornecer informações que o compilador precisa para evitar quebrar alguns padrões de código (por exemplo, @nocollapse
e @noinline
).
Use apenas acesso DOT (por exemplo, object.property
) ou use apenas acesso dinâmico (por exemplo, object[propertyName]
ou Object.keys(object)
) para acessar as propriedades de um tipo de objeto específico.
Misturando estes ocultará alguns usos de uma propriedade do compilador, resultando em código de saída quebrado quando renunciar à propriedade.
Em geral, o compilador espera ver um aplicativo inteiro como uma única compilação. As interfaces devem ser cuidadosamente e explicitamente construídas para permitir a interoperação com o código fora da unidade de compilação.
O compilador assume que pode ver todos os usos de todas as variáveis e propriedades e as renomeará livremente ou removê -las se parecer não utilizadas.
Use arquivos externos para informar o compilador de quaisquer variáveis ou propriedades que ele não deve remover ou renomear.
Existem arquivos externos padrão que declaram as APIs JS e DOM padrão. Mais arquivos externos são necessários se você estiver usando APIs menos comuns ou espera que algum código JavaScript externo acesse uma API no código que você está compilando.
A maneira mais fácil de instalar o compilador é com o npm ou o fio:
yarn global add google-closure-compiler
# OR
npm i -g google-closure-compiler
O gerenciador de pacotes vinculará o binário para você e você poderá acessar o compilador com:
google-closure-compiler
Isso inicia o compilador no modo interativo. Tipo:
var x = 17 + 25 ;
Pressione Enter
, depois Ctrl+Z
(no Windows) ou Ctrl+D
(no Mac/Linux) e Enter
novamente. O compilador responderá com a saída compilada (usando o modo SIMPLE
por padrão):
var x = 42 ;
Uma versão pré-compilada do compilador também está disponível via Maven.
O compilador de fechamento tem muitas opções para ler a entrada de um arquivo, gravar saída em um arquivo, verificar seu código e executar otimizações. Aqui está um exemplo simples de comprimir um programa JS:
google-closure-compiler --js file.js --js_output_file file.out.js
Obtemos o máximo de benefícios do compilador se fornecermos todo o nosso código -fonte (consulte Compilar vários scripts), o que nos permite usar otimizações ADVANCED
:
google-closure-compiler -O ADVANCED rollup.js --js_output_file rollup.min.js
Nota: A saída abaixo é apenas um exemplo e não está atualizada. As bandeiras e opções da página do wiki são atualizadas durante cada versão.
Para ver todas as opções do compilador, digite:
google-closure-compiler --help
--flag | Descrição |
---|---|
--compilation_level (-O) | Especifica o nível de compilação a ser usado. Opções: BUNDLE , WHITESPACE_ONLY , SIMPLE (padrão), ADVANCED |
--env | Determina o conjunto de externos construídos para carregar. Opções: BROWSER , CUSTOM . Padrões para BROWSER . |
--externs | O arquivo que contém JavaScript extern. Você pode especificar múltiplos |
--js | O nome do JavaScript. Você pode especificar múltiplos. O nome do sinalizador é opcional, porque os args são interpretados como arquivos por padrão. Você também pode usar padrões globais de estilo mínimo. Por exemplo, use --js='**.js' --js='!**_test.js' _test.js |
--js_output_file | Nome do arquivo de saída primária. Se não for especificado, a saída é gravada para STDOUT. |
--language_in | Define as especificações do idioma às quais as fontes de entrada devem estar em conformidade. Opções: ECMASCRIPT3 , ECMASCRIPT5 , ECMASCRIPT5_STRICT , ECMASCRIPT_2015 , ECMASCRIPT_2016 ECMASCRIPT_NEXT ECMASCRIPT_2017 , ECMASCRIPT_2018 , STABLE , ECMASCRIPT_2019 |
--language_out | Define a especificação do idioma para a qual a saída deve estar em conformidade. Opções: ECMASCRIPT3 , ECMASCRIPT5 , ECMASCRIPT5_STRICT , ECMASCRIPT_2015 , ECMASCRIPT_2016 , ECMASCRIPT_2017 , ECMASCRIPT_2018 , ECMASCRIPT_2019 , STABLE |
--warning_level (-W) | Especifica o nível de aviso a ser usado. Opções: QUIET , DEFAULT , VERBOSE |
Você pode acessar o compilador em um 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 pacote fornecerá acesso programático ao binário nativo de Graal na maioria dos casos e voltará à versão Java.
Se você possui vários scripts, compilá -los todos juntos com um comando compilar.
google-closure-compiler in1.js in2.js in3.js --js_output_file out.js
Você também pode usar globs no estilo mínimo.
# 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
O compilador de fechamento concatenará os arquivos na ordem em que eles foram aprovados na linha de comando.
Se você estiver usando globs ou muitos arquivos, poderá começar a ter problemas com o gerenciamento de dependências entre os scripts. Nesse caso, você deve usar o lib/base.js incluído que fornece funções para aplicar dependências entre scripts (ou seja, goog.module
e goog.require
). O compilador de fechamento reordenará as entradas automaticamente.
O compilador de fechamento libera com lib/base.js que fornece funções e variáveis de JavaScript que servem como primitivas, permitindo certos recursos do compilador de fechamento. Este arquivo é um derivado da base de nome idêntica na biblioteca de fechamento depreciada em breve. Este base.js
será suportado pelo compilador de fechamento daqui para frente e poderá receber novos recursos. Foi projetado para manter apenas suas partes principais percebidas.
Para construir o compilador, você precisará do seguinte:
Pré -requisito | Descrição |
---|---|
Java 11 ou mais tarde | Usado para compilar o código -fonte do compilador. |
Nodejs | Usado para gerar recursos usados pela compilação Java |
Git | Usado por Bazel para baixar dependências. |
Bazelisco | Usado para construir os vários alvos do compilador. |
O Bazelisk é um invólucro ao redor do Bazel que carrega dinamicamente a versão apropriada do Bazel para um determinado repositório. Usá -lo impede que erros espúrios resultem do uso da versão errada do Bazel para construir o compilador, além de facilitar o uso de diferentes versões do Bazel para outros projetos.
O Bazelisk está disponível em muitos gerentes de pacotes. Sinta -se à vontade para usar o que você estiver mais confortável.
Instruções para instalar o Bazelisk.
$ bazelisk build //:compiler_uberjar_deploy.jar
# OR to build everything
$ bazelisk build //:all
Os testes podem ser executados de maneira semelhante. O comando a seguir executará todos os testes no repositório.
$ bazelisk test //:all
Existem centenas de metas de teste individuais, por isso levará alguns minutos para executar todos eles. Durante o desenvolvimento, geralmente é melhor especificar os testes exatos em que você está interessado.
bazelisk test //: $path_to_test_file
Veja Integrações de Bazel IDE.
Uma vez que o compilador for construído, o frasco compilado estará no bazel-bin/
. Você pode acessá -lo com uma chamada para java -jar ...
ou usando o script package.json:
# java -jar bazel-bin/compiler_uberjar_deploy.jar [...args]
yarn compile [...args]
src/com/google/javascript/jscomp/CommandLineRunner.java
ou crie sua própria versão estendida da classe.No entanto, você optar por contribuir, cumpra nosso código de conduta para manter nossa comunidade um local saudável e acolhedor.
Copyright 2009 The Closure Compiler Authors.
Licenciado sob a licença Apache, versão 2.0 (a "licença"); Você não pode usar esse arquivo, exceto em conformidade com a licença. Você pode obter uma cópia da licença em http://www.apache.org/license/license-2.0.
A menos que exigido pela lei aplicável ou acordada por escrito, o software distribuído pela licença é distribuído "como está", sem garantias ou condições de qualquer tipo, expressa ou implícita. Consulte a licença para o idioma específico que rege as permissões e limitações sob a licença.
Caminho de código | src/com/google/javascript/rhino , test/com/google/javascript/rhino |
Url | https://developer.mozilla.org/en-us/docs/mozilla/projects/rhino |
Versão | 1.5R3, com modificações pesadas |
Licença | Netscape Public License e MPL / GPL Licença dupla |
Descrição | Uma cópia parcial do Mozilla Rhino. Mozilla Rhino é uma implementação do JavaScript para a JVM. As estruturas de dados da árvore de análise JavaScript foram extraídas e modificadas significativamente para uso pelo compilador JavaScript do Google. |
Modificações locais | Os pacotes foram renomeados. Todo o código não relevante para a árvore de análise foi removido. Um analisador JSDOC e sistema de digitação estática foram adicionados. |
Url | http://args4j.kohsuke.org/ |
Versão | 2.33 |
Licença | Mit |
Descrição | O ARGS4J é uma pequena biblioteca de classes Java que facilita a análise das opções/argumentos da linha de comando no seu aplicativo CUI. |
Modificações locais | Nenhum |
Url | https://github.com/google/guava |
Versão | 31.0.1 |
Licença | Licença Apache 2.0 |
Descrição | As principais bibliotecas Java do Google. |
Modificações locais | Nenhum |
Url | https://github.com/findbugsproject/findbugs |
Versão | 3.0.1 |
Licença | Licença BSD |
Descrição | Anotações para detecção de defeitos de software. |
Modificações locais | Nenhum |
Url | http://junit.org/junit4/ |
Versão | 4.13 |
Licença | Licença pública comum 1.0 |
Descrição | Uma estrutura para escrever e executar testes automatizados em Java. |
Modificações locais | Nenhum |
Url | https://github.com/google/protobuf |
Versão | 3.0.2 |
Licença | Nova licença BSD |
Descrição | Bibliotecas de suporte para buffers de protocolo, uma codificação de dados estruturados. |
Modificações locais | Nenhum |
Url | https://github.com/google/re2j |
Versão | 1.3 |
Licença | Nova licença BSD |
Descrição | TEMPO LINEAR COMPRIMEIRA EXPRESSÃO COMPRIMENTO EM JAVA. |
Modificações locais | Nenhum |
Url | https://github.com/google/truth |
Versão | 1.1 |
Licença | Licença Apache 2.0 |
Descrição | Estrutura de afirmação/proposição para testes de unidade Java |
Modificações locais | Nenhum |
Url | https://ant.apache.org/bindownload.cgi |
Versão | 1.10.11 |
Licença | Licença Apache 2.0 |
Descrição | A formiga é uma ferramenta de construção baseada em Java. Em teoria, é como "Make" sem as rugas de Make e com a portabilidade total do código Java puro. |
Modificações locais | Nenhum |
Url | https://github.com/google/gson |
Versão | 2.9.1 |
Licença | Licença Apache 2.0 |
Descrição | Uma biblioteca Java para converter JSON em objetos Java e vice-versa |
Modificações locais | Nenhum |
Caminho de código | contrib/nodejs |
Url | https://github.com/dcodeio/node.js-lure-compiler-externs |
Versão | E891B4FBCF5F466CC4307B0FA842A7D8163A073A |
Licença | Licença Apache 2.0 |
Descrição | Contratos de tipo para NodeJS APIs |
Modificações locais | Mudanças substanciais para torná -las compatíveis com o npmCommandlinerunner. |