Представляємо Packem: надшвидкий експериментальний пакет, написаний у Rust

Packem - це експериментальний попередньо скомпільований пакет модулів JavaScript, реалізований переважно в Rust. Він також може обробляти різні інші типи файлів, такі як YAML / TOML, файли шейдерних фрагментів та багато іншого. Перевірте веб-сайт або сторінку GitHub, щоб швидко розпочати.

Packem розв'язує залежності модуля і регідратує їх в графік модуля, плоский список, що містить інтерфейси модулів, які по суті є посиланнями на змінні структури даних на основі купи, що містяться в пам'яті, що містять спеціальні метадані модуля в графіку модуля.

Більша частина бізнес-логіки абстрагована від Rust за допомогою прив'язок FFI, щоб забезпечити низький рівень взаємодії між обома кінцями. Бінарні файли Rusty доступні як попередньо скомпільовані аддони Node C / C ++ у репозиторії Packem. Хмарний інтерфейс використовується для запуску декількох сценаріїв з попередньою установкою gyp, створюючи специфічні для ОС бінарні файли з підтримкою пізніших версій Node (8, 9, 10).

Цей рівень ядра Packem називається логічним контекстом (LC) . Усі інші операції, які не мають явного пріоритету , регресуються до загального середовища виконання Node, що, з точки зору Packem, є контекстом виконання (RC) . Детальніше про контексти читайте тут.

Теоретично, модульний графік залишається рівним, щоб уникнути загальних підводних каменів, які призвели б до непотрібних обходів, якщо дерево було використано на місці. Це дозволяє RC відстежувати такі випадки, як глибокі циклічні залежності або сильно вкладені динамічні імпорти (розбиття коду), серед іншого, належним чином з мінімальними наслідками для продуктивності або побічними ефектами.

Більш детально можна ознайомитися на README.md Packem.

Я мав на увазі цю ідею, але ніколи не планував її реалізувати, поки не об’єднав зусиль із Саддамом М. Мені справді було в інтересі бачити об’єднання модулів як концепцію, безпечну для всіх, хто може навчитися, зрозуміти та реалізувати. Люди боролися з конфігураціями, документацією та плагінами, було надзвичайно жахливо, і я хотів би скористатися шансом змінити це. З тобою. За допомогою Packem.

Швидка історія

Я витратив трохи часу, щоб вичерпати більшість пакетів, написаних у середовищі, що не є JavaScript. Я виявив, що більшість із них забули, що вони повинні бути пакетом, а не бібліотекою C / C ++ з темних 19-х років.

Те, що я хотів, - це пакет, який робить більшу частину важкої атлетики мовою, близькою до металу, для користувача, не вимагаючи ніякої взаємодії з його внутрішніми елементами. Тоді я знайшов Руста. Розумна і стисла мова систем, яка демонструє деякі похвальні функції, такі як безстрашна модель одночасності, безпека типу тощо! Я б очікував стільки ж від використання C / C ++, але я волію дотримуватися Rust, оскільки це досить просто, коли справа доходить до управління пам'яттю.

Чому інший пакет?

То що тут взяти? Навіщо нам потрібен інший інструмент побудови, оскільки ми вже маємо такі чудові, як webpack, Parcel, Rollup тощо? Я візьму вас разом із кількома причинами. Можливо, у вас можуть бути власні інтереси щодо того, щоб ваші терміни розробки та виробництва значно скоротились.

Настав 2019 рік, нам більше не потрібні повільні інструменти

Незважаючи на те, що Packem швидший за веб-пакет 4, він більш ніж удвічі швидший за Parcel (із багатоядерною компіляцією) . У тестовому тесті ми поєднали Lodash v4.17.1 з Packem та Parcel, і це отримало результат:

Ніколи не беріть лавок за номіналом. Ви можете випробувати це на собі тут.

Причина, по якій я не турбувався порівняльним аналізом Parcel проти webpack, полягала в тому, що webpack 4 набагато швидший, ніж Parcel. Я довів цей факт, скориставшись власними лавками Шона Т. Ларкіна, а посилання на нього в Twitter можна знайти тут.

