Плоская структура node_modules не является единственным способом
Новые пользователи pnpm часто спрашивают меня о странной структуре node_modules которую создает pnpm. Почему она не плоская? Где находятся все под-зависимости?
Предположу, что читатели этой статьи уже знакомы с плоской по структуре папкой
node_modules, создаваемой npm и Yarn. Если вы не понимаете, почему в npm начиная с третьей версии начали использовать плоскую структуруnode_modules, вы можете найти некоторую предысторию в Почему мы должны использовать pnpm?.
Так чем же необычна папка node_modules в pnpm? Давайте создадим две директории и запустим npm add express в одном из них, а pnpm add express в другом. Вот верхняя часть того, что вы получаете в первой директории node_modules:
.bin
accepts
array-flatten
body-parser
bytes
content-disposition
cookie-signature
cookie
debug
depd
destroy
ee-first
encodeurl
escape-html
etag
express
Вы можете увидеть всю директорию здесь.
А вот что вы получаете в папке node_modules, созданной pnpm:
.pnpm
.modules.yaml
express
Вы можете проверить это здесь.
Так где же все зависимости? В node_modules есть только одна папка .pnpm и символическая ссылка express. Что ж, мы установили только express, так что это единственный пакет, к которому ваше приложение должно иметь доступ
Узнайте больше о том, почему строгость pnpm — это хорошо здесь
Давайте посмотрим, что внутри express:
▾ node_modules
▸ .pnpm
▾ express
▸ lib
History.md
index.js
LICENSE
package.json
Readme.md
.modules.yaml
Внутри express нет node_modules? Где все зависимости express?
Дело в том, что express — это просто символическая ссылка. Когда Node.js разрешает зависимости, он использует их реальные расположения, поэтому символические ссылки не сохраняются. Но, где реальное расположение express, вы можете спросить?
Here: node_modules/.pnpm/express@4.17.1/node_modules/express.
Итак, теперь мы знаем назначение папки .pnpm/. .pnpm/ хранит все пакеты в структуре папок с плоской иерархией, поэтому каждый пакет можно найти в папке, названной по этому шаблону:
.pnpm/<name>@<version>/node_modules/<name>
Это мы называем виртуальной директорией хранилища.
Эта плоская структура избегает проблем с длинными путями, которые вызывались вложенными node_modules, созданными npm v2, но сохраняет изоляцию пакетов, в отличие от плоских node_modules, созданных npm v3,4,5,6 или Yarn v1.
Теперь давайте посмотрим на реальное расположение express:
▾ express
▸ lib
History.md
index.js
LICENSE
package.json
Readme.md
Это обман? В нем до сих пор не хватает node_modules! The second trick of pnpm's node_modules structure is that the dependencies of packages are on the same directory level as the real location of the dependent package. Так что зависимости от express не находятся в .pnpm/express@4.17.1/node_modules/express/node_modules/, но в .pnpm/express@4.17.1/node_modules/:
▾ node_modules
▾ .pnpm
▸ accepts@1.3.5
▸ array-flatten@1.1.1
...
▾ express@4.16.3
▾ node_modules
▸ accepts
▸ array-flatten
▸ body-parser
▸ content-disposition
...
▸ etag
▾ express
▸ lib
History.md
index.js
LICENSE
package.json
Readme.md