Rome, новый набор инструментов JavaScript

Rome, новый набор инструментов JavaScript

От автора: Себастьян МакКензи, первоначальный создатель Yarn и Babel и член команды Facebook React Native, работает над решением «все в одном» для разработки JavaScript и TypeScript. Проект Rome, отсылка ко «все дороги ведут в Рим», был представлен общественности 26 фев 2020.

Что такое Rome?

Rome — это реализация полного набора инструментов JavaScript с нуля. Он компилирует и связывает проекты JavaScript, линты и проверки типов, запускает тесты, а также может форматировать код.

На что это похоже?

Хотя Rome все еще находится на ранней стадии, CLI предоставляет некоторую полезную информацию о его использовании:

rome bundle — создать отдельный набор JS для пакета

rome compile — скомпилировать один файл

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Узнать подробнее

rome develop — запустить веб-сервер

rome parse — парсировать один файл и вывести его

rome resolve — разрешить файл

rome analyzeDependencies — проанализировать и вывести зависимости файла

Для получения полной информации см. Использование CLI.

Почему это может быть хорошей идеей?

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

Это помогает решить одну из проблем, с которыми сталкиваются популярные упаковщики, такие как Webpack и Rollup, а именно то, что анализ и оптимизация всей программы оказываются очень сложными или затратными, поскольку каждый инструмент должен анализировать и создавать свой собственный AST.

Пакетирование

Архитектура Rome относительно уникальна: вся компиляция происходит отдельно для каждого модуля, что позволяет обрабатывать каждый модуль в пуле потоков workers. Это хорошо подходит для преобразований для каждого модуля, но представляет собой сложную задачу для объединения: во избежание необходимости повторного анализа каждого модуля, созданного workers, модули должны быть предварительно разделены именами, чтобы все они могли совместно использовать одну область.

Чтобы сделать возможным связывание, несмотря на то, что компиляция выполняется для каждого файла, Rome добавляет префиксы для всех переменных области модуля с идентификатором, сгенерированным на основе имени файла модуля. Например, переменная foo в файле с именем test.js становится test_js_foo.

Это также применяется к импортируемым и экспортируемым идентификаторам каждого модуля, что означает, что любой экспорт модуля может быть выполнен с использованием только имени файла модуля и имени экспорта:

Качество вывода

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

Я провел первоначальное исследование того, как выглядит выход Rome. Похоже, что он производит «свернутые по объему» пакеты с одним замыканием, довольно похожие на те, что генерируются в Rollup:

В настоящее время не предусмотрено способа минимизации выходных данных в пакете, чего можно было ожидать с учетом ранней стадии проекта. Однако выполнение вышеуказанного результата с использованием Terser дает очень неплохой вывод:

Как вы можете видеть, здесь есть небольшое количество оптимизационных вещей, даже в таком очень простом пакете. В идеале сборщик может быть осведомлен о предполагаемом режиме, и если известно, что он компилируется для цели ES-модулей, он может опустить директиву закрытия и строгого режима. Он также может поднять объявление «global» в область видимости модуля, что в приведенном выше случае позволит Terser полностью устранить код.

В более крупных проектах

Давайте посмотрим на немного более сложную демонстрацию, включающую два модуля с общей зависимостью:

entry.tsx:

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Узнать подробнее

other.tsx:

react.tsx:

Объединение этого с помощью rome bundle entry.tsx out создает каталог с файлом index.js (и исходной картой):

Это немного сложнее, но мы видим ту же структуру, что и в примере с одним модулем. После удаления из вывода Rome реализации модулей и мертвый код взаимодействия CommonJS, наши три исходных модуля будут встроены в одно закрывающее завершение:

Минимизация в производстве

Как я уже упоминал, в настоящее время в Rome не предусмотрена минимизация в производстве, хотя его дизайн хорошо подходит для минимизации на уровне сборки. Мы можем пропустить приведенный выше вывод через Terser, чтобы посмотреть, как он выглядит.

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

Дальнейшая оптимизация

Последние полгода я работаю над проектом, целью которого является применение автоматической оптимизации к пакетному JavaScript (он еще не выпущен, извините!). В качестве теста я попытался пропустить вывод Rome через этот компилятор перед тем, как передать его Terser с теми же настройками, что и выше. Я рад сказать, что это привело к чему-то близкому к идеальному выводу: нет оборачивающих функций, нет мертвого кода, и он использует преимущества размера современного синтаксиса:

Это многообещающе!

Разделение кода

Rome пока не поддерживает динамический импорт или разделение кода. Использование в коде операторов import() действительно обнаруживает импортированный модуль, но он встроен в пакет, как если бы это был статический импорт. Исходный оператор import() остается неизменным в сгенерированном выводе, что вызывает ошибку.

Еще неизвестно, как разделение кода и разбиение на фрагменты повлияют на качество вывода, поскольку оба зависят от доступа к переменным, заключенным в один пакет из другого. Я еще недостаточно знаком с Rome, чтобы даже предполагать, как это может выглядеть.

Использование CLI

Если вы просто хотите взглянуть на то, что предлагает CLI Rome, вот вывод —help, который вы получите, не создавая его самостоятельно (хотя его очень быстро собрать!):

Автор: Jason Miller

Источник: https://jasonformat.com

Редакция: Команда webformyself.

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Узнать подробнее

Full-Stack практика. Создание JavaScript блога

Создание веб-приложения с нуля на JavaScript, NodeJS, ExpressJS

Смотреть

Метки:

Похожие статьи:

Комментарии Вконтакте:

Комментарии Facebook: