透過 npx 在呼叫套件時省略 node_modules/.bin 前綴

總結

在把專案 package.json 中的 scripts 內容都移植到 Makefile 時,發現在 make 腳本中如果省略 npxyarn 的話,就無法執行套件,修正完腳本後查了一下 npx 到底做了哪些事情,這篇筆記基本上就是圍繞在這個主題上。

筆記

什麼是 npx

可透過 npx <package-name> 來執行套件。如果該套件沒有被安裝,則先進行安裝、再啟動套件。功能與 npm run <command>npm run-script <command>)相同。

npm blog: Have you ever run into a situation where you want to try some CLI tool, but it’s annoying to have to install a global just to run it once? npx is great for that, too. Calling npx <command> when <command> isn’t already in your $PATH will automatically install a package with that name from the npm registry for you, and invoke it.

npm official doc: npx allows you to run an arbitrary command from an npm package (either one installed locally, or fetched remotely), in a similar context as running it via npm run.

# https://docs.npmjs.com/cli/v8/commands/npm-run-script#synopsis

npm run-script <command> [-- <args>]
# aliases: run, rum, urn

而當透過 npm run <command> 執行腳本時,npm run 會幫忙加上路徑前綴 node_modules/.bin

npm official doc: In addition to the shell’s pre-existing PATH, npm run adds node_modules/.bin to the PATH provided to scripts. Any binaries provided by locally-installed dependencies can be used without the node_modules/.bin prefix.

node_modules 中的 .bin 資料夾

能透過 npm run <command> 執行的內容都會放在這裡:

npm official doc: When in local mode, executables are linked into ./node_modules/.bin so that they can be made available to scripts run through npm. (For example, so that a test runner will be in the path when you run npm test.)

stackOverFlow: As for the .bin, this directory stores all the executables of your node_modules for which your project is dependent upon to run. This allows your project to just ‘run’ the libraries which are necessary, for your project, without you having to worry about compiling these files yourself.

實際運用

總結:在 Makefile 中,如果想要在終端直接執行某些套件(比如 webpacknext),需透過 npx <package-name> 或手動連結到 node_modules/.bin 來呼叫。

以下列出的三種寫法都能執行 next dev 功能:

.PHONY: dev
dev:
	node node_modules/.bin/next dev
.PHONY: dev
dev:
	npx next dev
.PHONY: dev
dev:
  # this is equivalent to `yarn run next dev`, see https://yarnpkg.com/cli/run#examples
  yarn next dev

參考文件