node_modulesのjunctionはmklinkよりPowerShell New-Itemで作る
OneDrive配下のNode.jsプロジェクトで node_modules を外へ逃がすとき、よく出てくるのが mklink /J です。
ただし、スクリプト化するなら mklink よりPowerShellの New-Item -ItemType Junction を使うほうが安全です。
特にWindowsでは、パスに日本語、空白、ローカライズされたフォルダ名が入ることがあります。このとき cmd.exe 経由の mklink は、PowerShellとの境界で引用符や文字コードの問題を起こしやすくなります。
mklinkの問題
mklink はPowerShellのコマンドではなく、cmd.exe の組み込みコマンドです。
PowerShellから呼ぶと、こうなります。
cmd.exe /c "mklink /J `"$JunctionPath`" `"$TargetPath`""
この時点で、PowerShellの文字列、cmd.exeの解釈、引用符、エスケープが絡みます。パスに日本語が入ると、存在するはずのパスが壊れて渡り、The system cannot find the path specified のようなエラーになることがあります。
New-Itemを使う
PowerShellにはjunctionを作るためのcmdletがあります。
New-Item -ItemType Junction -Path $JunctionPath -Target $TargetPath
PowerShellの文字列をそのまま扱えるため、cmd.exe を挟むより安定します。スクリプトにするならこちらを標準にしたほうがよいです。
繰り返し実行できる形にする
実用では、junction作成を一度だけ実行するのではなく、何度実行しても壊れないscriptにします。
$ErrorActionPreference = "Stop"
$ProjectRoot = Split-Path -Parent $PSScriptRoot
$JunctionPath = Join-Path $ProjectRoot "node_modules"
$TargetPath = "<external-store>\my-project\node_modules"
New-Item -ItemType Directory -Path $TargetPath -Force | Out-Null
if (Test-Path $JunctionPath) {
$item = Get-Item $JunctionPath -Force
if ($item.LinkType -eq "Junction" -and $item.Target -eq $TargetPath) {
Write-Host "node_modules junction already correct"
exit 0
}
Remove-Item $JunctionPath -Recurse -Force
}
New-Item -ItemType Junction -Path $JunctionPath -Target $TargetPath | Out-Null
Write-Host "node_modules junction created"
このscriptは、junctionが正しければ何もしません。違う場所を指していたり、普通のフォルダになっていたりすれば作り直します。
npm scriptに組み込む
predev や prebuild に入れておくと、開発やbuild前に自動確認できます。
{
"scripts": {
"predev": "powershell.exe -NoProfile -ExecutionPolicy Bypass -File scripts\\ensure-node-modules.ps1",
"prebuild": "powershell.exe -NoProfile -ExecutionPolicy Bypass -File scripts\\ensure-node-modules.ps1"
}
}
npm installがjunctionを普通のフォルダに置き換えることがあるため、毎回確認する価値があります。
まとめ
Windowsで node_modules junctionをスクリプト作成するなら、mklink /J より New-Item -ItemType Junction を優先してください。
理由は単純です。PowerShellの中で完結し、引用符と文字コードの事故が減るからです。特に日本語パスやOneDrive配下では、この差がそのまま安定性に出ます。