The Closure Compiler - также называемый JSCompiler внутри компании Google - поддерживает большинство веб-ресурсов Google за счет оптимизации, проверки типов, транспиляции и организации кода JavaScript. Это делает Google более продуктивным и позволяет нам создавать JavaScript, используя методы разработки программного обеспечения, а не как случайный набор исходных файлов, связанных вместе.

Вы также можете использовать его, хотя это может быть непросто. ⚠️

Вы говорите, сложно? Из-за преимуществ, которые приносит вам закрытие, проблемы могут того стоить. В этом посте будет рассказано об упаковке, наборе текста и о том, как вы можете использовать компилятор в своих проектах.

Давай посмотрим демо, тогда

Ok! Загрузите веб-сервис Closure Compiler. Пусть вас не обманывает устаревший пользовательский интерфейс - он запускает весь компилятор под капотом.

Ссылка выше загрузит простой код ES6. Нажмите Скомпилировать и увидите справа уменьшенный результат ES5, который можно использовать в большинстве браузеров. Довольно круто!

Теперь выберите режим оптимизации Advanced и снова нажмите "Compile". Результат даже меньше, чем с Simple, фактически удаляя лишние пути (вот небольшой пример) - но он также съедает имена символов, такие как объект Foo, который теперь является однобуквенным. переменная, потому что мы не сказали Closure, что нас это волнует.

Поздравляем - вы столкнулись с одной из основных одновременных проблем, связанных с преимуществами и проблемами при использовании компилятора.

Задача набора текста

Замыкание имеет простой и расширенный. В нем также есть Только пробелы (хотя это не интересно и не заслуживает упоминания).

Практически весь код при передаче через Simple будет выводить преобразованный миниатюрный код. Замыкание будет жаловаться, если у вас есть синтаксические ошибки, или если у вас есть ошибки типа, о которых он знает. Он также будет потреблять и генерировать исходные карты, чтобы упростить отладку в браузере (исходные карты помогают вашему браузеру сопоставить скомпилированную версию с исходным исходным кодом).

Простой режим даст вам поведение, подобное или лучше, чем у большинства других компиляторов JavaScript, существующих сегодня. Вы должны это использовать! 👍

Но, как вы видели ранее, он не будет статически анализировать ваш код, обрезать ветки (например, условные выражения, неиспользуемые вызовы функций) или выполнять другие оптимизации. Только Advanced действительно снизит сложность вашего кода.

В чем подвох?

Чтобы использовать Advanced или получить максимальную отдачу от Simple, ваш код должен быть (частично) аннотирован. Эти аннотации являются разновидностью JSDoc и делятся на три категории:

  • Введите аннотации к вашему коду, например:
function returnTwiceThisNumber(/** number */ x) { return x + x; }

Этот пример сообщает компилятору, что вы должны ожидать здесь только число. Передача чего-либо еще вызовет ошибку. Вы спросите, почему я не могу это оставить, ведь компилятор не справится с этим за меня?

Обратите внимание, что добавление двух строк вместе также допустимо, даже если это не то, для чего ваша функция должна использоваться - и без подсказок типом, скорее всего, будет unknown, который означает, что компилятор не может его оптимизировать.

  • Внешние файлы, например:
/** @return {string} */
jQuery.deferred.prototype.state = function() {};

Это одна строка от jQuery’s externs. Если вы используете код, который не компилируете как часть пакета, вам необходимо сообщить об этом компилятору. Этот метод не принимает аргументов и возвращает строку. Если вы используете state () для отложенного объекта jQuery, Closure теперь будет знать, что вернет строку.

Стандартные библиотечные методы, например Math.pow -, тоже имеют внешние элементы, но они встроены в компилятор.

  • Экспорт определений, например:
/** @export */
class EntryPointToMyApp { constructor() { ... } }

Эта строка говорит Closure оставить EntryPointToMyApp в покое. Он не будет переименовывать его в вашем выходном коде.

Экспорт, вероятно, является наименее изученной частью Closure: многие приложения не используют их (поскольку приложения «запускаются» сами), и они вам нужны только в том случае, если вы пишете библиотеку, которая, в свою очередь, используется другими (например, через ваши собственные файлы externs в Closure или непосредственно в HTML).

Это звучит сбивающе с толку

Самая большая оговорка в Closure - печатать. Если вы набираете неправильно - или его не существует, если вы думаете о переносе существующего проекта - в расширенном режиме вы можете получить непригодный для использования код.

С другой стороны, он также очень громко сообщит вам о наличии проблем. 💥

Отсутствие типизированной информации помешает компилятору выполнять свою работу - пример string vs number, ранее (решенный с помощью аннотаций типов), - но он также может съесть ваши имена переменных - пример Foo.

Это сложно. Если вы начинаете новый проект, Closure в режиме Advanced отлично подходит и может повысить вашу продуктивность; для старых проектов Simple легко включить, он сократит ваш код и не причинит вам вреда. Для получения дополнительной информации обо всей этой области ознакомьтесь со следующим -

Расскажи подробнее!

Большой! Есть несколько различных способов интегрировать Closure в ваши проекты Не ищите больше образец проекта, который компилируется в расширенном режиме.

Но если вы продолжаете читать, вы должны сначала знать, что есть ряд флагов, которые вы можете настроить при запуске Closure. Вот краткий список предложений:

  • warningLevel: VERBOSE, чтобы вы знали, если вы допустили ошибку. Обычно Closure пытается добиться успеха любой ценой.
  • processCommonJsModules: true для поддержки операторов require
  • rewritePolyfills: true добавит библиотеки, которых нет на вашем целевом языке (обычно и по умолчанию ES5).
  • compilationLevel: ADVANCED (или SIMPLE, но это значение по умолчанию)

Скомпилировать через веб-сервис

Веб-сервис, который мы видели раньше и который доступен здесь, можно использовать вручную, но он также имеет API. Существуют плагины для узлов, которые могут вызывать это как часть процесса сборки. Это быстро, так как Google съедает стоимость компиляции за вас, но это может быть не для всех.

Лично я использую вспомогательный сценарий, оставленный в моем $ PATH, для вызова Closure из командной строки: это полезно для небольших приложений.

Скомпилировать через модуль Node

По состоянию на август 2016 года Google только что выпустил чистую JS-версию компилятора Closure. Также есть версия Java - немного быстрее, но вам может не понравиться зависимость от Java.

В версиях JS и Java есть плагины для Gulp, Webpack и других систем сборки. Вы сможете довольно легко добавить их в свои существующие проекты. В качестве реального примера, Google использует плагин Gulp для компиляции Santa Tracker 🎄 каждый год.

Скомпилировать в командной строке

Если вы загрузили Java-приложение Closure Compiler, вы можете вызвать его из командной строки и напрямую указать файлы. У него еще больше флагов и опций; вы можете использовать это приложение как часть более крупного процесса сборки.

java -jar compiler.jar --js hello.js --js_output_file out.js

Милый анекдот

В Google мы долгое время считали типобезопасный JavaScript само собой разумеющимся. Это упрощает рефакторинг, и у нас действительно может быть меньше простых тестов, потому что компилятор проверяет, например, что этот тип - это то, что мы ожидаем в любой момент.

Когда я пришел в компанию в 2009 году, я спросил во время интервью: «Каким же образом Gmail не дает постоянный сбой из-за ошибок JS?» - и хотя с тех пор сообщество JS внедрило множество других инструментов, Closure была и остается одной из причин, по которой Google может создавать высококачественные веб-приложения.

Надеюсь, это поможет вам сделать то же самое!

💻 🛠️