~/guides/npm-v12-allowscripts-monorepo

JSON

allowScripts в монорепозитории: общий allowlist или отдельный на пакет

Как npm v12 применяет allowScripts к воркспейсам, и практический подход к слиянию разрешений из нескольких package.json.

Монорепозиторий с npm workspaces обычно имеет package.json у каждого пакета, но npm v12 применяет allowScripts централизованно — на уровне корневого package.json воркспейса, а не разрознено по каждому пакету отдельно. Это создаёт практический вопрос при миграции: как собрать единый корректный allowlist, не потеряв и не задублировав записи из десятка пакетов.

Почему нельзя просто иметь allowScripts в каждом пакете

packages/frontend/package.json:
  allowScripts: { "esbuild@0.21.5": true }

packages/backend/package.json:
  allowScripts: { "bcrypt@5.1.1": true }

npm v12 не читает allowScripts из отдельных пакетов воркспейса при выполнении install-скриптов для всего дерева зависимостей — контроль применяется на уровне корня. Обе записи должны оказаться в корневом package.json, иначе install-скрипты esbuild и bcrypt останутся заблокированными вне зависимости от того, что написано в подпапках.

Практическая стратегия сборки корневого allowlist

Пройдитесь по package.json каждого пакета воркспейса, соберите все записи allowScripts, объедините их в один объект в корне. Дубликаты (одна и та же пара пакет-версия в нескольких пакетах) естественным образом схлопнутся в одну запись при слиянии.

Ситуация Что делать
Одна и та же зависимость с одной версией в двух пакетах Одна запись в корневом allowScripts
Одна и та же зависимость с разными версиями в разных пакетах Две отдельные записи, версионный пиннинг разный
Зависимость только в одном пакете воркспейса Запись переносится в корень как есть

Стоит ли оставлять allowScripts в отдельных пакетах после слияния

Практика зависит от структуры вашего workspace-менеджера, но разумный дефолт — единственный источник истины в корне, а не дублирование в подпапках, которое со временем неизбежно разойдётся с реальным корневым allowlist.

Как собрать это автоматически, а не переписывать вручную

Вычитывать и сверять записи из десятка package.json вручную утомительно и легко ошибиться. Monorepo allowScripts Merger объединяет allowScripts из нескольких package.json в один корневой блок без дублей.

Итоговый чеклист

npm v12 применяет allowScripts централизованно на уровне корневого package.json воркспейса, а не по каждому пакету отдельно.

Одна и та же зависимость с разными версиями в разных пакетах — это разные записи, версионный пиннинг сохраняется по каждой отдельно.

Единственный источник истины в корне снижает риск расхождения между реальным allowlist и тем, что написано в подпапках пакетов.