Я разработал и внедрил PnP, так что я могу говорить об этом часами
tl; dr: Мы записываем только папки .pnp.js
и .pnp
(поверх обычного кэша пряжи). Мы не храним конфигурацию где-либо еще.
Без Plug'n'Play
Когда вы запускаете yarn install
(даже без PnP), происходит несколько вещей:
- Если вы используете функцию автономного зеркала , мы загружаем тарболы из реестра и сохраняем их в папке автономного зеркала
- Независимо от того, используете ли вы автономное зеркало или нет, мы распаковываем все загруженные архивы и сохраняем их файлы в кэше пряжи
- Затем мы выясняем, какие файлы из кэша должны быть скопированы в какое место в
node_modules
- Мы применяем вычисленные изменения (куча
rsync
операций, в основном)
с Plug'n'Play
С PnP рабочий процесс становится таким:
- Без изменений, загружаем tarballs из реестра в автономное зеркало (если включено)
- Без изменений, мы все еще распаковываем их в кэш Yarn
- Мы генерируем
.pnp.js
файл¹
И это все. Нет другого сгенерированного файла, кроме файла .pnp.js
(и кеша, но он уже был там раньше).
¹ Как вы упомянули, мы также создаем папку .pnp
(.yarn
по состоянию на Пряжа 2) в проекте. Эта папка предназначена для хранения данных двух типов:
Отключенные пакеты - это пакеты, которые должны быть локальными для проекта. Как правило, это пакеты со сценариями постинсталляции (мы не можем сохранить их в кеше, поскольку сгенерированные артефакты могут отличаться от проекта к другому).
Виртуальные пакеты, которые являются символическими ссылками, созданными для каждого пакета в вашем дереве зависимостей, в котором перечислены зависимости между равноправными узлами. Не вдаваясь в подробности, они являются необходимой частью дизайна и должны заставить require.resolve
работать как прежде. Эти файлы больше не существуют по состоянию на Пряжа 2 ?
Как это работает?
Файл .pnp.js
содержит информацию, подобную следующей:
webpack@1.0.0 -> /cache/webpack-1.0.0/
-> it depends on lodash@1.0.0
lodash@1.0.0 -> /cache/lodash-1.0.0/
-> no dependencies
Имея эту информацию, разрешение может правильно сделать вывод, что, когда файл в /cache/webpack-1.0.0
делает требуемый вызов lodash
, требуемые файлы должны быть загружены из /cache/lodash-1.0.0
. На практике это немного сложнее (мы сохраняем обратную карту для улучшенного перфорирования, мы используем относительные пути для обеспечения переносимости и т. Д.), Но общая концепция существует.
Бонусный раунд: с Plug'n'Play + Zip loading (Пряжа 2)
Бонус: С Yarn 2 мы собираемся еще больше улучшить этот рабочий процесс. Вот как это будет выглядеть:
- Мы загружаем tarballs из реестра и затем сохраняем в кеш (больше нет различий между автономным зеркалом и кешем - они одинаковые)
- Мы генерируем тот же
.pnp.js
файл, что и раньше
И это все! Как видите, мы больше не распаковываем пакеты (вместо этого мы используем загрузчик Node для чтения их из архивов пакетов во время выполнения).
Это имеет очень интересное свойство: если кеш и файлы .pnp.js
есть, вам не нужно запускать yarn install
, чтобы ваше приложение работало! И чтобы убедиться, что у вас есть эти файлы, вам просто нужно добавить их в свой репозиторий и сделать их версию, как и во всех остальных случаях .²
Это очень полезно, так как вам не нужно запускать yarn install
после git rebase
, git pull
или git checkout
, и ваши системы CI становятся быстрее и стабильнее, так как им не требуется специальная настройка - просто клонируйте свое приложение, и оно будет работать.
² Прежде чем кто-то упомянул об этом - регистрация двоичных файлов в репозитории прекрасно . Причина, по которой node_modules
была очень плохая вещь для регистрации в вашем репозитории, заключалась в экспоненциальном количестве текстовых файлов, что оказывало огромное напряжение для Git - технически, но и философски, поскольку проверки кода были невозможны.
В описанном мной случае мы не страдаем от одной и той же проблемы, потому что количество файлов ограничено (ровно один файл для каждого пакета), и просмотреть их очень просто - на самом деле, это лучше в что вы можете четко видеть, сколько новых пакетов добавлено в ваш проект с помощью PR!