1.

npm ERR! path %RESOURCE_DIR%/package.json の原因と対処(IDE / cross-env)

編集
この記事の要点
  • npm 実行時に リテラル %RESOURCE_DIR% が解決されず、そのパスを探しに行って ENOENT になるエラー
  • 原因: package.json の scripts に Windows 環境変数記法(%VAR%)が混入、または IDE(IntelliJ / WebStorm 等)の Run Configuration が変数を展開しないまま渡している
  • クロスプラットフォーム対応の欠如も典型例。Linux/Mac は $VAR、Windows は %VAR% と書式が違う
  • 対処: cross-env パッケージで OS 差吸収、または scripts を Node スクリプト経由に書き換える
  • IDE 側は Run Configuration の Working directory / Environment variables を見直す

このエラーの概要

npm スクリプト実行時に次のようなエラーが表示されます:

npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path C:\Users\xxx\~\%RESOURCE_DIR%\package.json
npm ERR! errno -4058
npm ERR! enoent ENOENT: no such file or directory, open 'C:\...\%RESOURCE_DIR%\package.json'
npm ERR! enoent This is related to npm not being able to find a file.

注目すべきは パスに %RESOURCE_DIR% がそのまま残っている点です。本来であれば実際のディレクトリ(例: C:\Users\xxx\workspace\myapp)に展開されているはずが、文字列のまま渡されていることを意味します。

原因 1: package.json の scripts に環境変数記法

もっとも多いのが、Windows 用の %VAR% を Linux / macOS で実行しているケース、またはその逆です:

{
  "scripts": {
    "build": "webpack --config %RESOURCE_DIR%/webpack.config.js",
    "test": "NODE_ENV=test jest"
  }
}

npm の scripts は OS のシェルでそのまま実行されます:

  • Windows (cmd.exe): %VAR% 展開、$VAR は文字列のまま
  • Linux / macOS (sh): $VAR 展開、%VAR% は文字列のまま

つまり、%RESOURCE_DIR% を Linux 系で動かしたり、%RESOURCE_DIR%そもそも定義されていない と未展開のまま渡ります。

原因 2: IDE の Run Configuration

IntelliJ IDEA / WebStorm / Android Studio の「npm Run Configuration」で、Working directoryArguments%RESOURCE_DIR% のような IDE マクロを書いたが、対応するマクロが未定義 / 別 IDE のマクロ、というケース:

  • Android Studio: $ModuleFileDir$ / $ProjectFileDir$ 等が正しい
  • VSCode: ${workspaceFolder} / ${fileDirname}
  • %RESOURCE_DIR% は Android Studio Profile / 一部プラグインのマクロで、別コンテキストでは未定義

対処 1: cross-env でクロスプラットフォーム化

OS による環境変数記法の違いを吸収する定番が cross-env です:

npm install --save-dev cross-env
{
  "scripts": {
    "build:dev": "cross-env NODE_ENV=development webpack",
    "build:prod": "cross-env NODE_ENV=production webpack",
    "test": "cross-env NODE_ENV=test jest"
  }
}

cross-env を介すと、NODE_ENV=... 記法が Windows でもそのまま動きます。

対処 2: パス系は Node スクリプト経由に

パスを動的に組み立てる場合は、シェル変数に頼らず Node でやるほうが安全:

// scripts/build.js
const path = require('path');
const { execSync } = require('child_process');

const resourceDir = path.resolve(__dirname, '..', 'resources');
process.env.RESOURCE_DIR = resourceDir;

execSync(`webpack --config ${resourceDir}/webpack.config.js`, {
  stdio: 'inherit',
  env: process.env,
});
{
  "scripts": {
    "build": "node scripts/build.js"
  }
}

対処 3: IDE の Run Configuration を見直す

  1. Run → Edit Configurations を開く
  2. npm の Run Configuration を選択
  3. Working directory を絶対パスまたは正しい IDE マクロ($ProjectFileDir$ 等)に変更
  4. Environment variables に RESOURCE_DIR=... を必要なら設定
  5. Apply → Run

対処 4: シェル側で事前に export

CI / シェルスクリプト経由なら、npm 実行前に環境変数を出してしまう手もあります:

# Linux / macOS
export RESOURCE_DIR=$(pwd)/resources
npm run build

# Windows cmd
set RESOURCE_DIR=%CD%\resources
npm run build

# Windows PowerShell
$env:RESOURCE_DIR = "$PWD\resources"
npm run build

原因の確認コマンド

# package.json の scripts を確認
cat package.json | jq .scripts

# 現在の環境変数に RESOURCE_DIR があるか
echo $RESOURCE_DIR         # Linux/Mac
echo %RESOURCE_DIR%        # Windows cmd
$env:RESOURCE_DIR          # PowerShell

# npm の verbose ログ
npm run build --loglevel verbose

# 実際にどのコマンドが走るか
npm run build --dry-run    # 一部の npm version で

関連エラー

エラー原因
'NODE_ENV' is not recognizedWindows で NODE_ENV=x 記法 → cross-env で解決
ENOENT: no such file or directoryパス未展開 / 存在しないパス指定
$VAR is not definedWindows で $VAR 記法 → %VAR% または cross-env

FAQ

Q: cross-env を導入したくない
A: scripts を全部 Node スクリプト経由(node scripts/xxx.js)にすれば cross-env なしで OS 差を吸収できます。Node の process.env はクロスプラットフォームです。

Q: モノレポで子パッケージから親の RESOURCE_DIR を参照したい
A: npm-run-allturbo で親から子を呼ぶときに --scope 経由で渡す、もしくは process.env を Node で組み立てる方が確実です。

Q: なぜ %RESOURCE_DIR% がパスに混入する?
A: scripts 文字列内の未展開リテラルを npm がそのまま現在ディレクトリのサブパスとして解釈し、ENOENT に到達するためです。

編集
Post Share
子ページ

子ページはありません

同階層のページ

同階層のページはありません