diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml index 0991e9d..05aef6b 100644 --- a/.github/workflows/build-dev.yml +++ b/.github/workflows/build-dev.yml @@ -34,10 +34,13 @@ jobs: with: node-version: '18' + - name: Setup pnpm + uses: pnpm/action-setup@v6 + with: + version: 9 + - name: Install dependencies - run: | - npm install -g pnpm - pnpm install --frozen-lockfile + run: pnpm install --frozen-lockfile - name: Build for ${{ matrix.platform }} run: | diff --git a/package.json b/package.json index d5da862..671eb19 100644 --- a/package.json +++ b/package.json @@ -11,9 +11,9 @@ "prepare": "husky install", "docs:format": "node scripts/format-docs.js", "docs:check": "node scripts/format-docs.js --check", - "pkgwin": "node node_modules/pkg/lib-es5/bin.js . -t node18-win-x64 -C GZip -o precompiled/app", - "pkglinux": "node node_modules/pkg/lib-es5/bin.js . -t node18-linux-x64 -C GZip -o precompiled/app", - "pkgmacos": "node node_modules/pkg/lib-es5/bin.js . -t node18-macos-x64 -C GZip -o precompiled/app" + "pkgwin": "node scripts/build-pkg.js . -t node18-win-x64 -C GZip -o precompiled/app", + "pkglinux": "node scripts/build-pkg.js . -t node18-linux-x64 -C GZip -o precompiled/app", + "pkgmacos": "node scripts/build-pkg.js . -t node18-macos-x64 -C GZip -o precompiled/app" }, "bin": "./app.js", "pkg": { diff --git a/scripts/build-pkg.js b/scripts/build-pkg.js new file mode 100644 index 0000000..90af314 --- /dev/null +++ b/scripts/build-pkg.js @@ -0,0 +1,51 @@ +/** + * Invoke the pkg packager (cross-platform, independent of node_modules layout). + * + * Background: on Windows, pnpm links node_modules/pkg to + * node_modules/.pnpm/pkg@/node_modules/pkg via a junction. Some CI + * environments (pnpm 11 + Windows runner) may fail to create that link, + * so executing node_modules/pkg/lib-es5/bin.js directly throws + * MODULE_NOT_FOUND. + * + * This script first resolves pkg via require.resolve and falls back to + * scanning the .pnpm physical directory, so pkg is found whether the + * junction exists or not. + */ +const { spawnSync } = require('child_process') +const fs = require('fs') +const path = require('path') + +function resolvePkgBin() { + try { + return require.resolve('pkg/lib-es5/bin.js') + } catch (err) { + // require.resolve failed (e.g. missing node_modules/pkg link): scan .pnpm + const pnpmDir = path.join(process.cwd(), 'node_modules', '.pnpm') + if (fs.existsSync(pnpmDir)) { + const candidates = fs + .readdirSync(pnpmDir) + .filter((dir) => dir.startsWith('pkg@')) + .map((dir) => + path.join(pnpmDir, dir, 'node_modules', 'pkg', 'lib-es5', 'bin.js'), + ) + .filter((file) => fs.existsSync(file)) + if (candidates.length) { + return candidates[0] + } + } + return null + } +} + +const bin = resolvePkgBin() +if (!bin) { + console.error( + '[build-pkg] pkg executable not found; run `pnpm install --frozen-lockfile` first', + ) + process.exit(1) +} + +const result = spawnSync(process.execPath, [bin, ...process.argv.slice(2)], { + stdio: 'inherit', +}) +process.exit(result.status === null ? 1 : result.status)