Тому що ми можемо. Будь-хто може, правда?

Звичайно, те, що матиме найбільший сенс, - це тому, що ми можемо . У нас була ідея швидшого комплектування з інтерфейсом Rusty або з FFI, або з WASM (на той час ще не було впевненого). FFI був більш розумним, що стосується швидкості та DX, тому ми пішли на те, щоб Packem був реалізований у прив'язках Rust FFI.

Ми зіткнулися з кількома проблемами, пов’язаними з нитками, тому ми мало використовували наявні ресурси. В результаті ми використали кілька дочірніх процесів вузлів (з node-worker-farm ) , ту саму техніку, яку використовує Parcel для багатоядерної компіляції, але для більших графіків модулів, оскільки вона додає значний час запуску поверх часу безвідмовної роботи Node при використанні з меншими графіками модулів .

Стиль конфігурації

Це була складна частина. Було багато питань, на які потрібна була хороша відповідь, щоб підібрати правильний стиль конфігурації. Статичний чи динамічний? JSON / YAML / TOML? Наш вибір був повністю заснований на тому, чи потрібен нам Packem для:

  1. Мають акуратніший стиль конфігурації та
  2. Будьте агностиком щодо інших користувацьких конфігурацій, таких як .babelrc або package.json .

Підсумок, ми перейшли до стилю статичної конфігурації, оскільки виявили, що це саме те, що нам потрібно. Щось, що могло б декларативно сказати Packem, як керувати циклом комплектування . Всі межі статичної конфігурації були чітко визначені.

Іншим цікавим аспектом був тип файлу, який ми повинні використовувати для конфігурації. JSON, який є більш характерним для переважної більшості розробників JavaScript або стилів YAML / TOML / XML, які є менш поширеними, але мають власні переваги. Все ще було запропоновано підтримку JSON (№5).

JSON просто не вирізав через усі непотрібні лапки, фігурні та блочні дужки, що має сенс, оскільки це формат обміну даними . XML-іш підхід не заслуговує на повагу щодо використання як формату конфігурації, оскільки робить речі гіршими за JSON, що стосується непотрібних символів. TOML представив багато нових рядків, і налагодження вкладених параметрів не було привабливим для очей, оскільки ми знали, що плагіни Packem можуть стати справді неприємними.

Остаточним переможцем став YAML! Він зміг пройти через усі аспекти належного формату конфігурації (принаймні для Packem). Це:

  1. Робить конфігурацію безболісною.
  2. Використовує елегантний підхід.
  3. Досі знайоме оку JavaScript
  4. Був розроблений спеціально для цього випадку використання (конфігурації) .

Ось приклад типової конфігурації Packem ( packem.config.yml) . Перевірте самі і подумайте про те, щоб написати той самий вміст у стилі JSON / TOML / XML.

До уваги, потрібні лише перші два варіанти! ?

Розширення Packem

Ця функція ще не реалізована.

Іноді нам може знадобитися використовувати функцію, яка ще не існує , може бути не реалізована в Packem або дуже специфічна для нашого проекту . У такому випадку у вас буде два шляхи вирішення ваших потреб:

  1. Створіть плагін Packem для вашого випадку використання (що є рекомендованим варіантом).
  2. Створіть власний RC поверх бінарних файлів Packem.

Використання Rust дає нам можливість перетворити LC в інші двійкові формати, такі як WebAssembly, що дозволить Packem демонструвати декілька цілей компіляції:

  1. Аддон C / C ++ на базі NAPI зі специфічними двійковими файлами платформи, необхідними за замовчуванням RC Packem.
  2. Двійковий файл на основі WebAssembly, який є міжплатформеним і вводиться в RC.
  3. Стандартний пакет Packem, який використовує WebAssembly із сумісною з браузером реалізацією RC.
Останні два ще не знайдені, оскільки внутрішні рефакторинг все ще перебирається.

