TR kizaki Tech Memo

Adjusting .yarnrc.yml ensure to compatibility with pnpm

.yarnrc.yml nodeLinkerをnode_moduleからpnpmに変更

Starting from Yarn 3.1, you can try out symlink-based installs by adding the following setting to your .yarnrc.yml file:

Yarn では v3.1 から pnpm リンカが追加され、これによって Yarn でも pnpm が作成するのと同じようなシンボリックリンクによる構造を持つ node_modules ディレクトリが作成できるようになった。

npm でも pnpm から触発されて isolated mode  と呼ばれるシンボリックリンクによる node_modules ディレクトリを作れるように現在取り組んでいるとのこと。これまでの node_modules ディレクトリの作成方法は hoisted-modeと呼ばれるようになった。ただし、複数のプロジェクト間でまたがる依存関係の重複排除については行わない予定とのこと。

ref: npm-about-dependencsies

後発のパッケージマネージャーである pnpm ではパッケージの管理を厳格に行うことでこの Phantom dependencies の問題をベースから解決している。pnpm と言う名前は「performant npm」に由来します。

ref: pnpm-feature

• 他のツールと比較して最大 2 倍高速
• ディスク容量を効率化
• 厳格なパッケージ管理で、package.json に記載のあるものにしかアクセスできない

pnpm が他のパッケージマネージャーよりもよくパフォーマンスを発揮しているのかというと、pnpm はインストールステージごとにブロッキングが発生しないという理由が述べられています。 パッケージをインストールするには「Resolving」「Fetching」「Writing」それぞれのステージが存在します。下記の画像が示すように、従来のパッケージマネージャーは、各パッケージが次のステージを開始するためには現在のステージの完了を待つ必要があります。

pnpm でnpm/yarn - 不足点解決法 • フラットのnode_modules構造は、引用していない任意のパッケージにもアクセスできてしまう。
• 違うプロジェクトのパッケージが共有できなくて、ディスク容量消耗になる。 • インストールのスピードが遅い、node_modulesに重複のインストールがある。
⇒ シンボリックリンクを用い独自のnode_modules構造を使用して、package.jsonにあるものしかアクセスできなくする(厳格)。

