JavaScript
Node.js
js

npx で実行するか npm scripts で実行するかで glob パスの解釈が違う

自分が困ったので、備忘録として残す。

node_modules/ 内のモジュールを実行する際、対象ファイルの指定をマルチパス形式で「〜ディレクトリ配下すべて」と記述すると、npx と npm scripts で処理対象となるファイルが異なる。

(※今回はstylelintを例に説明)


事象


package.json

"scripts" : {

"stylelint": "stylelint resources/assets/sass/test/**/*.scss",
}

上記npm scriptsを用意した状態で実行する npm run stylelint

npx stylelint resources/assets/sass/test/**/*.scss で、処理対象となるファイルに違いが出た。

npx はディレクトリを再帰的に掘って走査してくれるが、npm scripts では第一階層しか探してくれない。

これを、npm scripts でも配下すべてのディレクトリを再帰的に走査するようにしたい。

※再現環境

macOS 10.14

Node.js 10.9.0

npm 6.2.0


解決方法

パスをシングルクォーテーションで囲む。

つまり、以下のように記述する。


package.json

"scripts" : {

"stylelint": "stylelint 'resources/assets/sass/test/**/*.scss'",
}


事象の再現・調査

最初にキックされるJSファイルに console.log を仕込み、実際に対象になっているファイルの規則性を確かめる。


node_modules/stylelint/bin/stylelint.js

#!/usr/bin/env node


"use strict";

console.log(process.argv); // この1行を追加

require("../lib/cli")(process.argv.slice(2));


この状態でそれぞれコマンドを叩き、結果を比較する。

↓出力結果(npm scripts)

npm run stylelint

> @ stylelint /Users/[プロジェクトディレクトリまでのフルパス]
> stylelint resources/assets/sass/test/**/*.scss

[ '/Users/[ユーザ名]/.nodebrew/node/v10.9.0/bin/node',
'/Users/[プロジェクトディレクトリまでのフルパス]/node_modules/.bin/stylelint',
'resources/assets/sass/test/pages/_style.4.scss',
'resources/assets/sass/test/settings/_style.5.scss',
'resources/assets/sass/test/settings/_style.6.scss' ]

↓出力結果(npx)

npx stylelint resources/assets/sass/test/**/*.scss

[ '/Users/[ユーザ名]/.nodebrew/node/v10.9.0/bin/node',
'/Users/[プロジェクトディレクトリまでのフルパス]/node_modules/.bin/stylelint',
'resources/assets/sass/test/_style.scss',
'resources/assets/sass/test/pages/1/_style.1.scss',
'resources/assets/sass/test/pages/2/2-1/_style.2.scss',
'resources/assets/sass/test/pages/2/_style.3.scss',
'resources/assets/sass/test/pages/_style.4.scss',
'resources/assets/sass/test/settings/_style.5.scss',
'resources/assets/sass/test/settings/_style.6.scss' ]

対象となるファイルに違いがあることが判明した。


まとめ


  • 勉強不足で Node.js の中の仕組みに詳しくなく、どうしてこうなるのかまではまだ理解できていません。。分かり次第追記したいと思います。

  • 同じJSがキックされているのに解釈が違うので、stylelint 以外のnpmモジュールでも再現します。

  • 学びとしては「npm scripts の中に書くパスはシングルクォーテーションでくくったほうが無難」という小さな内容ですが、気をつけていきたいです。