Closed10

Windows 環境にて yarn だと WSL 内の node が使われてしまう問題 ~script-shell の設定を忘れていた~

ピン留めされたアイテム
okathiraokathira
PS D:\my_projects\node-version-check> (get-command bash).Path 
C:\WINDOWS\system32\bash.exe
PS D:\my_projects\node-version-check> yarn config list
{
~~~略~~~
  'script-shell': 'C:\\Windows\\System32\\bash.exe'
}

Windows側のyarn configファイル %HOMEPATH%/.yarnrc も確認したところ、なぜか script-shell "C:\\Windows\\System32\\bash.exe" がここで設定されてた。これが原因ぽい。
その行を消したら治った

PS D:\my_projects\node-version-check> yarn test  
yarn run v1.22.22
$ node index.js
v20.17.0
D:\my_projects\node-version-check
C:\Users\username\AppData\Local\nvs\default\node.exe
Done in 0.22s.

(いろいろ試して結局nvsを入れてる)

なんで?

vscodeでシェルスクリプトの設定をしていたのが戻っていなかった?
前に自分で設定していたのを忘れていた
https://zenn.dev/link/comments/39474fa4bf6d22

okathiraokathira

アプリ実行エイリアスの bash.exe をオフにしてたはずなんだけど C:\\Windows\\System32\\bash.exe が消えるわけじゃないのかな

okathiraokathira

環境

  • Windows 11
  • nvm 1.1.12
  • テスト時
    • node: 20.17.0
    • npm: 10.8.2
    • yarn: 1.22.22

困ったこと

Windowsにて、npmだと問題ないがyarnだと謎のバージョンが実行されてしまう。

内部でnodeを実行しているnpmパッケージをyarnで利用しようとすると、nodeのバージョンが古いことに起因するエラーが出てしまった。しかしそのエラメッセージで古いと言われたバージョンはそもそも入れている認識がない。

再現

再現環境

適当なフォルダを用意する。
そこに js ファイル(ここでは index.js)を作る。中身は

// index.js
console.log(process.version);

その後 npm init を実行、そしてエンターキー連打。
package.json が生成されるので、npm script の test を編集して node index.js を実行するように。

// package.json
{
  "name": "version-check",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "node index.js"
  },
  "author": "",
  "license": "ISC",
  "description": ""
}

テスト

npm run test を実行すると、


> version-check@1.0.0 test
> node index.js

v20.17.0

しかし、yarn -v を実行すると、

yarn run v1.22.22
$ node index.js
v10.19.0
Done in 3.14s.

yarn から node を呼んだときに知らないバージョンを使ってしまっている。
nvm list で確認してもそこには存在しないバージョンだった。

okathiraokathira

v10.19.0 で調べると「Ubuntu 20.04 LTS」というワードがちょこちょこヒットする
WSLを入れているのでそれかも

Windows 環境上から wsl -l -v をして調べると

  NAME                   STATE           VERSION
* Ubuntu-20.04           Running         2
~~~略~~~

とあり、バージョンが一致していて怪しい。

okathiraokathira

process.execPath で実行されている node 自体の path を取得できるらしい。
そこで、 index.js を書き換えて確認してみる

console.log(process.version);
console.log(__dirname);
console.log(process.execPath);

すると、
npm run test


> version-check@1.0.0 test
> node index.js

v20.17.0
D:\my_projects\node-version-check
G:\nodejs\node.exe

yarn test

yarn run v1.22.22
$ node index.js
v10.19.0
/mnt/d/my_projects/node-version-check
/usr/bin/node
Done in 0.52s.

となった。

WSLのものが実行されていそう?

okathiraokathira

そもそも yarn ってどこから取ってきているんだろうということで、

PS D:\my_projects\node-version-check> (get-command node).Path       
G:\nodejs\node.exe
PS D:\my_projects\node-version-check> (get-command npm).Path 
G:\nodejs\npm.cmd
PS D:\my_projects\node-version-check> (get-command yarn).Path
G:\nodejs\yarn.ps1
PS D:\my_projects\node-version-check>

https://github.com/yarnpkg/yarn/blob/7cafa512a777048ce0b666080a24e80aae3d66a9/bin/yarn.ps1

okathiraokathira

実際に yarn.ps1 ファイルを確認したら

#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent

$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
  # Fix case when both the Windows and Linux builds of Node
  # are installed in the same directory
  $exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
  # Support pipeline input
  if ($MyInvocation.ExpectingInput) {
    $input | & "$basedir/node$exe"  "$basedir/node_modules/yarn/bin/yarn.js" $args
  } else {
    & "$basedir/node$exe"  "$basedir/node_modules/yarn/bin/yarn.js" $args
  }
  $ret=$LASTEXITCODE
} else {
  # Support pipeline input
  if ($MyInvocation.ExpectingInput) {
    $input | & "node$exe"  "$basedir/node_modules/yarn/bin/yarn.js" $args
  } else {
    & "node$exe"  "$basedir/node_modules/yarn/bin/yarn.js" $args
  }
  $ret=$LASTEXITCODE
}
exit $ret

だった

このスクラップは3ヶ月前にクローズされました