npx npkill これ怖いわー 現在フォルダ配下で全てのnode_modulesをスキャンして、動的で削除できる

  1. package.jsonに書いていないパッケージでもアクセスできる(Phantom・幻影)。
  2. node_modulesインストールの不確定性(Doppelgangers・自分自身の姿を自分で見る幻覚
  3. flat node_modulesアルゴリズム自体が複雑で、時間かかる。

pnpm.lock.yamlのfileを常にprojectに落とし込んでいけばいいのかな pnpm.lock.yamlのfileだけめっちゃ作り込んで。package.jsonにもmoduleのinstall反映されちゃうんだが、どのmoduleを使えばいいのか理解してdescribeしておく必要があるよね。 package.jsonのdefaultは大容量データになるのは変わらないのかな. 自分で必要のないものはproject毎に削っていくスタイルでいいかな?parentのpackage.jsonがっつり作り込むかぁ

実践的にnpm installでyarn.lockから条件引っ張ってきたnode_moduleから完成したpackage-lock.jsonから不要なdependencyをpick upして整理

parent Package.jsonの反映元設定のpackageManagerをyarn@3.2.0にしているから、

• npm 7を利用しているとき ◦ lockfileVersion が 1 のときに npm install をすると警告が出る。そして lockfileVersion が 2 に変更される ◦ lockfileVersion が 2 のときに npm install をしても問題はない

適用されるlockfileVersionとnpmの関係 調べてみたところ、lockfileVersionはv3まであるらしいが、これはv1との後方互換性がないものらしいので、利用するとしてもv2までにとどめておいたほうが良さそう。

• v1: npm v5 および v6 で使用されるpackage-lock.jsonのバージョン
• v2: npm v7(v8もこれ) で使用されているpackage-lock.jsonで、v1 のロックファイルとの後方互換性がある

• v3: npm v7(v8もこれ) で使用されるロックファイルのバージョンで、後方互換性はない。

lockfileVersion 2 の package-json.lock では、パッケージツリーを構築するための全ての情報が揃っているので、この問題を解消することができます。 package-json.lock と yarn.lock が共存するプロジェクトの場合、$ npm install や $ yarn add などで追加・更新・削除されたパッケージの情報はどちらのファイルにも自動で共有されます。

yarn init -y の-yってyesなんだな

最近はpnpm install からのpnpm startでprojectやってますね

~~voltaがpnpmやnpmのlatestのinstallに対応しなくなった。 pnpm re-install 2023.09.19~~

まずvoltaからpnpmのdataを全てdelete pnpmは別で管理するHomeのpackage.jsonのpackage managerを変更したい

/.yarnrc.yml

defaultSemverRangePrefix: ""

nodeLinker: pnpm

plugins:
  - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
    spec: "@yarnpkg/plugin-interactive-tools"
  - path: .yarn/plugins/@yarnpkg/plugin-production-install.cjs
    spec: "https://gitlab.com/Larry1123/yarn-contrib/-/raw/master/packages/plugin-production-install/bundles/@yarnpkg/plugin-production-install.js"
  - path: .yarn/plugins/@yarnpkg/plugin-typescript.cjs
    spec: "@yarnpkg/plugin-typescript"

yarnPath: .yarn/releases/yarn-3.2.0.cjs
  • .yarnrc.ymlのnodelinkerのsettingは一行でお願いします エラーになる。笑

➜  ~ git:(main) ✗ yarn --version
YAMLException: duplicated mapping key at line 4, column 1:
    nodeLinker: pnpm
    ^
    at generateError (/usr/local/lib/node_modules/yarn/lib/cli.js:126015:10)
    at throwError (/usr/local/lib/node_modules/yarn/lib/cli.js:126021:9)
    at storeMappingPair (/usr/local/lib/node_modules/yarn/lib/cli.js:126183:7)
    at readBlockMapping (/usr/local/lib/node_modules/yarn/lib/cli.js:126946:9)
    at composeNode (/usr/local/lib/node_modules/yarn/lib/cli.js:127207:12)
    at readDocument (/usr/local/lib/node_modules/yarn/lib/cli.js:127367:3)
    at loadDocuments (/usr/local/lib/node_modules/yarn/lib/cli.js:127423:5)
    at load (/usr/local/lib/node_modules/yarn/lib/cli.js:127444:19)
    at safeLoad (/usr/local/lib/node_modules/yarn/lib/cli.js:127466:10)
    at parse (/usr/local/lib/node_modules/yarn/lib/cli.js:64590:18)

pnpmのinstall

~ git:(main) ✗ curl -fsSL https://get.pnpm.io/install.sh | sh -
==> Extracting pnpm binaries 7.20.0
Copying pnpm CLI from /private/var/folders/7c/xsq3zg0d4ybdxd8qvb6wgypw0000gn/T/tmp.gUoIQl3w/pnpm to /Users/$HOME/Library/pnpm/pnpm
Appended new lines to /Users/$HOME/.zshrc

Next configuration changes were made:
export PNPM_HOME="/Users/$HOME/Library/pnpm"
export PATH="$PNPM_HOME:$PATH"

To start using pnpm, run:
source /Users/$HOME/.zshrc

.npmrcのupdate

strict-peer-dependencies オプションは false にします。これをしないと node モジュールインストール時に peer deps 関連のエラーメッセージが大量に表示されるのに加え[1]、Renovate によるモジュールアップデートが失敗してしまいます。

ref: pnpm で monorepo プロジェクトを構築する

//registry.npmjs.org/:_authToken=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
engine-strict=true
strict-peer-dependencies=false
  • pnpm i expressを試しに実行
git:(main) ✗ pnpm i express
 WARN  Moving @openzeppelin/contracts that was installed by a different package manager to "node_modules/.ignored
 WARN  Moving @parcel/transformer-sass that was installed by a different package manager to "node_modules/.ignored
 WARN  Moving aos that was installed by a different package manager to "node_modules/.ignored
 WARN  Moving axios that was installed by a different package manager to "node_modules/.ignored
 WARN  Moving parcel that was installed by a different package manager to "node_modules/.ignored
 WARN  3 other warnings
Downloading registry.npmjs.org/solc/0.8.17: 6.04 MB/6.04 MB, done
 WARN  deprecated uuid@3.3.2: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
 WARN  deprecated mkdirp-promise@5.0.1: This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that.8.5 MB
 WARN  deprecated cids@0.7.5: This module has been superseded by the multiformats moduleing registry.npmjs.org/@parcel/transformer-js/2.8.2: 6.95 MB/48.5 MB
 WARN  deprecated multicodec@0.5.7: This module has been superseded by the multiformats modulegistry.npmjs.org/@parcel/transformer-js/2.8.2: 7.23 MB/48.5 MB
 WARN  deprecated stable@0.1.8: Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility
 WARN  deprecated multicodec@1.0.4: This module has been superseded by the multiformats modulegistry.npmjs.org/@parcel/transformer-js/2.8.2: 14.4 MB/48.5 MB
 WARN  deprecated multibase@0.6.1: This module has been superseded by the multiformats moduleegistry.npmjs.org/@parcel/transformer-js/2.8.2: 14.9 MB/48.5 MB
 WARN  deprecated multibase@0.7.0: This module has been superseded by the multiformats moduleegistry.npmjs.org/@parcel/transformer-js/2.8.2: 14.9 MB/48.5 MB
 WARN  deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142arcel/transformer-js/2.8.2: 17.7 MB/48.5 MB
 WARN  deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
 WARN  deprecated har-validator@5.1.5: this library is no longer supported
Packages: +539
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Packages are hard linked from the content-addressable store to the virtual store.ownloading registry.npmjs.org/@parcel/transformer-js/2.8.2: 27.8 MB/48.5 MB
  Content-addressable store is at: /Users/$HOME/Library/pnpm/store/v3
  Virtual store is at:             node_modules/.pnpm
Downloading registry.npmjs.org/@parcel/transformer-js/2.8.2: 48.5 MB/48.5 MB, donewnloading registry.npmjs.org/@parcel/transformer-js/2.8.2: 48.5 MB/48.5 MB
node_modules/.pnpm/es5-ext@0.10.62/node_modules/es5-ext: Running postinstall script...
node_modules/.pnpm/bufferutil@4.0.7/node_modules/bufferutil: Running install script...
node_modules/.pnpm/es5-ext@0.10.62/node_modules/es5-ext: Running postinstall script, done in 185ms
node_modules/.pnpm/bufferutil@4.0.7/node_modules/bufferutil: Running install script, done in 1.9sm/keccak@3.0.2/node_modules/keccak: Running install script...
node_modules/.pnpm/secp256k1@4.0.3/node_modules/secp256k1: Running install scripnode_modules/.pnpm/@parcel+watcher@2.0.7/node_modules/@parcel/watcher: Running install script, done in 2.2slidate@5.0.10/node_modules/utf-8-validate: Running innode_modules/.pnpm/keccak@3.0.2/node_modules/keccak: Running install script, donnode_modules/.pnpm/secp256k1@4.0.3/node_modules/secp256k1: Running install scripnode_modules/.pnpm/utf-8-validate@5.0.10/node_modules/utf-8-validate: Running install script, done in 2.3s
node_modules/.pnpm/msgpackr-extract@2.2.0/node_modules/msgpackr-extract: Runningnode_modules/.pnpm/msgpackr-extract@2.2.0/node_modules/msgpackr-extract: Running install script, done in 800ms
node_modules/.pnpm/lmdb@2.5.2/node_modules/lmdb: Running install script, done in 498ms
node_modules/.pnpm/web3-shh@1.8.0/node_modules/web3-shh: Running postinstall scrnode_modules/.pnpm/web3-shh@1.8.0/node_modules/web3-shh: Running postinstall script, done in 11ms
node_modules/.pnpm/web3@1.8.0/node_modules/web3: Running postinstall script, done in 16ms

dependencies:
+ @openzeppelin/contracts 4.8.0
+ @parcel/transformer-sass 2.8.2
+ aos 2.3.4
+ axios 1.2.1
+ express 4.18.2
+ parcel 2.8.2
+ solc 0.8.17
+ tachyons 4.12.0
+ web3 1.8.0 (1.8.1 is available)

 WARN  Issues with peer dependencies found
.
└─┬ @parcel/transformer-sass 2.8.2
  └─┬ @parcel/plugin 2.8.2
    └─┬ @parcel/types 2.8.2
      └─┬ @parcel/cache 2.8.2
        ├── ✕ missing peer @parcel/core@^2.8.2
        └─┬ @parcel/fs 2.8.2
          ├── ✕ missing peer @parcel/core@^2.8.2
          └─┬ @parcel/types 2.8.2
            └─┬ @parcel/package-manager 2.8.2
              ├── ✕ missing peer @parcel/core@^2.8.2
              └─┬ @parcel/fs 2.8.2
                ├── ✕ missing peer @parcel/core@^2.8.2
                └─┬ @parcel/workers 2.8.2
                  └── ✕ missing peer @parcel/core@^2.8.2
Peer dependencies that should be installed:
  @parcel/core@">=2.8.2 <3.0.0"  

Done in 34.2s

projectごとにpackage.jsonに以下のフィールドを追記し .npmrcファイルの作成・設定をすることで、 npmyarnなど pnpm以外のコマンド利用を禁止できます。

{
  "name": "my-project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  {
+  "engines": {
+   "pnpm": "7.20.0",
+   "npm": "please_use_pnpm_instead"
+ },
+   "packageManager": "pnpm@7.20.0"
+ },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
  • $HOMEのpackage.json思いっきり変えてみたぜ!
{
    {
     "engines": {
      "pnpm": "7.20.0",
      "npm": "please_use_pnpm_instead"
     },
      "packageManager": "pnpm@7.20.0"
    },
  "dependencies": {
    "@openzeppelin/contracts": "^4.7.3",
    "@parcel/transformer-sass": "^2.7.0",
    "aos": "^2.3.4",
    "axios": "^1.1.3",
    "babel": "^6.23.0",
    "express": "^4.18.2",
    "parcel": "^2.7.0",
    "solc": "^0.8.17",
    "tachyons": "^4.12.0",
    "web3": "1.8.0"
  },
  "volta": {
    "node": "19.3.0",
    "yarn": "3.2.0",
    "npm": "9.2.0"
  }
}

なんかnode -vとかyarn -vとか何もできなくなってcorepack enableもできないからもとに戻した…pnpmはso strict!!

{
  "packageManager": "yarn@3.2.0",
  "dependencies": {
    "@openzeppelin/contracts": "^4.7.3",
    "@parcel/transformer-sass": "^2.7.0",
    "aos": "^2.3.4",
    "axios": "^1.1.3",
    "babel": "^6.23.0",
    "express": "^4.18.2",
    "parcel": "^2.7.0",
    "solc": "^0.8.17",
    "tachyons": "^4.12.0",
    "web3": "1.8.0"
  },
  "volta": {
    "node": "19.3.0",
    "yarn": "3.2.0",
    "npm": "9.2.0"
  }
}

実験でbabel更新。pnpmでnode_moduleをシンボリックリンク化しまくるのだ

➜  ~ git:(main) ✗ pnpm i babel
 WARN  deprecated babel@6.23.0: In 6.x, the babel package has been deprecated in favor of babel-cli. Check https://opencollective.com/babel to support the Babel maintainers
 WARN  deprecated mkdirp-promise@5.0.1: This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that.
 WARN  deprecated uuid@3.3.2: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
 WARN  deprecated stable@0.1.8: Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility
 WARN  deprecated multicodec@0.5.7: This module has been superseded by the multiformats module
 WARN  deprecated cids@0.7.5: This module has been superseded by the multiformats module
 WARN  deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
 WARN  deprecated multibase@0.6.1: This module has been superseded by the multiformats module
 WARN  deprecated multicodec@1.0.4: This module has been superseded by the multiformats module
 WARN  deprecated multibase@0.7.0: This module has been superseded by the multiformats module
 WARN  deprecated har-validator@5.1.5: this library is no longer supported
 WARN  deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
Packages: +540
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Packages are hard linked from the content-addressable store to the virtual store.
  Content-addressable store is at: /Users/$HOME/Library/pnpm/store/v3
  Virtual store is at:             node_modules/.pnpm
Progress: resolved 553, reused 536, downloaded 0, added 1, done
node_modules/.pnpm/msgpackr-extract@2.2.0/node_modules/msgpackr-extract: Runningnode_modules/.pnpm/msgpackr-extract@2.2.0/node_modules/msgpackr-extract: Running install script, done in 710ms
node_modules/.pnpm/lmdb@2.5.2/node_modules/lmdb: Running install script, done in 512ms

dependencies:
+ babel ^6.23.0

 WARN  Issues with peer dependencies found
.
└─┬ @parcel/transformer-sass 2.8.2
  └─┬ @parcel/plugin 2.8.2
    └─┬ @parcel/types 2.8.2
      └─┬ @parcel/cache 2.8.2
        ├── ✕ missing peer @parcel/core@^2.8.2
        └─┬ @parcel/fs 2.8.2
          ├── ✕ missing peer @parcel/core@^2.8.2
          └─┬ @parcel/types 2.8.2
            └─┬ @parcel/package-manager 2.8.2
              ├── ✕ missing peer @parcel/core@^2.8.2
              └─┬ @parcel/fs 2.8.2
                ├── ✕ missing peer @parcel/core@^2.8.2
                └─┬ @parcel/workers 2.8.2
                  └── ✕ missing peer @parcel/core@^2.8.2
Peer dependencies that should be installed:
  @parcel/core@">=2.8.2 <3.0.0"  

Done in 4.5s

ref: pnpmの速度比較graph

.npmrc

//registry.npmjs.org/:_authToken=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
engine-strict=true
strict-peer-dependencies=false

これだとyarn installできない


~~voltaがpnpmやnpmのlatestのinstallに対応しなくなった。 pnpm re-install 2023.09.19~~

まずvoltaからpnpmのdataを全てdelete

pnpmは別で管理する

└─(11:13:26 on main ✖ ✹ ✭)──> curl -fsSL https://get.pnpm.io/install.sh | sh -
==> Downloading pnpm binaries 8.7.6
 WARN  using --force I sure hope you know what you are doing
Copying pnpm CLI from /private/var/folders/7c/xsq3zg0d4ybdxd8qvb6wgypw0000gn/T/tmp.HEeVK29y/pnpm to /Users/$HOME/Library/pnpm/pnpm
Replaced configuration in /Users/$HOME/.zshrc

Next configuration changes were made:
export PNPM_HOME="/Users/$HOME/Library/pnpm"
case ":$PATH:" in
  *":$PNPM_HOME:"*) ;;
  *) export PATH="$PNPM_HOME:$PATH" ;;
esac

To start using pnpm, run:
source /Users/$HOME/.zshrc
└─(12:33:36 on main ✖ ✹ ✭)──> source ~/.zshrc
(12:34:34 on main ✖ ✹ ✭)──> exec $SHELL -l
└─(12:36:23 on main ✖ ✹ ✭)──> volta setup                 130 ↵ ──(Tue,Sep19)─┘
success: Setup complete. Open a new terminal to start using Volta!
└─(12:36:46 on main ✖ ✹ ✭)──> 
which pnpm                        ──(Tue,Sep19)─┘
/Users/$HOME/.volta/bin/pnpm

pathが記載してあるzshrcの位置の変更後、最新のpnpmにupdateできた

└─(12:37:04 on main ✖ ✹ ✭)──>
 pnpm -v                           ──(Tue,Sep19)─┘
8.7.6

残っていたバイナリファイル.volta/bin/pnpmをdelete後にやっとwhichに反映

└─(14:43:59 on main ✖ ✹ ✭)──> 
which pnpm                        ──(Tue,Sep19)─┘
/usr/local/bin/pnpm

Homeのpackage.jsonのpackage managerを変更したい