Пейджер

🌍 Всем привет! 👋

TL;DR
  • phantomjs-prebuilt при установке через install-скрипт скачивает бинарник
  • pnpm 10+ по умолчанию блокирует lifecycle-скрипты
  • Причина — защита от вредоносных postinstall-скриптов
  • Решение: добавить пакет в onlyBuiltDependencies
🌍 Всем привет! 👋

Cегодня поговорим про неее очень популярную темку 🥺, но если нарветесь, то будете готовы, ну или хотя бы будет понимание почему так, а дальше кирку в руки и на шахтуГПТ.

Недавно я встрял с библиотекой phantomjs-prebuilt (да я видел что она обновлялась последний раз 8 лет назад, но у самурая есть только путь).
Вы могли подумать наверное проблема была в каком-то функционале, но нет 😃. Проблема возникала в момент установки пакета, возможно кто-то не знает, но за кулисами установки разыгрывается целая пьеса.

Что происходит в процессе установки пакета

Разберемся на примере npm, статистика вещь упрямая и npm занимает уверенное первое место среди package managers (хотя лично я, использую на всех проектах только pnpm).

Когда вы пишете npm install, npm прогоняет цепочку скриптов — preinstall → install → postinstall и еще парочку (вот тута можно ознакомиться с каждым)

А дальше фокус-покус 💭, когда в package.json есть install-скрипт или любой другой из цепочки скриптов, то он выполнится автоматически. Вот вам простенький package.json, попробуйте, посмотрите что у вас будет в консоли при установке пакета.

У phantomjs-prebuilt так и происходит, внутри пакета прописан install-скрипт, который при установке запускает скачивание бинарника phantomJS.

Кстати это не означает что это какой-то особый пакет 💎, такой флоу существует даже в популярных библиотеках:

🟠puppeteer - при выполнение скрипта postinstall скачивает Chromium. Без этого бинаря — ничего не запустится.
🟠sharp - при выполнение скрипта install скачивает/собирает libvips.
🟠canvas - при установке компилирует нативные зависимости.

🏳️ Примерчик, а дальше поговорим о реальных проблемках

🔖 Ставим пакет:

npm install phantomjs-prebuilt


🔖 npm видит в package.json такой скрипт:

"scripts": {
  "install": "node install.js"
}


Этот install.js подтягивает бинарник phantomJS под вашу систему и кладёт его в node_modules/.bin откуда и подхватывается npx.

🔖 И теперь прям из консоли можно вызвать:

npx phantomjs --version


🤔 А в чём собсна подвох ?

Я нашел несколько проблем и каждая вытекает из предыдущей:

Началось все с того, что в моменте, на проекте мы сменили npm на pnpm, и у нас отвалилась логика завязанная на ту самую библиотеку phantomjs-prebuilt, я не мог понять почему, крутил 🚘 и вертел, понял что не создается бинарник, хотя с npm все было четенько.

Оказалось все очень даже интересно 😍, начиная с версии 10.0.0, pnpm блокирует lifecycle scripts by default.

Я нашел дико интересную статью почему такая мажористая правка вышла в 10-ке, и если кратко:

🟠Были инциденты с установкой вредоносного ПО для майнинга криптовалют, через скрипт postinstall, который соответственно запускался автоматически при установке пакета.
🟠Долго мусолили блокировать или нет по умолчанию, создавали опросы на различных площадках.
🟠Ссылались на Bun - он ведь уже блокирует скрипты.
🟠Yarn поддержал такую инициативу.

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

🍷 Решение было простым, добавил phantomjs-prebuilt в список onlyBuiltDependencies, чтобы pnpm разрешил выполнять его install-скрипты.

✏️ В сухом остатке

💡 npm и другие пакетные манагеры умеют автоматически запускать скрипты preinstall, install, postinstall и др.
💡Для npm есть флаг --ignore-scripts, чтобы отключить автоматический запуск при установке.
💡 Cтарайтесь проверяйть package.json на наличие того, что может исполняться автоматически.
💡Можно почитать про approve-builds, лишним не будет.
💡Вы можете задать свои кастомные скрипты, которые будут выполнять по своему жизненному циклу.

💬 Делитесь своим мнением в комментариях👇! Если вам понравилась статья, не забудьте поставить лайк! 👍

#PNPM #NPM
Медиа 1
Хотите больше таких постов?
Подпишитесь на канал и читайте продолжение в Telegram.
Подписаться на @ivanchikovitclub Открыть пост в Telegram