<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://pnpm.io/pnpm/ru/blog</id>
    <title>pnpm Blog</title>
    <updated>2022-12-30T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://pnpm.io/pnpm/ru/blog"/>
    <subtitle>pnpm Blog</subtitle>
    <icon>https://pnpm.io/pnpm/ru/img/favicon.png</icon>
    <entry>
        <title type="html"><![CDATA[The year 2022 for pnpm]]></title>
        <id>https://pnpm.io/pnpm/ru/blog/2022/12/30/yearly-update</id>
        <link href="https://pnpm.io/pnpm/ru/blog/2022/12/30/yearly-update"/>
        <updated>2022-12-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[It is the end of the year. A really hard year. As you may know, I live in Ukraine, so due to Russia's war against us, it was harder to lead this project than in previous years. Nevertheless, it was a good year for pnpm. We've got a lot of new users, contributors, and we have implemented many great features.]]></summary>
        <content type="html"><![CDATA[<p>It is the end of the year. A really hard year. As you may know, I live in Ukraine, so due to Russia's war against us, it was harder to lead this project than in previous years. Nevertheless, it was a good year for pnpm. We've got a lot of new users, contributors, and we have implemented many great features.</p><p><img loading="lazy" src="/pnpm/ru/assets/images/2022-review-092f8f0dfe82b760c2e90fd776d82f75.png" width="640" height="640" class="img_XicP"></p><p>(the above illustration was generated by Midjourney. The tiger symolizes the year of the tiger)</p><h2 class="anchor anchorWithStickyNavbar_M9ON" id="использование">Использование<a href="#использование" class="hash-link" aria-label="Прямая ссылка на Использование" title="Прямая ссылка на Использование">​</a></h2><h3 class="anchor anchorWithStickyNavbar_M9ON" id="статистика-скачиваний">Статистика скачиваний<a href="#статистика-скачиваний" class="hash-link" aria-label="Прямая ссылка на Статистика скачиваний" title="Прямая ссылка на Статистика скачиваний">​</a></h3><p>My goal this year was to beat Lerna by the number of downloads. We were able to achieve this goal <a href="https://npm-stat.com/charts.html?package=pnpm&amp;package=lerna&amp;from=2022-01-01&amp;to=2022-12-30" target="_blank" rel="noopener noreferrer">in August</a>:</p><p><img loading="lazy" src="/pnpm/ru/assets/images/pnpm-vs-lerna-stats-cad28f3b9685ef684c864f919f7f9c5e.png" width="997" height="400" class="img_XicP"></p><p>pnpm was downloaded more than <a href="https://npm-stat.com/charts.html?package=pnpm&amp;from=2016-12-01&amp;to=2022-12-30" target="_blank" rel="noopener noreferrer">5 times more</a> in 2022 than in 2021:</p><p><img loading="lazy" src="/pnpm/ru/assets/images/download-stats-2022-e4de79bf61e1066802166f9d97cb36ac.png" width="997" height="400" class="img_XicP"></p><h3 class="anchor anchorWithStickyNavbar_M9ON" id="посещения-документации">Посещения документации<a href="#посещения-документации" class="hash-link" aria-label="Прямая ссылка на Посещения документации" title="Прямая ссылка на Посещения документации">​</a></h3><p>Мы собираем некоторую обезличенную статистику из нашей документации с помощью Google Analytics. In 2022, sometimes we had more than 20,000 unique visitors a week. This is 10 times more than in 2021!</p><p><img loading="lazy" src="/pnpm/ru/assets/images/ga-unique-visits-2022-b2e9bf0b6c559a5c59fdbfd8bb1861f0.png" width="778" height="391" class="img_XicP"></p><h3 class="anchor anchorWithStickyNavbar_M9ON" id="звезды-на-github">Звезды на GitHub<a href="#звезды-на-github" class="hash-link" aria-label="Прямая ссылка на Звезды на GitHub" title="Прямая ссылка на Звезды на GitHub">​</a></h3><p>Our <a href="https://github.com/pnpm/pnpm" target="_blank" rel="noopener noreferrer">main GitHub repository</a> received almost +7,000 stars this year.</p><p><img loading="lazy" src="/pnpm/ru/assets/images/stars-2022-434ca95e6da688fdff1bb1bf89d6a2d9.png" width="584" height="787" class="img_XicP"></p><h3 class="anchor anchorWithStickyNavbar_M9ON" id="our-contributors">Our contributors<a href="#our-contributors" class="hash-link" aria-label="Прямая ссылка на Our contributors" title="Прямая ссылка на Our contributors">​</a></h3><p>We had a lot of new and active contributors this year. These are the people the merge at least one PR in 2022:</p><ul><li><a href="https://github.com/zkochan" target="_blank" rel="noopener noreferrer">Zoltan Kochan</a></li><li><a href="https://github.com/lvqq" target="_blank" rel="noopener noreferrer">chlorine</a></li><li><a href="https://github.com/await-ovo" target="_blank" rel="noopener noreferrer">await-ovo</a></li><li><a href="https://github.com/gluxon" target="_blank" rel="noopener noreferrer">Brandon Cheng</a></li><li><a href="https://github.com/d3lm" target="_blank" rel="noopener noreferrer">Dominic Elm</a></li><li><a href="https://github.com/mcmxcdev" target="_blank" rel="noopener noreferrer">MCMXC</a></li><li><a href="https://github.com/dev-itsheng" target="_blank" rel="noopener noreferrer">那里好脏不可以</a></li><li><a href="https://github.com/HomyeeKing" target="_blank" rel="noopener noreferrer">Homyee King</a></li><li><a href="https://github.com/Shinyaigeek" target="_blank" rel="noopener noreferrer">Shinobu Hayashi</a></li><li><a href="https://github.com/BlackHole1" target="_blank" rel="noopener noreferrer">Black-Hole</a></li><li><a href="https://github.com/kenrick95" target="_blank" rel="noopener noreferrer">Kenrick</a></li><li><a href="https://github.com/weyert" target="_blank" rel="noopener noreferrer">Weyert de Boer</a></li><li><a href="https://github.com/gwhitney" target="_blank" rel="noopener noreferrer">Glen Whitney</a></li><li><a href="https://github.com/chengcyber" target="_blank" rel="noopener noreferrer">Cheng</a></li><li><a href="https://github.com/fireairforce" target="_blank" rel="noopener noreferrer">zoomdong</a></li><li><a href="https://github.com/ufec" target="_blank" rel="noopener noreferrer">thinkhalo</a></li><li><a href="https://github.com/LuciNyan" target="_blank" rel="noopener noreferrer">子瞻 Luci</a></li><li><a href="https://github.com/Spencer17x" target="_blank" rel="noopener noreferrer">spencer17x</a></li><li><a href="https://github.com/liuxingbaoyu" target="_blank" rel="noopener noreferrer">liuxingbaoyu</a></li><li><a href="https://github.com/WhiteKiwi" target="_blank" rel="noopener noreferrer">장지훈</a></li><li><a href="https://github.com/jondlm" target="_blank" rel="noopener noreferrer">Jon de la Motte</a></li><li><a href="https://github.com/Jack-Works" target="_blank" rel="noopener noreferrer">Jack Works</a></li><li><a href="https://github.com/milahu" target="_blank" rel="noopener noreferrer">milahu</a></li><li><a href="https://github.com/David-Collins" target="_blank" rel="noopener noreferrer">David Collins</a></li><li><a href="https://github.com/nikoladev" target="_blank" rel="noopener noreferrer">nikoladev</a></li><li><a href="https://github.com/ibezkrovnyi" target="_blank" rel="noopener noreferrer">Igor Bezkrovnyi</a></li><li><a href="https://github.com/illright" target="_blank" rel="noopener noreferrer">Lev Chelyadinov</a></li><li><a href="https://github.com/javier-garcia-meteologica" target="_blank" rel="noopener noreferrer">javier-garcia-meteologica</a></li></ul><h2 class="anchor anchorWithStickyNavbar_M9ON" id="feature-highlights">Feature Highlights<a href="#feature-highlights" class="hash-link" aria-label="Прямая ссылка на Feature Highlights" title="Прямая ссылка на Feature Highlights">​</a></h2><h3 class="anchor anchorWithStickyNavbar_M9ON" id="supporting-a-symlinkless-hoisted-node_modules-since-v6250">Supporting a symlinkless hoisted <code>node_modules</code> (since <a href="https://github.com/pnpm/pnpm/releases/tag/v6.25.0" target="_blank" rel="noopener noreferrer">v6.25.0</a>)<a href="#supporting-a-symlinkless-hoisted-node_modules-since-v6250" class="hash-link" aria-label="Прямая ссылка на supporting-a-symlinkless-hoisted-node_modules-since-v6250" title="Прямая ссылка на supporting-a-symlinkless-hoisted-node_modules-since-v6250">​</a></h3><p>Right at the beginning of 2022, we have added support for the "traditional" hoisted (a.k.a flat <code>node_modules</code>). We use Yarn's hoisting algorithm to create a proper hoisted <code>node_modules</code>. This new setting has basically made pnpm compatible with all Node.js stack that are compatible with npm CLI.</p><p>To use the hoisted <code>node_modules</code> directory structure, use the <code>node-linker=hoisted</code> setting in an <code>.npmrc</code> file.</p><h3 class="anchor anchorWithStickyNavbar_M9ON" id="side-effects-cache-since-v700">Side effects cache (since <a href="https://github.com/pnpm/pnpm/releases/tag/v7.0.0" target="_blank" rel="noopener noreferrer">v7.0.0</a>)<a href="#side-effects-cache-since-v700" class="hash-link" aria-label="Прямая ссылка на side-effects-cache-since-v700" title="Прямая ссылка на side-effects-cache-since-v700">​</a></h3><p>Since v7, <a href="/pnpm/ru/npmrc#side-effects-cache">side-effect-cache</a> is enabled by default, so dependencies that should be built are only built once on a machine. This improves installation speed by a lot in projects that have dependencies with build scripts.</p><h3 class="anchor anchorWithStickyNavbar_M9ON" id="dependencies-patching-since-v740">Dependencies patching (since <a href="https://github.com/pnpm/pnpm/releases/tag/v7.4.0" target="_blank" rel="noopener noreferrer">v7.4.0</a>)<a href="#dependencies-patching-since-v740" class="hash-link" aria-label="Прямая ссылка на dependencies-patching-since-v740" title="Прямая ссылка на dependencies-patching-since-v740">​</a></h3><p>The <a href="/pnpm/ru/cli/patch"><code>pnpm patch</code></a> command have been added for patching dependencies in your <code>node_modules</code>.</p><h3 class="anchor anchorWithStickyNavbar_M9ON" id="time-based-resolution-strategy-since-v7100">Time-based resolution strategy (since <a href="https://github.com/pnpm/pnpm/releases/tag/v7.10.0" target="_blank" rel="noopener noreferrer">v7.10.0</a>)<a href="#time-based-resolution-strategy-since-v7100" class="hash-link" aria-label="Прямая ссылка на time-based-resolution-strategy-since-v7100" title="Прямая ссылка на time-based-resolution-strategy-since-v7100">​</a></h3><p>A new resolution mode was added to pnpm, which should make updating dependencies more secure. You can change the resolution mode with the <a href="https://pnpm.io/npmrc#resolution-mode" target="_blank" rel="noopener noreferrer">resolution-mode</a> setting.</p><h3 class="anchor anchorWithStickyNavbar_M9ON" id="listing-licenses-of-dependencies-since-v7170">Listing licenses of dependencies (since <a href="https://github.com/pnpm/pnpm/releases/tag/v7.17.0" target="_blank" rel="noopener noreferrer">v7.17.0</a>)<a href="#listing-licenses-of-dependencies-since-v7170" class="hash-link" aria-label="Прямая ссылка на listing-licenses-of-dependencies-since-v7170" title="Прямая ссылка на listing-licenses-of-dependencies-since-v7170">​</a></h3><p>You may now use the <a href="/pnpm/ru/cli/licenses"><code>pnpm licenses list</code></a> command to check the licenses of the installed packages.</p>]]></content>
        <author>
            <name>Zoltan Kochan</name>
            <uri>http://twitter.com/zoltankochan</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[2021 год для pnpm]]></title>
        <id>https://pnpm.io/pnpm/ru/blog/2021/12/29/yearly-update</id>
        <link href="https://pnpm.io/pnpm/ru/blog/2021/12/29/yearly-update"/>
        <updated>2021-12-29T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Уже конец года, и он был хорошим для pnpm, так что давайте посмотрим каким он был.]]></summary>
        <content type="html"><![CDATA[<p>Уже конец года, и он был хорошим для pnpm, так что давайте посмотрим каким он был.</p><h2 class="anchor anchorWithStickyNavbar_M9ON" id="использование">Использование<a href="#использование" class="hash-link" aria-label="Прямая ссылка на Использование" title="Прямая ссылка на Использование">​</a></h2><h3 class="anchor anchorWithStickyNavbar_M9ON" id="статистика-скачиваний">Статистика скачиваний<a href="#статистика-скачиваний" class="hash-link" aria-label="Прямая ссылка на Статистика скачиваний" title="Прямая ссылка на Статистика скачиваний">​</a></h3><p>Моей целью на этот год было победить Bower по количеству скачиваний. И мы достигли этой цели в <a href="https://npm-stat.com/charts.html?package=pnpm&amp;package=bower&amp;from=2021-01-01&amp;to=2021-12-29" target="_blank" rel="noopener noreferrer">ноябре</a>:</p><p><img loading="lazy" src="/pnpm/ru/assets/images/pnpm-vs-bower-stats-6ec69a7308f5fbc1433420b1b2f7457f.png" width="976" height="389" class="img_XicP"></p><p>pnpm был скачан примерно <a href="https://npm-stat.com/charts.html?package=pnpm&amp;from=2016-12-01&amp;to=2021-12-29" target="_blank" rel="noopener noreferrer"> в 3 раза больше</a> в 2021, чем в 2020:</p><p><img loading="lazy" src="/pnpm/ru/assets/images/download-stats-2021-1418562cb03abd558c4a6b4b17155227.png" width="983" height="394" class="img_XicP"></p><div class="theme-admonition theme-admonition-note alert alert--secondary admonition_qn3S"><div class="admonitionHeading_ueQW"><span class="admonitionIcon_N0Kn"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>примечание</div><div class="admonitionContent_JsRk"><p>Эта статистика даже не измеряет все возможные способы установки pnpm! Она измеряет только количество загрузок <a href="https://www.npmjs.com/package/pnpm" target="_blank" rel="noopener noreferrer">npm пакета pnpm</a>. В этом году мы так-же добавили исполняемые файлы pmpm, которые скачиваются иначе.</p></div></div><h3 class="anchor anchorWithStickyNavbar_M9ON" id="посещения-документации">Посещения документации<a href="#посещения-документации" class="hash-link" aria-label="Прямая ссылка на Посещения документации" title="Прямая ссылка на Посещения документации">​</a></h3><p>Мы собираем некоторую обезличенную статистику из нашей документации с помощью Google Analytics. В 2021 году, иногда у нас было более 2000 уникальных посетителей в неделю.</p><p><img loading="lazy" src="/pnpm/ru/assets/images/ga-unique-visits-2021-b8bc3649f680565127696c85bdd4b701.png" width="665" height="509" class="img_XicP"></p><p>Большинство наших пользователей из США и Китая.</p><p><img loading="lazy" src="/pnpm/ru/assets/images/countries-2021-8eb9625e1798649ee04451dfb10ac851.png" width="585" height="498" class="img_XicP"></p><h3 class="anchor anchorWithStickyNavbar_M9ON" id="звезды-на-github">Звезды на GitHub<a href="#звезды-на-github" class="hash-link" aria-label="Прямая ссылка на Звезды на GitHub" title="Прямая ссылка на Звезды на GitHub">​</a></h3><p>Наш <a href="https://github.com/pnpm/pnpm" target="_blank" rel="noopener noreferrer">основной репозиторий на GitHub</a> получил +5000 звезд в этом году.</p><p><img loading="lazy" src="/pnpm/ru/assets/images/stars-2021-0061c16f424e33ba0db224d82bcb53f3.png" width="913" height="800" class="img_XicP"></p><h3 class="anchor anchorWithStickyNavbar_M9ON" id="новые-пользователи">Новые пользователи<a href="#новые-пользователи" class="hash-link" aria-label="Прямая ссылка на Новые пользователи" title="Прямая ссылка на Новые пользователи">​</a></h3><p>Наш самый большой новый пользователь в этом году - <a href="https://github.com/pnpm/pnpm.github.io/pull/89" target="_blank" rel="noopener noreferrer">Bytedance</a> (компания, стоящая за TikTok).</p><p>Кроме того, многие замечательные проекты с открытым исходным кодом начали использовать pnpm. Некоторые перешли на pnpm из-за хорошей поддержки монорепозиториев:</p><ul><li><a href="https://github.com/vuejs/vue-next" target="_blank" rel="noopener noreferrer">Vue</a></li><li><a href="https://github.com/vitejs/vite" target="_blank" rel="noopener noreferrer">Vite</a></li><li>и <a href="https://pnpm.io/workspaces#usage-examples" target="_blank" rel="noopener noreferrer">другие</a></li></ul><p>Некоторые переключились, потому что им нравится, насколько эффективный, быстрый и красивый pnpm:</p><ul><li><a href="https://twitter.com/Autoprefixer/status/1476226146488692736" target="_blank" rel="noopener noreferrer">Autoprefixer</a></li><li><a href="https://twitter.com/PostCSS/status/1470438664006258701" target="_blank" rel="noopener noreferrer">PostCSS</a></li><li><a href="https://twitter.com/Browserslist/status/1468264308308156419" target="_blank" rel="noopener noreferrer">Browserslist</a></li></ul><h2 class="anchor anchorWithStickyNavbar_M9ON" id="feature-highlights">Feature Highlights<a href="#feature-highlights" class="hash-link" aria-label="Прямая ссылка на Feature Highlights" title="Прямая ссылка на Feature Highlights">​</a></h2><h3 class="anchor anchorWithStickyNavbar_M9ON" id="new-lockfile-format-since-v600">New lockfile format (since <a href="https://github.com/pnpm/pnpm/releases/tag/v6.0.0" target="_blank" rel="noopener noreferrer">v6.0.0</a>)<a href="#new-lockfile-format-since-v600" class="hash-link" aria-label="Прямая ссылка на new-lockfile-format-since-v600" title="Прямая ссылка на new-lockfile-format-since-v600">​</a></h3><p>One of the first and most important changes this year was the new <code>pnpm-lock.yaml</code> format. This was a breaking change, so we had to release v6. But it was a success. The old lockfile was causing Git conflicts frequently. Since the new format was introduced, we did not receive any complaints about Git conflicts.</p><h3 class="anchor anchorWithStickyNavbar_M9ON" id="managing-nodejs-versions-since-v6120">Managing Node.js versions (since <a href="https://github.com/pnpm/pnpm/releases/tag/v6.12.0" target="_blank" rel="noopener noreferrer">v6.12.0</a>)<a href="#managing-nodejs-versions-since-v6120" class="hash-link" aria-label="Прямая ссылка на managing-nodejs-versions-since-v6120" title="Прямая ссылка на managing-nodejs-versions-since-v6120">​</a></h3><p>We shipped a new command (<code>pnpm env</code>) that allows to manage Node.js versions. So you may use pnpm instead of Node.js version managers like nvm or Volta.</p><p>Also, pnpm is shipped as a standalone executable, so you can run it even with no Node.js preinstalled on the system.</p><h3 class="anchor anchorWithStickyNavbar_M9ON" id="injecting-local-dependencies-since-v6200">Injecting local dependencies (since <a href="https://github.com/pnpm/pnpm/releases/tag/v6.20.0" target="_blank" rel="noopener noreferrer">v6.20.0</a>)<a href="#injecting-local-dependencies-since-v6200" class="hash-link" aria-label="Прямая ссылка на injecting-local-dependencies-since-v6200" title="Прямая ссылка на injecting-local-dependencies-since-v6200">​</a></h3><p>You may "inject" a local dependency. By default, local dependencies are symlinked to <code>node_modules</code> but with this new feature you may instruct pnpm to hard link the files of the package instead.</p><h3 class="anchor anchorWithStickyNavbar_M9ON" id="improved-reporting-of-peer-dependency-issues-since-v6240">Improved reporting of peer dependency issues (since <a href="https://github.com/pnpm/pnpm/releases/tag/v6.24.0" target="_blank" rel="noopener noreferrer">v6.24.0</a>)<a href="#improved-reporting-of-peer-dependency-issues-since-v6240" class="hash-link" aria-label="Прямая ссылка на improved-reporting-of-peer-dependency-issues-since-v6240" title="Прямая ссылка на improved-reporting-of-peer-dependency-issues-since-v6240">​</a></h3><p>Peer dependency issues used to be printed as plain text and it was hard to understand them. They are now all grouped and printed in a nice hierarchy structure.</p><h2 class="anchor anchorWithStickyNavbar_M9ON" id="конкуренция">Конкуренция<a href="#конкуренция" class="hash-link" aria-label="Прямая ссылка на Конкуренция" title="Прямая ссылка на Конкуренция">​</a></h2><h3 class="anchor anchorWithStickyNavbar_M9ON" id="yarn">Yarn<a href="#yarn" class="hash-link" aria-label="Прямая ссылка на Yarn" title="Прямая ссылка на Yarn">​</a></h3><p>Yarn added a pnpm linker in <a href="https://dev.to/arcanis/yarn-31-corepack-esm-pnpm-optional-packages--3hak#new-install-mode-raw-pnpm-endraw-" target="_blank" rel="noopener noreferrer">v3.1</a>. So Yarn can create a similar node-modules directory structure to the one that pnpm creates.</p><p>Also, the Yarn team plans to implement a content-addressable storage to be more disk space efficient.</p><h3 class="anchor anchorWithStickyNavbar_M9ON" id="npm">npm<a href="#npm" class="hash-link" aria-label="Прямая ссылка на npm" title="Прямая ссылка на npm">​</a></h3><p>The npm team decided to also adopt the symlinked node-modules directory structure that pnpm uses (related <a href="https://github.com/npm/rfcs/blob/main/accepted/0042-isolated-mode.md" target="_blank" rel="noopener noreferrer">RFC</a>).</p><h3 class="anchor anchorWithStickyNavbar_M9ON" id="другие">Другие<a href="#другие" class="hash-link" aria-label="Прямая ссылка на Другие" title="Прямая ссылка на Другие">​</a></h3><p>Оба <a href="https://twitter.com/jarredsumner/status/1473416431291174912/photo/1" target="_blank" rel="noopener noreferrer">Bun</a>, написанный на Zig, и <a href="https://github.com/voltpkg/volt" target="_blank" rel="noopener noreferrer">Volt</a>, написанный на Rust, говорять что они быстрее чем npm/Yarn/pnpm. Я еще не замерял производительность этих пакетных менеджеров.</p><h2 class="anchor anchorWithStickyNavbar_M9ON" id="планы-на-будущее">Планы на будущее<a href="#планы-на-будущее" class="hash-link" aria-label="Прямая ссылка на Планы на будущее" title="Прямая ссылка на Планы на будущее">​</a></h2><p>Быстрее, лучше, лучший.</p>]]></content>
        <author>
            <name>Zoltan Kochan</name>
            <uri>http://twitter.com/zoltankochan</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Node-Modules configuration options with pnpm]]></title>
        <id>https://pnpm.io/pnpm/ru/blog/2020/10/17/node-modules-configuration-options-with-pnpm</id>
        <link href="https://pnpm.io/pnpm/ru/blog/2020/10/17/node-modules-configuration-options-with-pnpm"/>
        <updated>2020-10-17T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[There are many ways to create a nodemodules directory. Your goal must be to create the most strict one but if that is not possible, there are options to make a loose nodemodules as well.]]></summary>
        <content type="html"><![CDATA[<p>There are many ways to create a node_modules directory. Your goal must be to create the most strict one but if that is not possible, there are options to make a loose node_modules as well.</p><h2 class="anchor anchorWithStickyNavbar_M9ON" id="the-default-setup">The default setup<a href="#the-default-setup" class="hash-link" aria-label="Прямая ссылка на The default setup" title="Прямая ссылка на The default setup">​</a></h2><p>By default, pnpm v5 will create a semi-strict node_modules. Semi-strict means that your application will only be able to require packages that are added as dependencies to <code>package.json</code> (with a few exceptions). However, your dependencies will be able to access any packages.</p><p>The default configuration looks like this:</p><div class="language-ini codeBlockContainer_PfM4 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_sVD5"><pre tabindex="0" class="prism-code language-ini codeBlock_IFdB thin-scrollbar"><code class="codeBlockLines__UdX"><span class="token-line" style="color:#393A34"><span class="token plain">; All packages are hoisted to node_modules/.pnpm/node_modules</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">hoist-pattern[]=*</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">; All types are hoisted to the root in order to make TypeScript happy</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">public-hoist-pattern[]=*types*</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">; All ESLint-related packages are hoisted to the root as well</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">public-hoist-pattern[]=*eslint*</span><br></span></code></pre><div class="buttonGroup_W9z0"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_U9Tg" aria-hidden="true"><svg class="copyButtonIcon_jN4X" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_ajRE" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_M9ON" id="plugnplay-the-strictest-configuration">Plug'n'Play. The strictest configuration<a href="#plugnplay-the-strictest-configuration" class="hash-link" aria-label="Прямая ссылка на Plug'n'Play. The strictest configuration" title="Прямая ссылка на Plug'n'Play. The strictest configuration">​</a></h2><p>pnpm supports <a href="https://yarnpkg.com/features/pnp" target="_blank" rel="noopener noreferrer">Yarn's Plug'n'Play</a> since v5.9. With PnP, both your application and the dependencies of your application will have access only to their declared dependencies. This is even stricter then setting <code>hoist=false</code> because inside a monorepo, your application will not be able to access even the dependencies of the root project.</p><p>To use Plug'n'Play, set these settings:</p><div class="language-ini codeBlockContainer_PfM4 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_sVD5"><pre tabindex="0" class="prism-code language-ini codeBlock_IFdB thin-scrollbar"><code class="codeBlockLines__UdX"><span class="token-line" style="color:#393A34"><span class="token plain">node-linker=pnp</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">symlink=false</span><br></span></code></pre><div class="buttonGroup_W9z0"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_U9Tg" aria-hidden="true"><svg class="copyButtonIcon_jN4X" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_ajRE" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_M9ON" id="a-strict-traditional-modules-directory">A strict, traditional modules directory<a href="#a-strict-traditional-modules-directory" class="hash-link" aria-label="Прямая ссылка на A strict, traditional modules directory" title="Прямая ссылка на A strict, traditional modules directory">​</a></h2><p>If you are not ready to use PnP yet, you can still be strict and only allow packages to access their own dependencies by setting the hoist configuration to false:</p><div class="language-ini codeBlockContainer_PfM4 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_sVD5"><pre tabindex="0" class="prism-code language-ini codeBlock_IFdB thin-scrollbar"><code class="codeBlockLines__UdX"><span class="token-line" style="color:#393A34"><span class="token plain">hoist=false</span><br></span></code></pre><div class="buttonGroup_W9z0"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_U9Tg" aria-hidden="true"><svg class="copyButtonIcon_jN4X" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_ajRE" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>However, if some of your dependencies are trying to access packages that they don't have in dependencies, you have two options:</p><ol><li><p>Create a <code>pnpmfile.js</code> and use a <a href="/pnpm/ru/pnpmfile">hook</a> to add the missing dependency to the package's manifest.</p></li><li><p>Add a pattern to the <code>hoist-pattern</code> setting. For instance, if the not found module is <code>babel-core</code>, add the following setting to <code>.npmrc</code>:</p><div class="language-ini codeBlockContainer_PfM4 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_sVD5"><pre tabindex="0" class="prism-code language-ini codeBlock_IFdB thin-scrollbar"><code class="codeBlockLines__UdX"><span class="token-line" style="color:#393A34"><span class="token plain">hoist-pattern[]=babel-core</span><br></span></code></pre><div class="buttonGroup_W9z0"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_U9Tg" aria-hidden="true"><svg class="copyButtonIcon_jN4X" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_ajRE" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></li></ol><h2 class="anchor anchorWithStickyNavbar_M9ON" id="the-worst-case---hoisting-to-the-root">The worst case - hoisting to the root<a href="#the-worst-case---hoisting-to-the-root" class="hash-link" aria-label="Прямая ссылка на The worst case - hoisting to the root" title="Прямая ссылка на The worst case - hoisting to the root">​</a></h2><p>Some tools might not work even with the default configuration of pnpm, which hoists everything to the root of the virtual store and some packages to the root. In this case, you can hoist either everything or a subset of dependencies to the root of the modules directory.</p><p>Hoisting everything to the root of node_modules:</p><div class="language-ini codeBlockContainer_PfM4 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_sVD5"><pre tabindex="0" class="prism-code language-ini codeBlock_IFdB thin-scrollbar"><code class="codeBlockLines__UdX"><span class="token-line" style="color:#393A34"><span class="token plain">shamefully-hoist=true</span><br></span></code></pre><div class="buttonGroup_W9z0"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_U9Tg" aria-hidden="true"><svg class="copyButtonIcon_jN4X" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_ajRE" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Hoisting only packages that match a pattern:</p><div class="language-ini codeBlockContainer_PfM4 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_sVD5"><pre tabindex="0" class="prism-code language-ini codeBlock_IFdB thin-scrollbar"><code class="codeBlockLines__UdX"><span class="token-line" style="color:#393A34"><span class="token plain">public-hoist-pattern[]=babel-*</span><br></span></code></pre><div class="buttonGroup_W9z0"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_U9Tg" aria-hidden="true"><svg class="copyButtonIcon_jN4X" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_ajRE" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>]]></content>
        <author>
            <name>Zoltan Kochan</name>
            <uri>http://twitter.com/zoltankochan</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Плоская структура node_modules не является единственным способом]]></title>
        <id>https://pnpm.io/pnpm/ru/blog/2020/05/27/flat-node-modules-is-not-the-only-way</id>
        <link href="https://pnpm.io/pnpm/ru/blog/2020/05/27/flat-node-modules-is-not-the-only-way"/>
        <updated>2020-05-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Новые пользователи pnpm часто спрашивают меня о странной структуре node_modules которую создает pnpm. Почему она не плоская? Где находятся все под-зависимости?]]></summary>
        <content type="html"><![CDATA[<p>Новые пользователи pnpm часто спрашивают меня о странной структуре <code>node_modules</code> которую создает pnpm. Почему она не плоская? Где находятся все под-зависимости?</p><blockquote><p>Я принял считать, что читатели этой статьи уже хорошо знакомы с плоской по структуре папкой <code>node_modules</code>, создаваемой npm и Yarn. If you don't understand why npm 3 had to start using flat <code>node_modules</code> in v3, you can find some prehistory in <a href="https://www.kochan.io/nodejs/why-should-we-use-pnpm.html" target="_blank" rel="noopener noreferrer">Why should we use pnpm?</a>.</p></blockquote><p>So why is pnpm's <code>node_modules</code> unusual? Let's create two directories and run <code>npm add express</code> in one of them and <code>pnpm add express</code> in the other one. Here's the top of what you get in the first directory's <code>node_modules</code>:</p><div class="language-text codeBlockContainer_PfM4 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_sVD5"><pre tabindex="0" class="prism-code language-text codeBlock_IFdB thin-scrollbar"><code class="codeBlockLines__UdX"><span class="token-line" style="color:#393A34"><span class="token plain">.bin</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">accepts</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">array-flatten</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">body-parser</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">bytes</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">content-disposition</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">cookie-signature</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">cookie</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">debug</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">depd</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">destroy</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ee-first</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">encodeurl</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">escape-html</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">etag</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">express</span><br></span></code></pre><div class="buttonGroup_W9z0"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_U9Tg" aria-hidden="true"><svg class="copyButtonIcon_jN4X" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_ajRE" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>You can see the whole directory <a href="https://github.com/zkochan/comparing-node-modules/tree/master/npm-example/node_modules" target="_blank" rel="noopener noreferrer">here</a>.</p><p>And this is what you get in the <code>node_modules</code> created by pnpm:</p><div class="language-text codeBlockContainer_PfM4 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_sVD5"><pre tabindex="0" class="prism-code language-text codeBlock_IFdB thin-scrollbar"><code class="codeBlockLines__UdX"><span class="token-line" style="color:#393A34"><span class="token plain">.pnpm</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">.modules.yaml</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">express</span><br></span></code></pre><div class="buttonGroup_W9z0"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_U9Tg" aria-hidden="true"><svg class="copyButtonIcon_jN4X" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_ajRE" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>You can check it <a href="https://github.com/zkochan/comparing-node-modules/tree/master/pnpm5-example/node_modules" target="_blank" rel="noopener noreferrer">here</a>.</p><p>So where are all the dependencies? There is only one folder in the <code>node_modules</code> called <code>.pnpm</code> and a symlink called <code>express</code>. Well, we installed only <code>express</code>, so that is the only package that your application has to have access to</p><blockquote><p>Read more about why pnpm's strictness is a good thing <a href="https://medium.com/pnpm/pnpms-strictness-helps-to-avoid-silly-bugs-9a15fb306308" target="_blank" rel="noopener noreferrer">here</a></p></blockquote><p>Let's see what is inside <code>express</code>:</p><div class="language-text codeBlockContainer_PfM4 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_sVD5"><pre tabindex="0" class="prism-code language-text codeBlock_IFdB thin-scrollbar"><code class="codeBlockLines__UdX"><span class="token-line" style="color:#393A34"><span class="token plain">▾ node_modules</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  ▸ .pnpm</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  ▾ express</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    ▸ lib</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      History.md</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      index.js</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      LICENSE</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      package.json</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      Readme.md</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  .modules.yaml</span><br></span></code></pre><div class="buttonGroup_W9z0"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_U9Tg" aria-hidden="true"><svg class="copyButtonIcon_jN4X" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_ajRE" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><code>express</code> has no <code>node_modules</code>? Where are all the dependencies of <code>express</code>?</p><p>The trick is that <code>express</code> is just a symlink. When Node.js resolves dependencies, it uses their real locations, so it does not preserve symlinks. But where is the real location of <code>express</code>, you might ask?</p><p>Here: <a href="https://github.com/zkochan/comparing-node-modules/tree/master/pnpm5-example/node_modules/.pnpm/express@4.17.1/node_modules/express" target="_blank" rel="noopener noreferrer">node_modules/.pnpm/express@4.17.1/node_modules/express</a>.</p><p>OK, so now we know the purpose of the <code>.pnpm/</code> folder. <code>.pnpm/</code> stores all the packages in a flat folder structure, so every package can be found in a folder named by this pattern:</p><div class="language-text codeBlockContainer_PfM4 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_sVD5"><pre tabindex="0" class="prism-code language-text codeBlock_IFdB thin-scrollbar"><code class="codeBlockLines__UdX"><span class="token-line" style="color:#393A34"><span class="token plain">.pnpm/&lt;name&gt;@&lt;version&gt;/node_modules/&lt;name&gt;</span><br></span></code></pre><div class="buttonGroup_W9z0"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_U9Tg" aria-hidden="true"><svg class="copyButtonIcon_jN4X" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_ajRE" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>We call it the virtual store directory.</p><p>This flat structure avoids the long path issues that were caused by the nested <code>node_modules</code> created by npm v2 but keeps packages isolated unlike the flat <code>node_modules</code> created by npm v3,4,5,6 or Yarn v1.</p><p>Now let's look into the real location of <code>express</code>:</p><div class="language-text codeBlockContainer_PfM4 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_sVD5"><pre tabindex="0" class="prism-code language-text codeBlock_IFdB thin-scrollbar"><code class="codeBlockLines__UdX"><span class="token-line" style="color:#393A34"><span class="token plain">  ▾ express</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    ▸ lib</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      History.md</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      index.js</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      LICENSE</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      package.json</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      Readme.md</span><br></span></code></pre><div class="buttonGroup_W9z0"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_U9Tg" aria-hidden="true"><svg class="copyButtonIcon_jN4X" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_ajRE" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Is it a scam? It still lacks <code>node_modules</code>! The second trick of pnpm's <code>node_modules</code> structure is that the dependencies of packages are on the same directory level on which the real location of the dependent package. So dependencies of <code>express</code> are not in <code>.pnpm/express@4.17.1/node_modules/express/node_modules/</code> but in <a href="https://github.com/zkochan/comparing-node-modules/tree/master/pnpm5-example/node_modules/.pnpm/express@4.17.1/node_modules" target="_blank" rel="noopener noreferrer">.pnpm/express@4.17.1/node_modules/</a>:</p><div class="language-text codeBlockContainer_PfM4 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_sVD5"><pre tabindex="0" class="prism-code language-text codeBlock_IFdB thin-scrollbar"><code class="codeBlockLines__UdX"><span class="token-line" style="color:#393A34"><span class="token plain">▾ node_modules</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  ▾ .pnpm</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    ▸ accepts@1.3.5</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    ▸ array-flatten@1.1.1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    ...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    ▾ express@4.16.3</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      ▾ node_modules</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ▸ accepts</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ▸ array-flatten</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ▸ body-parser</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ▸ content-disposition</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ▸ etag</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ▾ express</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          ▸ lib</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            History.md</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            index.js</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            LICENSE</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            package.json</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            Readme.md</span><br></span></code></pre><div class="buttonGroup_W9z0"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_U9Tg" aria-hidden="true"><svg class="copyButtonIcon_jN4X" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_ajRE" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>All the dependencies of <code>express</code> are symlinks to appropriate directories in <code>node_modules/.pnpm/</code>. Placing dependencies of <code>express</code> one level up allows avoiding circular symlinks.</p><p>So as you can see, even though pnpm's <code>node_modules</code> structure seems unusual at first:</p><ol><li>it is completely Node.js compatible</li><li>packages are nicely grouped with their dependencies</li></ol><p>The structure is a little bit <a href="/pnpm/ru/how-peers-are-resolved">more complex</a> for packages with peer dependencies but the idea is the same: using symlinks to create a nesting with a flat directory structure.</p>]]></content>
        <author>
            <name>Zoltan Kochan</name>
            <uri>http://twitter.com/zoltankochan</uri>
        </author>
    </entry>
</feed>