Незабаром очікується, що розширений посібник покаже вам, як створити власний інструмент збірки за допомогою двійкових файлів Packem, щоб відповідати вашим власним потребам у випадку, якщо вам потрібно використовувати Packem поза середовищем браузера та Node. Ці двійкові файли завершують всю генерацію графіків, а також фільтрування дублікатів та інші аспекти, пов'язані з графіками. Це означає, що ви можете використовувати власний серіалізатор, програму перегляду файлів, систему плагінів тощо. Це дуже схоже на те, як ви можете створити власний візуалізатор через OpenGL.

  1. Ви все ще можете прийняти систему плагінів Packem, оскільки це дозволить вам інтегрувати екосистему плагінів Packem із вашим власним пакетом.
  2. Якщо ви не впевнені, чи потрібно вам створювати власний пакет, знайте, що вам не завжди потрібно буде це робити. Спершу спробуйте подати проблему.
  3. Це гарантія того, що ці двійкові файли прискорять ваш робочий процес залежно від конкретних випадків використання.

Поточний стан

  • Split Розбиття коду для режимів розробки та виробництва.
  • ? Покращений CLI (`- багатослівний`) для кращої інформації про цикл пакетування.
  • ? Інтерфейси модулів, що дозволяють легко маніпулювати графіком модулів.
  • ✔ Правильний пріоритет. Власні функціональні можливості ідеально вписуються в LC. Це означає, що є більше шансів на швидкі збірки.
  • ? Експортуйте N ativeUtils для зовнішнього використання власних функціональних можливостей, включаючи g, enerateModuleGraph що повторює процес створення графіку модулів. Це важко, але все ще корисно у випадках, коли вам потрібен клон поточного графіка активного модуля. Його використання означає подвоєння часу збірки, тому використовуйте його обережно.

Що далі?

Це функції, які ми сподіваємось мати найближчим часом у майбутніх релізах. Вашими зусиллями ми могли б зробити зв’язування правильно . Коли Packem на рівні 1.0 , ми розраховуємо на повну підтримку всіх перелічених нижче функцій та інших, згаданих у дорожній карті Packem.

  • Сумісний з браузером автономний пакет Packem з LC у WebAssembly для більш тісної інтеграції з базовою системою. Аксель Раушмайер вже подав запит на функцію, щоб мати сумісну з Node версію в WASM. Для запису ми незабаром попрацюємо над обома.
  • Тренування дерев, але просунуте. Вирішення імпортного / неназваного імпорту та видалення мертвого коду повинно бути легким завданням. Це означає, що ви можете використовувати такі бібліотеки, як lodash, замість lodash-es, не турбуючись про те, чи буде ваш код видалений чи ні.
  • Автоконфігурація. Як Zero Config, але орієнтований за замовчуванням для додаткової гнучкості.
  • Розширені можливості CLI, щоб зробити розробку з Packem другою природою.
  • Краще звітування про помилки.
  • Більше цілей навколишнього середовища. Наразі Packem може комплектувати лише браузер. Зрештою, ми розраховуємо підтримати Node CJS та інші формати.
  • Більше плагінів. Нам потрібно більше плагінів! Packem має набір загальних плагінів для швидшого початку роботи. Але для розвитку спільноти нам потрібна чудова екосистема плагінів. Перевірте загальнодоступні плагіни або розділ плагінів на сайті, щоб негайно розпочати розробку плагіна.
  • І набагато більше…

Ресурси

  • Packem на GitHub
  • Дорожня карта та запити на функції
  • Офіційний сайт Packem
  • Створення плагінів за допомогою Packem
  • Розбиття коду за допомогою Packem
  • Графік модулів

Packem не досягне 1,0 ще . Якщо ви виявили, що Packem вам взагалі цікавий, спробуйте внести свій вклад у сам Packem, створивши плагіни, оновивши документацію, підтримавши нас фінансово, представляючи Packem на конференціях чи будь-якими іншими способами. Ми цінуємо Ваші зусилля!

Щасливого комплектування! ???