היום למדתי: משתנה הסביבה INIT_CWD ב npm

19/10/2020

טריק פשוט עם npm שבטח שמתם לב אליו הוא שאפשר להריץ כל סקריפט npm מכל תת-תיקיה של הפרויקט. באופן אוטומטי npm מחפש במעלה העץ את הקובץ package.json ויריץ את הסקריפט כאילו הרצנו אותו מהתיקיה בה נמצא ה package.json. במילים אחרות ובדוגמה, אם יש לנו את מבנה הפרויקט הבא:

.
├── foo
│   └── bar
│       └── buz
└── package.json

ובקובץ package.json התוכן הבא:

{
  "name": "npmdemo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo Running from $(realpath .)"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

אז אני יכול מתוך תיקיה פנימית בפרויקט להריץ:

 ~/tmp/npmdemo/foo/bar/buz  npm test

> npmdemo@1.0.0 test /home/ynon/tmp/npmdemo
> echo Running from $(realpath .)

Running from /home/ynon/tmp/npmdemo

והסקריפט ירוץ מהתיקיה הראשית של הפרויקט, בלי שאכפת למישהו שאני הייתי בתיקיית foo/bar/buz כשהרצתי את הפקודה.

אבל - מה אם כן אכפת לי באיזו תיקיה הייתי כשהרצתי את הפקודה? מה אם באמת יש לי מספר תתי פרויקטים בתוך אותו פרויקט, וכל פעם שאני מריץ סקריפט npm אני רוצה שהוא יתייחס לתיקיה ממנה הרצתי אותו?

בשביל זה בדיוק npm מגדיר משתנה סביבה בשם INIT_CWD שכולל את הנתיב המלא לתיקיה ממנה הרצתי את פקודת ה npm. בשביל לראות את זה אעדכן את package.json לתוכן הבא:

{
  "name": "npmdemo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo Running from $(realpath .)",
    "test-here": "cd $INIT_CWD; echo Running from $(realpath .)"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

ועכשיו בהרצה אני מקבל:

 ~/tmp/npmdemo/foo/bar/buz  npm run test

> npmdemo@1.0.0 test /home/ynon/tmp/npmdemo
> echo Running from $(realpath .)

Running from /home/ynon/tmp/npmdemo
 ~/tmp/npmdemo/foo/bar/buz  npm run test-here

> npmdemo@1.0.0 test-here /home/ynon/tmp/npmdemo
> cd $INIT_CWD; echo Running from $(realpath .)

Running from /home/ynon/tmp/npmdemo/foo/bar/buz