Bundlejs: онлайн-сборщик на основе Esbuild

Bundlejs: онлайн-сборщик на основе Esbuild

24 мая 2022 г.

Вступление


bundlejs (произносится как bundle js) — это быстрый и простой способ встряхивания дерева, объединения, минимизации и сжатия (либо в [gzip] (https: //en.wikipedia.org/wiki/Gzip) или brotli) ваш машинопись, javascript, jsx и npm проектов, получая при этом общий размер файла пакетов.


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


  • Выполнение всех комплектаций локально

  • Вывод связанного кода дерева встряхивания

  • Получение результирующего размера бандла

Преимущества использования bundlejs:


  1. Легче отлаживать ошибки

  1. Вы можете проверить полученный код в комплекте

  1. Возможность настроить свои бандлы

  1. Возможность встряхивать связки деревьев

  1. Возможность просмотра визуального анализа бандлов

  1. Вы можете связать в автономном режиме (если модуль использовался ранее)

  1. Поддерживает различные типы модулей из различных Сетей доставки контента (CDN), например, CDN, начиная от модулей deno и заканчивая модулями npm, случайными сценариями GitHub и т. д.

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


📒Примечание: после этой статьи будет продолжение, в котором будут подробно описаны технические подробности о том, как работает bundlejs, и как вы можете использовать то, что я узнал из этого проекта, для создайте свой собственный онлайн-сборщик или js-реплику с поддержкой es build-wasm.


😅 TL;DR: этот пост в блоге довольно длинный, поэтому взгляните на bundlejs.com, затем просмотрите этот пост в блоге и обязательно ознакомьтесь с изображениями и примерами кода, которые могут помочь избежать путаницы и сократить необходимое время чтения.


Быстрый запуск функции


https://www.youtube.com/watch?v=5FTricK1peg


В этом видео показаны все основные функции bundlejs (есть звук, но у меня нет хорошего микрофона 😅)


Объединение, встряхивание деревьев и минификация


  • Объединение — это процесс эффективного объединения модулей вместе в один файл, который мы называем пакетом.

\


  • Встряхивание деревьев — это процесс, когда сборщик перебирает модули, которые необходимо объединить, и удаляет неиспользуемый код.

\


  • Минификация — это процесс сокращения объема кода, необходимого для создания функциональной программы, например. удаление пробелов или сокращение имен переменных и т. д.

bundlejs использует [esbuild] (https://esbuild.github.io) и его невероятную способность связывать, преобразовывать, транспилировать, минимизировать, встряхивать дерево и перемещать файлы. В частности, bundlejs использует esbuild-wasm, который может получить доступ к подмножеству этих функций, с основными ограничениями:


  1. Npm работает только на узле, поэтому никакого package.json или npm install (а-ля, шутка об использовании StackBlitz WebContainers для запуска узла в браузере)

  1. Браузеры работают не так, как nodejs. У них нет простого способа доступа к файловой системе, поэтому хранение файлов и доступ к ним нецелесообразны. То, как esbuild обычно работает при установке на узле, просто вызывает проблемы в Интернете.

  1. Из-за ограничений esbuild-wasm при работе в браузере (без npm и nodejs) единственным вариантом является получение модулей из Интернета, но esbuild изначально не поддерживает импорт http(s): //... модулей, поэтому требуется другое решение.

Для решения каждой из этих проблем в помощь приходит система плагинов esbuild. Я создал в общей сложности 4 плагина для устранения этих ограничений, а именно:


  1. Плагин HTTP - извлекает и кэширует модули

  1. Плагин CDN - перенаправляет импорт пакетов npm (иногда называемый голым импортом) на Content Delivery Network (CDN) URL-адреса для получения

  1. Плагин EXTERNALS — помечает определенные импорты/экспорты как модули, которые следует исключить из объединения.

  1. Плагин ALIAS - Псевдонимы некоторых импортов/экспортов в модули с другим именем.

Сети доставки контента (CDN) — отличный способ распространять код по всему миру на высоких скоростях. В контексте bundlejs CDN представляют собой онлайн-репозитории кода, из которого bundlejs могут получать данные.


Например, unpkg.com — это быстрая глобальная сеть доставки контента для всего, что связано с npm. Он используется для быстрой и простой загрузки любого файла из любого пакета в npm с использованием URL-адреса, например: https://unpkg.com/package-name@version/file.js, то же самое применимо и для [skypack.dev]. (https://cdn.skypack.dev), esm.sh и т. д.


В более позднем сообщении в блоге я углублюсь в технические детали работы этих плагинов, но пока просто имейте в виду, что эти плагины помогают esbuild-wasm создавать пакеты javascript.


ℹ️ Информация: это влияние встряхивания дерева и минимизации пакета на размер пакета:


потрясен деревом


Изображение расшатанного дерева


по сравнению с


не-деревотрясение


Изображение пакета без деревьев


Консоль


Изображение виртуальной консоли bundlejs сразу после инициализации esbuild-wasm


В предыдущих версиях bundlejs.com я рекомендовал разработчикам использовать консоль devtools для просмотра журналов консоли, и какое-то время я думал, что это нормально, но я начал понимая, что это неудобно и не очень удобно для мобильных устройств.


Изначально я думал, что создание виртуальной консоли будет сложной задачей, поэтому я довольно долго откладывал добавление пользовательской консоли. Итак, в марте этого года, вдохновленный @hyrious esbuild-repl , наконец-то я это сделал 👏.


Результаты для консолей


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


![Изображение результатов связки в консоли. Он показывает время пакета и размер пакета в сжатом/несжатом виде.


Получение пакетов


Изображение процесса загрузки пакетов в виртуальной консоли


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


Для некоторых пакетов (гм, @babel/core) слишком много подпакетов. Виртуальная консоль обрабатывает множество журналов, которые потребляют слишком много памяти и/или замедляют работу менее мощных устройств; поэтому я ограничиваю количество журналов до 250, и когда этот предел будет превышен, bundlejs покажет это дружественное сообщение:


![Изображение виртуальной консоли усеченного пакета.]


📒 Примечание: вы по-прежнему можете получить доступ к полному журналу консоли из консоли devtools, даже если виртуальная консоль выполняет какое-либо усечение.


Вы можете изменить максимальное количество журналов, разрешенных в конфигурации, через:


```машинопись


"сборка": {


"logLimit": 500


}


Ошибки и предупреждения консоли


Ошибки выглядят так:


Изображение ошибок в виртуальной консоли bundlejs


Предупреждения выглядят так:


Изображение предупреждений в виртуальной консоли bundlejs


Кнопки консоли


Консолям также дали кнопки для облегчения навигации, они вот здесь


Изображение кнопок виртуальной консоли


  • Изображение консоли прокручивается до верхней кнопки

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


  • Изображение кнопки прокрутки консоли вниз

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


  • Изображение кнопки консоли с ошибками и предупреждениями развернуть/свернуть

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


  • Изображение кнопки очистки консоли

Это кнопка очистки консоли, она очищает консоль от содержимого, оставляя консоль такой:


Изображение пустой консоли


Дополнения для консолей


Липкая консоль: Прикрепляет позицию прокрутки консоли к нижней части для новых журналов. Если вы прокручиваете ~ 50px снизу, это поведение больше не применяется; если вы прокрутите вниз, поведение будет применено снова.


Ненавистное выравнивание: Меня так раздражает, когда вещи, которые могут выравниваться, не выравниваются, поэтому я встроил в консоль функцию выравнивания по умолчанию с разделом результатов bundlejs на достаточно большом экране, например ноутбуки, планшеты, настольные компьютеры и т. д.


![Изображение выравнивания между консолью и разделом результатов bundlejs, и оно великолепно]


Интерактивные ссылки консоли: Точно так же, как это звучит, кликабельные ссылки консоли выделяют URL-адреса, начинающиеся с http(s)://..., они функционируют так же, как vscode и devtools, и действуют как простой способ получить доступ к URL-адресам консоли без необходимости копировать и вставлять URL-адрес вручную.


Изображение кликабельной ссылки в консоли


У него есть некоторые ограничения, а именно, иногда ему трудно распознать, какие символы являются ссылками, а какие нет, например,


Я не смог найти пример при создании этого поста в блоге 🤣, когда/если (надеясь, что это если, а не когда) я найду его, я обновлю этот пост.


Зарегистрировать результаты пакета: Результаты пакета, например, время, необходимое для создания пакета, начальный размер пакета, размер сжатого пакета и другие данные, регистрируются в консоли.


Изображение результатов сборки консоли


Вкладки ввода и вывода


![Изображение вкладок ввода и вывода с кнопкой конфигурации сбоку]


С добавлением консоли я хотел, чтобы редакторы не были громоздкими, поэтому я создал панель вкладок для ввода, вывода и редактора конфигурации. Панель вкладок обеспечивает быстрый доступ ко всем редакторам, обеспечивая постоянную доступность «консоли».


Конфигурация


В v0.2 я добавил поддержку пользовательских конфигураций (конфигов), он поддерживает большинство параметров сборки esbuild, а также некоторые добавленные параметры для изменения CDN по умолчанию и алгоритма сжатия.


Конфигурация по умолчанию:


```машинопись


"cdn": "https://unpkg.com",


"сжатие": "gzip",


"сборка": {


"цель": [ "esnext"],


"формат": "esm",


"комплект": правда,


"уменьшить": правда,


"treeShaking": правда,


"платформа": "браузер"


}


Когда вы нажмете кнопку «Поделиться», он также поделится пользовательской конфигурацией, которую вы настроили, например,


```машинопись


"cdn": "https://unpkg.com",


"сжатие": "lz4",


"сборка": {


"цель": [ "es2018" ],


...


}


Конфигурация выше приведет к этому URL-адресу общего ресурса bundlejs.com/?q=@okikio/animate&config={"compression":"lz4","esbuild":{"target":["es2018"]}} .


Обратите внимание, что cdn отсутствует в URL-адресе общего ресурса, потому что bundlejs разумно решает, какую конфигурацию отправить как часть URL-адреса общего ресурса, основываясь на том, насколько новая конфигурация отличается от конфигурации по умолчанию.


📒 Примечание: существует 3 доступных алгоритма сжатия: brotli, gzip и lz4.


Хосты CDN


Сети доставки контента (CDN) — отличный способ распространять код по всему миру на высоких скоростях. В контексте bundlejs CDN представляют собой онлайн-репозитории кода, из которого bundlejs могут получать данные.


Например, unpkg.com — это быстрая глобальная сеть доставки контента для всего, что связано с npm. Он используется для быстрой и простой загрузки любого файла из любого пакета в npm с использованием URL-адреса, например: https://unpkg.com/package-name@version/file.js, то же самое применимо и для [skypack.dev]. (https://cdn.skypack.dev), esm.sh и т. д.


По умолчанию bundlejs позволяет вводить такой код:


```машинопись


экспорт * из "@okikio/animate";


Но за кулисами bundlejs автоматически извлекает этот конкретный пакет из CDN, а именно unpkg.


В старых версиях bundlejs CDN по умолчанию был skypack, но поскольку у skypack нет простого доступа к package.json узла пакеты, я переключился на использование unpkg в качестве CDN по умолчанию.


С более поздними обновлениями bundlejs получили возможность обновлять cdn по умолчанию в глобальном или локальном масштабе.


Технические детали и дополнительная информация...


Вы можете выбрать CDN по:


  1. (Global CDN) Настройка конфигурации CDN на другой хост CDN, например.

```машинопись


"cdn": "https://cdn.esm.sh",


// ИЛИ


"cdn": "скайпак"


  1. (Локальная CDN) Использование хоста CDN в качестве встроенной схемы URL, например.

```машинопись


экспортировать { animate } из "skypack:@okikio/animate";


// ^^^^^^^ https://cdn.skypack.dev/@okikio/animate


  1. Всего поддерживается 8 встроенных схем URL-адресов хостов CDN:









После определения используемой CDN следующим шагом будет определение того, поддерживает ли хост CDN модули в стиле npm, примерами которых являются unpkg, skypack, esm.sh и т.д...


Факторы, влияющие на определение того, что узел CDN поддерживает модули стиля npm, заключаются в том, что узел CDN поддерживает:


  1. CDN поддерживает управление версиями пакетов с помощью URL-тега @version (например, react@18).

  1. CDN может загружать пакеты узлов, файл package.json.

📒 Примечание: без package.json вы не можете загрузить импорт подпути, плюс это становится более сложным для определения правильных экспортируемых модулей для объединения.


⚠️ Предупреждение: если выбранный CDN не поддерживает файл package.json и не является хостом CDN в стиле npm, тогда bundlejs переключится на попытку угадать версии пакета; это может привести к неточным пакетам с неправильными версиями пакетов.


В более позднем сообщении в блоге я углублюсь в технические детали того, как работает плагин esbuild CDN, чтобы определить, какой хост CDN использовать, но пока вы просто помните, что плагины CDN помогают esbuild-wasm при разрешении URL-адресов хостов CDN.


Алгоритмы сжатия


bundlejs предлагает варианты объединения с использованием:


  1. brotli - дает наименьший размер пакета, но самый медленный

  1. gzip - дает 2-й наименьший размер пакета, но он быстрее, чем brotli (по умолчанию)

  1. lz4 - приводит к наибольшему размеру пакета, но это самый быстрый алгоритм пакета.

📒 Примечание: у каждого алгоритма сжатия своя история.


Проблема Бротли


brotli — это алгоритм сжатия, который очень хорошо сжимает данные, однако он очень медленный по сравнению с другими альтернативами. Добавление brotli было непростой задачей с множеством взлетов и падений, но благодаря Льюису Лю в Твиттере я смог использовать deno-brotli, чтобы включить WASM-версию brotli в bundlejs.


Узнайте историю поддержки Brotli...


Нет shade первоначальным создателям brotli-wasm и wasm-brotli (разные пакеты, похожие названия), но то, как оба пакета работают с WASM, вынуждает разработчиков использовать веб-пакеты (чего не было, я ценю свое время). слишком много для этого). После многочисленных попыток и 6 месяцев работы я наконец нашел deno-brotli.


Пример использования WASM в обоих пакетах (brotli-wasm и wasm-brotli) выглядит следующим образом:


```машинопись


импортировать WASM из "./bg.wasm";


Честно говоря, мне несправедливо обвинять создателей brotli-wasm и wasm-brotli, это не их вина. Ошибка заключается в том, что экосистема js еще не нашла интероперабельное решение для работы с WASM. Это одна из основных причин, почему я очень благодарен [Льюису Лю] (https://twitter.com/lewisl9029/status/1498928788477857794?s=20&t=iUL2EzC810kgGM6tn8nJeg) за то, что он указал на deno-brotli.


deno-brotli правильно делает 2 вещи, а именно:


  1. Он сжимает огромный файл WASM, необходимый для deno-brotli, в сжатую строку lz4, которую затем можно распаковать с помощью lz4, что позволяет легко хранить WASM в виде файла js (результатом являются отличные инструменты сборки поддержку, так как WASM — это просто строка внутри JS-файла, к тому же он очень хорошо решает проблему экосистемы).

Для поддержки lz4 bundlejs использует deno-lz4, который также работает через WASM, но способом deno-lz4 сжатие немного отличается от deno-brotli. Я настоятельно рекомендую вам взглянуть на исходный код [deno-lz4] (https://deno.land/x/lz4), он действительно информативен.


  1. Имея WASM в виде js-файла, вы можете предварительно загрузить WASM в виде js-модуля 🤯

![Вселенная, Тим и Эрик, Mind Blown GIF]


Вы можете прочитать эту ветку твита, чтобы узнать больше:


https://twitter.com/okikio_dev/status/1498898909879422977?s=20&t=iUL2EzC810kgGM6tn8nJeg


По умолчанию Gzip


bundlejs уже довольно давно использует gzip по умолчанию. bundlejs раньше использовал pako, но благодаря обсуждению с @matthewcp, который справедливо указал на (De)compression Stream API, я начал искать альтернативы pako.


https://twitter.com/matthewcp/status/1503704061853450242?s=20&t=CDGJmTts_m2A9H7cyZfmew


Узнайте историю поддержки gzip...


Благодаря беседе с @matthewcp, я на самом деле провел дополнительное исследование альтернатив pako> У меня есть 3 возможных альтернативы, они являются denoflate (использующий WASM), deno-compress (использующий js) и CompressionStream (встроено в браузеры), да забавно 🎉😅.


В конце концов я решил заменить pako на denoflate в качестве алгоритма сжатия по умолчанию для gzip; это немного быстрее и меньше, чем [pako] (https://github.com/nodeca/pako).


LZ4, надо ехать быстро


Sanic The Hedgehob GIF


Чтобы использовать WASM переносимым способом, deno-brotli сжал бы двоичный файл WASM в строку base64, используя lz4 в качестве алгоритма сжатия. Я увидел возможность добавить еще один алгоритм сжатия, поэтому использовал реализацию lz4 (deno-lz4) для сжатия двоичной строки WASM brotli (см. # the-brotli-problem для получения дополнительной информации.), это был самый простой алгоритм сжатия для добавления в bundlejs 🤣.


Качество сжатия


Вы можете установить качество сжатия (по шкале от 1 до 11, где 1 — наименее сжатое, а 11 — максимальное сжатие), вы можете установить качество сжатия для любого из упомянутых выше алгоритмов сжатия, установив конфигурацию сжатия возможность:


```тс


"сжатие": {


"тип": "бротли",


"качество": 11


Вы можете посмотреть демо здесь, bundlejs.com/?config={"compression":{"type":"brotli","quality":11}}.


Псевдонимы и внешние имена


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


Внешние - это прямой запрос функции [issue # 13] (https://github.com/okikio/bundle/issues/13), это заняло некоторое время, но хорошее решение наконец-то стало частью bundlejs, вы используете его так, как вы использовал бы параметр конфигурации esbuild externals.


Подробнее...


Вы используете псевдонимы следующим образом:


```машинопись


"псевдоним": {


"@okikio/animate": "@babel/core"


Вы можете попробовать это ниже, bundlejs.com/?config={"alias":{"@okikio/animate":"@babel/core"}}.


Вы используете «внешние» следующим образом:


```машинопись


"сборка": {


"внешний": ["@okikio/animate"]


Вы можете попробовать это ниже, bundlejs.com/?config={"esbuild":{"external":["@okikio/animate"]}}.


Посмотрите сложный пример использования внешнего конфига bundlejs.com/?q=@babel/core&config={"esbuild":{"external":[...]}}


Никто другой не может понять мою боль ... Я добавляю больше возможностей в bundlejs, когда пишу этот пост в блоге, так что он становится все длиннее, длиннее и длиннее и т. д.... 😅


![Моя боль сильнее твоей, Наруто GIF]


Параметры конфигурации Esbuild


Параметры конфигурации esbuild звучат именно так, как они звучат, однако при запуске esbuild в браузере существуют некоторые ограничения на то, что может делать esbuild. Из-за отсутствия собственного доступа к файловой системе некоторые параметры не работают или устарели.


Поддерживаемые параметры сборки esbuild:


Простые варианты


  • [Комплект] (https://esbuild.github.io/api/#bundle)

  • [Определить] (https://esbuild.github.io/api/#define)


  • [Формат] (https://esbuild.github.io/api/#format)

  • [Внедрить] (https://esbuild.github.io/api/#inject)

  • [Загрузчик] (https://esbuild.github.io/api/#loader)

  • [Свернуть] (https://esbuild.github.io/api/#minify)

  • [Платформа] (https://esbuild.github.io/api/#platform)

  • [Исходная карта] (https://esbuild.github.io/api/#sourcemap)



Расширенные опции


  • [Анализ] (https://esbuild.github.io/api/#analyze)

  • [Имена активов] (https://esbuild.github.io/api/#asset-names)


  • [Кодировка] (https://esbuild.github.io/api/#charset)

  • [Имена блоков] (https://esbuild.github.io/api/#chunk-names)

  • [Цвет] (https://esbuild.github.io/api/#color)

  • [Дроп] (https://esbuild.github.io/api/#drop)

  • [Имена записей] (https://esbuild.github.io/api/#entry-names)

  • [Нижний колонтитул] (https://esbuild.github.io/api/#footer)

  • [Глобальное имя] (https://esbuild.github.io/api/#global-name)

  • [Игнорировать аннотации] (https://esbuild.github.io/api/#ignore-annotations)

  • [Инкрементальный] (https://esbuild.github.io/api/#incremental)

  • [JSX] (https://esbuild.github.io/api/#jsx)

  • [Фабрика JSX] (https://esbuild.github.io/api/#jsx-фабрика)

  • [фрагмент JSX] (https://esbuild.github.io/api/#jsx-fragment)

  • [Сохранить имена] (https://esbuild.github.io/api/#keep-names)

  • [Юридические комментарии] (https://esbuild.github.io/api/#legal-comments)

  • [Уровень журнала] (https://esbuild.github.io/api/#log-level)

  • [Ограничение журнала] (https://esbuild.github.io/api/#log-limit)

  • [Реквизит Mangle] (https://esbuild.github.io/api/#mangle-props)

  • [Метафайл] (https://esbuild.github.io/api/#metafile)

  • [Внешнее расширение] (https://esbuild.github.io/api/#out-extension)

  • [Внешняя база] (https://esbuild.github.io/api/#outbase)

  • [Общий путь] (https://esbuild.github.io/api/#public-path)

  • [Чистый] (https://esbuild.github.io/api/#pure)

  • [Разрешить расширения] (https://esbuild.github.io/api/#resolve-extensions)

  • [Исходный корень] (https://esbuild.github.io/api/#source-root)

  • [Исходный файл] (https://esbuild.github.io/api/#sourcefile)

  • [Контент источников] (https://esbuild.github.io/api/#sources-content)

  • [Стандартный] (https://esbuild.github.io/api/#stdin)

  • [Встряхивание дерева] (https://esbuild.github.io/api/#tree-shaking)

  • [Tsconfig необработанный] (https://esbuild.github.io/api/#tsconfig-raw)

Довольно много работы, я бы сказал.


Кнопки редактора + дополнительные функции...


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


Кнопки редактора добавляют дополнительные функциональные возможности редактору; они обеспечивают легкий доступ к общим задачам редактора.


Текущий список кнопок редактора:


Переключение панели редактора


Изображение переключателя панели редактора


Включает или выключает кнопки редактора, оставляя больше места для редактора кода. Вот так это выглядит, когда кнопки редактора скрыты:


Изображение скрытой панели редактора


Кнопка очистки редактора


Изображение кнопки очистки редактора


Очищает редактор от всего его содержимого.


Кнопка форматирования кода


Изображение кнопки редактора формата


Очищает любой грязный код, который он находит. Он использует dprint для форматирования кода редактора ввода и вывода, но возвращается к monaco-editors, запеченному в форматер для редактора конфигурации.


Кнопка сброса кода


Изображение кнопки сброса редактора


Сбрасывает редактор в исходное состояние.


  • Для редактора ввода он сбрасывается на это:

```машинопись


// Нажмите «Сборка», чтобы узнать размер объединенного, минимизированного и сжатого пакета.


экспорт * из "@okikio/animate";


  • Для редактора вывода он сбрасывается на это:

```машинопись


// Выход


  • Для редактора конфигурации он сбрасывается на это:

```машинопись


"cdn": "https://unpkg.com",


"сжатие": "gzip",


"анализ": ложь,


"сборка": {


"цель": [


"следующий"


"формат": "esm",


"связка": правда,


"уменьшить": правда,


"treeShaking": правда,


"платформа": "браузер"


Кнопка копирования кода


Изображение кнопки копирования кода


Копирует код редактора, всё именно так, как звучит (а вы чего ожидали? 🤣). Когда вы копируете код из редактора с помощью кнопки копирования, появляется это восхитительное маленькое сообщение:


image.png


Кнопка переноса кода


Изображение кнопки переключения вокруг редактора


Переключение между «обернутым» и «развернутым» кодом. Обтекание заключается в том, чтобы код редактора обтекал ограничения ограничивающей рамки редактора, устраняя необходимость горизонтальной прокрутки для просмотра всего кода.


Вот как выглядит «обернутый» код:


Изображение упакованного кода


Вот так выглядит «развернутый» код:


Изображение развернутого кода


Бонусные функции


Бонус: вы можете получить доступ к встроенной палитре команд monaco, нажав F1, например.


Изображение палитры команд редактора кода


Дополнительный бонус: вы можете использовать многие сочетания клавиш, которые есть в vscode, просто щелкнув правой кнопкой мыши, находясь в monaco-editor, например.


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


Ручки перетаскивания... Интерактивное развлечение


https://www.youtube.com/watch?v=AMt01tFstik&feature=youtu.be


Новые маркеры перетаскивания обеспечивают более интерактивный опыт работы с редактором; они немного похожи на ручки перетаскивания в vscode, но удобны для мобильных устройств.


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


Поддержка JSX


JSX теперь официально поддерживается в bundlejs 🎉.


Изображение демонстрационной версии JSX preact на bundlejs


Не обращайте внимания на красные строки ошибок, по какой-то причине редактор кода monaco не хочет нормально работать с JSX 😅


Чтобы использовать JSX, вам необходимо установить параметры конфигурации jsxFactory и jsxFragment в соответствии с используемой вами инфраструктурой на основе JSX.


например для Preact будет использоваться следующая конфигурация:


```машинопись


"сборка": {


"jsxFactory": "ч",


"jsxFragment": "Фрагмент"


Попробуйте preact demo


Общий доступ к пакетным сеансам


Чтобы совместно использовать сеансы пакетов* между несколькими пользователями (при этом не требуется сервер), нам нужен статический и локальный способ хранения и обмена кодом между пользователями. Чтобы решить эту проблему, я решил закодировать информацию о сеансе пакета* прямо в URL-адрес, потому что я хотел, чтобы весь проект работал в автономном режиме, и я не хотел высоких затрат на обслуживание сервера и базы данных.


*sessions — это конкретное состояние bundlejs в определенное время, это не вся история сеанса пакета, а только входной код и конфигурация пакета на момент нажатия кнопки «Поделиться».


Технические подробности...


Краткий обзор того, как это работает, заключается в том, что пользователи вносят изменения в редакторе входного кода, затем это изменение сохраняется и кодируется в URL-адресе. Затем URL-адрес можно использовать для создания повторов сеанса пакета.


URL-адрес [пример сеанса] (https://tinyurl.com/3fptk973):


```машинопись


/?q=(import)@okikio/emitter,(import)@okikio/animate,(import)@okikio/animate,(import)@okikio/animate,(import)@okikio/animate,@okikio/animate,@ okikio/animate,@okikio/animate,@okikio/animate&treeshake=[T],[{ анимировать }],[{ анимировать как B }],[ как TR],[{ type анимировать }],[],[{ анимировать как A }],[ как PR],[{ animate }]&text="экспортировать как PR18 из \"@okikio/animate\";
экспортировать { animate как animate2 } из \"@okikio/animate\"; "&share=MYewdgziA2CmB00QHMAUAiAwiG6CUQA&config={"cdn":"skypack","сжатие":"brotli","esbuild":{"format":"cjs","minify":false,"treeShaking":false}}&bundle


Результирующий входной код этого URL-адреса сеанса пакета выглядит следующим образом:


```машинопись


// Нажмите «Создать», чтобы выбрать размер пакета «Связанный, минимизированный и сжатый».


импортировать T из "@okikio/emitter";


импортировать {animate} из "@okikio/animate";


импортировать { анимировать как B } из "@okikio/animate";


импортировать как TR из "@okikio/animate";


импортировать { type animate } из "@okikio/animate";


экспорт из "@okikio/animate";


экспортировать { анимировать как A } из "@okikio/animate";


экспортировать как PR из "@okikio/animate";


экспортировать { animate } из "@okikio/animate";


console.log("Круто")


экспортировать как PR18 из "@okikio/animate";


экспортировать {анимацию как анимацию2} из "@okikio/animate";


с конфигом:


```машинопись


"cdn": "скайпак",


"сжатие": "бротли",


"сборка": {


"цель": ["esnext"],


"формат": "cjs",


"связка": правда,


"уменьшить": ложь,


"treeShaking": ложь,


"платформа": "браузер"


Разбивка URL:


```машинопись


q=(import)@okikio/emitter,(import)@okikio/animate,(import)@okikio/animate,(import)@okikio/animate,(import)@okikio/animate,@okikio/animate,@okikio/ анимация,@okikio/animate,@okikio/animate&


treeshake=[T],[{ анимировать }],[{ анимировать как B }],[ как TR],[{ type анимировать }],[],[{ анимировать как A }],[* как PR] ,[{ анимация }]&


text="экспортировать * как PR18 из \"@okikio/animate\";
экспортировать { animate as animate2 } из \"@okikio/animate\";"&


доля = MYewdgziA2CmB00QHMAUAiAwiG6CUQA&


config={"cdn":"skypack","сжатие":"brotli","esbuild":{"format":"cjs","minify":false,"treeShaking":false}}&


пучок


  • q или query представляет модуль, например. «реагировать», «вью» и т. д.

Вы можете добавить (import) перед определенным модулем, чтобы сделать его импортом, а не экспортом.


  • Treeshake представляет экспорт/импорт в treeshake.

Синтаксис встряхивания дерева позволяет указать несколько экспортов для каждого пакета с помощью следующего синтаксиса:


```машинопись


"[{x,y,z}],[],[ как X],[{тип xyz}]"


// к


экспорт {x, y, z} из "...";


экспорт * из "...";


экспортировать * как X из "...";


экспорт {тип xyz} из "...";


Квадратные скобки представляют собой отдельные пакеты, а все, что находится внутри квадратных скобок, является экспортируемыми методами, типами и т. д.


  • text представляет входной код в виде строки (используется для короткого входного кода)

  • share представляет сжатую строковую версию входного кода (используется для большого входного кода)

  • config представляет конфигурацию пакета, используемую при сборке пакета

  • bundle сообщает bundlejs, что необходимо связать входной код при запуске. Это не включено по умолчанию из соображений безопасности. Я хочу отговорить людей от отправки больших сложных пакетов, которые вызывают сбои в работе браузеров или требуют много времени для загрузки, особенно до того, как входной код будет должным образом подтвержден как невредоносный. Итак, если вы хотите связать код при запуске, вам нужно вручную добавить &bundle в конец URL-адреса.

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


Анализ пакетов


bundlejs может анализировать и визуально представлять пакеты в виде удобных для навигации и понятных диаграмм.


Использование порта esbuild-visualizer и rollup-plugin-visualizer от @bardadymchik, я добавил возможность визуализировать пакеты, эта функция исходит из запроса функции от @atomiks на issue #22, проблема все еще не решена, вы можете внести предложения по улучшению этой функции.


Диаграммы анализа пакетов отображаются прямо под редактором, например:


Изображение панели анализа пакетов в редакторе кода пакетов


Отображаемые диаграммы представлены в трех различных вариантах:


Диаграмма дерева


Диаграммы древовидной карты — это наиболее запоминающаяся форма диаграммы анализа пакетов; Источником вдохновения для этой диаграммы послужил webpack-bundle-analyzer. webpack-bundle-analyzer является прародителем анализаторов пакетов, и большое вдохновение для подхода bundlejs к созданию диаграмм.


Древовидные диаграммы:


  1. Помочь вам понять, что на самом деле находится внутри вашего пакета

  1. Узнайте, какие модули составляют большую часть его размера

  1. Найдите модули, которые попали туда по ошибке

  1. Оптимизируйте его!

\


Источник: github.com/webpack-contrib/webpack-bundle-analyzer


!)


Источник: github.com/webpack-contrib/webpack-bundle-analyzer


Хотя диаграмма дерева bundlejs менее эффективна, чем диаграмма дерева webpack-bundle-analyzer, она проще и быстрее в использовании (bundlejs использует esbuild, а анализ пакетов легко доступен в Интернете).


Сетевая диаграмма


Изображение сетевой диаграммы анализа бандлов


Сетевые диаграммы не сильно отличаются от treemap chart, однако они предлагают уникальный взгляд на влияние относительных размеров модулей в пакете.


График солнечных лучей


Изображение диаграммы солнечных лучей анализа пакетов bundlejs


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


В диаграммах солнечных лучей используются [круговые диаграммы] (https://en.wikipedia.org/wiki/Pie_chart) для представления размеров пакетов, это помогает понять, какую часть от общего размера пакетов занимают определенные модули.


Технические подробности...


📒 Примечание: Все аналитические диаграммы поддерживают размеры пакетов, сжатые gzip и brotli! При анализе пакета он выберет либо gzip, либо brotli в зависимости от типа сжатия.


напр. Конфиг:


```машинопись


"сжатие": "gzip"


будет использовать сжатие gzip для графиков, в результате чего:


Изображение сгенерированной древовидной диаграммы со сжатием gzip на bundlejs


Аналитика


Когда я изначально создавал проект, я использовал только простой счетчик просмотров страниц. Я хотел посмотреть, насколько проект популярен, не нарушая конфиденциальность пользователей, он работал, но я чувствовал, что он мог бы быть лучше. Итак, я решил также использовать umami в качестве альтернативы Google Analytics с открытым исходным кодом, сохраняющей конфиденциальность, без файлов cookie, аналитика которой общедоступна для всех.


Дополнительная информация...


Для bundlejs используется собственная версия [umami] (https://umami.is), которая обеспечивает конфиденциальность и безопасность пользовательских данных. При попытке настроить самостоятельную версию умами я обнаружил, что статья [Настройка Umami с помощью Vercel и Supabase] (https://dev.to/jakobbouchard/setting-up-umami-with-vercel-and-supabase -3a73) [Jakob Bouchard] (https://dev.to/jakobbouchard) очень помог.


Аналитика общедоступна, ознакомьтесь с ней по адресу analytics.bundlejs.com/share/bPZELB4V/bundle


Или нажмите счетчик посещений страницы:


Изображение счетчика посещения страницы


📒Примечание: bundlejs по-прежнему использует счетчик просмотров страниц, счетчик просмотров поддерживается countapi (насколько мне известно, countapi теперь устарело, однако серверы для проекта все еще работают, поэтому я буду продолжать использовать проект, пока не перейду на использование умами для просмотров страниц, а также для общей аналитики).


https://dev.to/jakobbouchard/setting-up-umami-with-vercel-and-supabase-3a73


Обсуждения и поддержка


Чтобы поощрять обсуждение, оказывать поддержку и получать отзывы, я добавил раздел комментариев в bundlejs, для этого я использовал giscus.


Первоначально, когда я создавал проект bundlejs, я также создал для него [Обсуждение GitHub] (https://github.com/okikio/bundle/discussions). Я не хотел нести накладные расходы на управление сервером Discord, поэтому я выбираю GitHub Discussions для чатов о bundlejs.


Проблема в том, что никто на самом деле не использует [Обсуждения GitHub] (https://github.com/okikio/bundle/discussions), поэтому я интегрировал его прямо в сам веб-сайт через [giscus] (https://github.com/ гиск/гиск). Это было сделано для того, чтобы новые пользователи могли легко взаимодействовать с другими, получать от меня поддержку и оставлять отзывы.


Технические подробности...


giscus — это система комментариев с открытым исходным кодом, основанная на обсуждениях GitHub; он позволяет посетителям оставлять комментарии и отзывы на вашем сайте через GitHub! Он был сильно вдохновлен [высказываниями] (https://github.com/utterance/utterances).


Для bundlejs я использую собственную версию [giscus] (https://github.com/giscus/giscus), это в основном из соображений безопасности. При попытке настроить giscus для bundlejs, документы на собственном хостинге в репозитории GitHub очень полезны. Я настоятельно рекомендую всем, кто думает об использовании giscus, прочитать ее, она дает представление о том, как giscus работает на бэкэнд.


Вы можете ознакомиться со встроенными комментариями giscus по ссылке bundlejs.com/#discus.


![Изображение раздела обсуждения на bundlejs, сейчас он довольно бесплоден]


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


Безопасность и производительность


Безопасность и производительность являются критически важными областями качества для bundlejs. Чтобы объединить модули вместе, bundlejs должен получить несколько наборов модулей со всего Интернета, при этом гарантируя, что злоумышленники не будут вовлечены, и что esbuild-wasm не используется для сбоя других устройств.


Некоторые действительно...действительно большие модули могут занимать до 4+ ГБ памяти, чтобы быть правильно собранными с помощью esbuild-wasm.


Критерии безопасности, которые я установил для bundlejs, были следующими:


  1. Не разглашайте личную информацию пользователя.

  1. Не проходить через центральный сервер, например, возможность получать модули узлов из разных источников.

  1. Убедитесь, что люди всегда знают, какие пакеты они объединяют.

  1. Убедитесь, что люди не могут использовать bundlejs для злонамеренного замедления работы браузеров.

Чтобы убедиться, что я выполнил установленные критерии безопасности:


  1. Я использую строгие политики безопасности контента (CSP) для bundlejs, гарантируя, что никакая непреднамеренная третья сторона не может быть вовлечена.

  1. Я сам размещаю столько сторонних скриптов, сколько могу. Указав количество рук, вовлеченных в [bundlejs.com] (https://bundlejs.com), я уменьшаю вероятность утечки личной информации.

  1. Я использую методы песочницы, например, «Веб-работники» и «Общие рабочие роли», чтобы обеспечить плавную работу основного потока со скоростью «60 кадров в секунду», избегая при этом доступа к DOM.

Web Workers и Shared Workers — это сценарии, которые выполняются в отдельном потоке. Используя Workers, я могу изолировать потенциально вредоносный код, гарантируя, что основной поток не будет затронут.


Большинство применений Workers были «Shared Workers». Shared Workers уменьшают влияние на производительность нескольких экземпляров сайта/веб-приложения bundlejs, работающих на одном устройстве.


  1. Чтобы уменьшить вероятность использования bundlejs для злонамеренного замедления работы браузеров, я гарантирую, что общий URL-адрес легко читается и понимается, и по умолчанию отключаю автоматическое связывание для общих URL-адресов.

Текущий ландшафт браузера для поддержки Shared Worker в лучшем случае неоднороден.


Таблица поддержки выглядит так:


| Браузер | Общие рабочие | Рабочие модули |


| Фаерфокс | Да | Нет |


| Хром | Да | Да |


| Сафари | Да* | Да |


| * Поддержка Safari в настоящее время является экспериментальной, но должна появиться в более поздних версиях | | |


Module Workers — это esmodules, которые запускаются в Workers.


📒 Примечание: я создал полифил Shared Worker @okikio/sharedworker. Это небольшой, но простой полифилл, который возвращается к обычному «Web Worker», если «Shared Workers» не поддерживаются.


Вы можете использовать его во время ожидания следующей версии Safari для поддержки «Shared Workers» или при поддержке более старых версий Safari.


⚠️ Предупреждение: Shared Worker polyfill не работает с модулями worker, вам все равно нужно каким-то образом скомпилировать ваши модули в не-ESM версии для поддержки рабочие в Firefox.


Вы можете посмотреть, как bundlejs обрабатывает рабочие модули, в исходном коде bundlejs, вы можете также хотите просмотреть исходный код astro-repl, чтобы увидеть, как он обрабатывает рабочие модули.


Большинство других политик безопасности носят пассивный характер, например,


  • bundlejs объединяется только при загрузке страницы, если в URL есть ?bundle.

  • bundlejs принудительно использует https:// для всех запросов, в том числе для iframe и т. д....

  • По умолчанию только должным образом проверенные хосты CDN для bundlejs.

  • и т.д...

Советы и приемы


Совет высшего уровня, подписывайтесь на меня (@@okikio_dev) и bundlejs (@jsbundle ) в Твиттере; бесстыдный плагин 🤣.


Я публикую объявления и обновления в этих учетных записях, а также небольшие советы и рекомендации, которые помогают максимально эффективно использовать bundlejs.


  • При объединении пакетов, которые также экспортируют CSS и другие внешние файлы, bundlejs.com теперь проверяет размер gzip/brotli этих внешних файлов, однако не выводит внешние файлы. код. Это поведение может измениться в будущем, но пока я придерживаюсь именно этого подхода. Имейте в виду, что это не ошибка, однако, если это вызывает путаницу, я готов изменить это поведение.

  • Встряхивание дерева доступно, но не все CDN поддерживают доступ к каждому пакету package.json, поэтому могут быть небольшие конфликты версий пакетов. Единственный проверенный CDN с доступом к package.json — https://unpkg.com. Другие используемые CDN либо предварительно объединяют код для нас (это зависит от пакета), либо они не являются полными CDN npm, например. https://deno.land или https://raw.githubusercontent.com.

  • Проверьте полную консоль devtools на наличие сообщений об ошибках и предупреждений, если у вас возникли проблемы с отладкой проблемы в bundlejs, или, что еще лучше, включите подробное ведение журнала esbuilds при попытке отладки проблем, например.

```машинопись


"сборка": {


"logLevel": "подробный"


Ознакомьтесь с демо.


  • Вы можете использовать настраиваемые протоколы, чтобы указать, какой конкретный модуль импорта/экспорта CDN следует использовать. Если возникает ошибка, из-за которой вы не можете правильно связать пакет, я настоятельно рекомендую переключить CDN либо с помощью пользовательских протоколов, либо путем изменения параметра конфигурации cdn. Я рекомендую использовать настраиваемые протоколы вместо параметра конфигурации cdn при попытке отладки проблем с CDN:

  • напр.

```машинопись


"cdn": "unpkg"


  • или

```машинопись


экспорт * из "unpkg:typescript";


Попробуйте использовать пользовательские протоколы для решения этой пример проблемы на bundlejs .


  • Для некоторых пакетов возникает программная ошибка, когда экспорт по умолчанию исключается из пакета встряхивания дерева. Решение для этого состоит в том, чтобы вручную включить экспорт по умолчанию, например так».

```машинопись


экспорт * из "skypack:solid-dismiss";


// и


экспорт {по умолчанию} из "skypack:solid-dismiss";


Если у вас есть совет и хитрость, которыми вы хотели бы поделиться, оставьте комментарий ниже или отправьте мне [твит] (https://twitter.com/okikio_dev)!


Делать вклад


Кодовая база в настоящее время довольно дезорганизована, поэтому я бы посоветовал написать мне прямое сообщение в [Twitter] (https://twitter.com/okikio_dev) или начать [обсуждение GitHub] (https://github.com/okikio/bundle/ обсуждения) для обсуждения способов внести свой вклад.


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


Вы можете использовать готовую среду разработки Gitpod, чтобы быстро приступить к работе над проектом или внести быстрые изменения в проект.



Открыть в Gitpod


Если вам нравится проект, я буду рад, если вы расскажете об этом. Моя цель — сделать bundlejs жизнеспособной альтернативой/заменой [bundlephobia] (https://bundlephobia.com/) и даже местные упаковщики. Но сейчас проект настолько мал, что большинство людей, которым он был бы полезен, не знают о нем. Я бы хотел, чтобы люди использовали его.


И последнее замечание: bundlejs теперь есть в OpenCollective, поэтому, если вы хотите внести в него финансовый вклад, мы будем признательны.


Вывод


bundlejs, быстрый и простой способ встряхивания дерева, объединения, минимизации и сжатия (либо в gzip или brotli) ваш машинопись, javascript, [jsx] (https://reactjs.org/docs/introduction-jsx.html) и [npm] (https://www.npmjs.com). /) проектов, получая при этом общий размер файла пакетов.


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


  • Выполнение всех комплектаций локально

  • Вывод связанного кода дерева встряхивания

  • Получение результирующего размера бандла

Преимущества использования bundlejs:


  1. Легче отлаживать ошибки

  1. Вы можете проверить полученный код в комплекте

  1. Возможность настроить свои бандлы

  1. Возможность встряхивать связки деревьев

  1. Возможность просмотра визуального анализа бандлов

  1. Вы можете связать в автономном режиме (если модуль использовался ранее)

  1. Поддерживает различные типы модулей из различных Сетей доставки контента (CDN), например, CDN, начиная от модулей deno и заканчивая модулями npm, случайными сценариями GitHub и т. д.

В следующий раз, когда вам понадобится собрать проект или узнать размер пакета проекта, попробуйте bundlejs.com.


📒Примечание: после этой статьи будет продолжение, в котором будут подробно описаны технические подробности о том, как работает bundlejs и как вы можете использовать то, что я узнал из этого проекта, для создания своего собственный онлайн-сборщик или js-репл. с поддержкой esbuild-wasm.


Фото Okiki Ojo, изображение можно найти в Dropbox.


Первоначально опубликовано на blog.okikio.dev


Также опубликовано на Hackernoon и dev.to



Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE