From c649b7891bfa9e52c459b852647201c3f240e1a4 Mon Sep 17 00:00:00 2001 From: Mason Chen Date: Thu, 4 Dec 2025 18:57:47 +0800 Subject: [PATCH 1/2] feat: add PKG_NATIVE_CACHE_PATH environment variable - Allow users to customize native addon cache directory at runtime - Default remains ~/.cache for backward compatibility - Useful for enterprise environments with restricted directories --- README.md | 33 +++++++++++++++++++++++---------- prelude/bootstrap.js | 7 +++++-- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 45999ba0..7de68fb6 100644 --- a/README.md +++ b/README.md @@ -302,21 +302,25 @@ The startup time of the application might be reduced slightly. All pkg-cache [environment vars](https://github.com/yao-pkg/pkg-fetch#environment), plus: -| Var | Description | -| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `CHDIR` | Override process `chdir` | -| `PKG_STRICT_VER` | Turn on some assertion in the walker code to assert that each file content/state that we appending to the virtual file system applies to a real file, not a symlink. | -| `PKG_EXECPATH` | Used internally by `pkg`, do not override | +| Var | Description | +| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `CHDIR` | Override process `chdir` | +| `PKG_NATIVE_CACHE_PATH` | Override the base directory for caching extracted native addons at runtime (default: `~/.cache`) | +| `PKG_STRICT_VER` | Turn on some assertion in the walker code to assert that each file content/state that we appending to the virtual file system applies to a real file, not a symlink. | +| `PKG_EXECPATH` | Used internally by `pkg`, do not override | Examples ```bash -# 1 - Using export +# 1 - Set cache path at build time (for pkg-fetch to cache Node.js binaries) export PKG_CACHE_PATH=/my/cache pkg app.js -# 2 - Passing it before the script -PKG_CACHE_PATH=/my/cache pkg app.js +# 2 - Set cache path at runtime (for packaged app to cache extracted native addons) +PKG_NATIVE_CACHE_PATH=/opt/myapp/cache ./myapp + +# 3 - Both can be used together +PKG_CACHE_PATH=/build/cache PKG_NATIVE_CACHE_PATH=/runtime/cache pkg app.js ``` ## Usage of packaged app @@ -384,8 +388,17 @@ add the `.node` file directly in the `assets` field in `package.json`. The way Node.js requires native addon is different from a classic JS file. It needs to have a file on disk to load it, but `pkg` only generates one file. To circumvent this, `pkg` will extract native addon files to -`$HOME/.cache/pkg/`. These files will stay on the disk after the process has -exited and will be used again on the next process launch. +`$HOME/.cache/pkg/` by default. These files will stay on the disk after the +process has exited and will be used again on the next process launch. + +You can customize the cache directory by setting the `PKG_NATIVE_CACHE_PATH` +environment variable. This is useful in enterprise environments where specific +directories may be restricted or monitored: + +```bash +# Set custom cache path for native addons +PKG_NATIVE_CACHE_PATH=/opt/myapp/cache ./myapp +``` When a package, that contains a native module, is being installed, the native module is compiled against current system-wide Node.js diff --git a/prelude/bootstrap.js b/prelude/bootstrap.js index 89232cfb..ba4278dc 100644 --- a/prelude/bootstrap.js +++ b/prelude/bootstrap.js @@ -2206,8 +2206,11 @@ function payloadFileSync(pointer) { // the hash is needed to be sure we reload the module in case it changes const hash = createHash('sha256').update(moduleContent).digest('hex'); - // Example: /home/john/.cache/pkg/ - const tmpFolder = path.join(homedir(), '.cache/pkg', hash); + // Allow users to override the cache directory via PKG_NATIVE_CACHE_PATH environment variable + // Example: /home/john/.cache/pkg/ or custom path like /opt/myapp/cache/pkg/ + const cacheBase = + process.env.PKG_NATIVE_CACHE_PATH || path.join(homedir(), '.cache'); + const tmpFolder = path.join(cacheBase, 'pkg', hash); fs.mkdirSync(tmpFolder, { recursive: true }); From aa42d540f60ea6ab4570f2fb18d65df50aed472e Mon Sep 17 00:00:00 2001 From: Mason Chen Date: Thu, 4 Dec 2025 19:20:55 +0800 Subject: [PATCH 2/2] Move PKG_NATIVE_CACHE_BASE outside of dlopen function --- prelude/bootstrap.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/prelude/bootstrap.js b/prelude/bootstrap.js index ba4278dc..3fee376d 100644 --- a/prelude/bootstrap.js +++ b/prelude/bootstrap.js @@ -2187,6 +2187,15 @@ function payloadFileSync(pointer) { dlopen: process.dlopen, }; + // Allow users to override the cache base directory via PKG_NATIVE_CACHE_PATH environment variable + // Default: path.join(homedir(), '.cache') + // - Linux/macOS: /home/john/.cache or /Users/john/.cache + // - Windows: C:\Users\John\.cache + // Custom example: /opt/myapp/cache or C:\myapp\cache + // Native addons will be extracted to: /pkg/ + const PKG_NATIVE_CACHE_BASE = + process.env.PKG_NATIVE_CACHE_PATH || path.join(homedir(), '.cache'); + function revertMakingLong(f) { if (/^\\\\\?\\/.test(f)) return f.slice(4); return f; @@ -2206,11 +2215,7 @@ function payloadFileSync(pointer) { // the hash is needed to be sure we reload the module in case it changes const hash = createHash('sha256').update(moduleContent).digest('hex'); - // Allow users to override the cache directory via PKG_NATIVE_CACHE_PATH environment variable - // Example: /home/john/.cache/pkg/ or custom path like /opt/myapp/cache/pkg/ - const cacheBase = - process.env.PKG_NATIVE_CACHE_PATH || path.join(homedir(), '.cache'); - const tmpFolder = path.join(cacheBase, 'pkg', hash); + const tmpFolder = path.join(PKG_NATIVE_CACHE_BASE, 'pkg', hash); fs.mkdirSync(tmpFolder, { recursive: true });