chmodnodenpmclishebangesbuildbun
Bun bundler はシェバンを除去する — ビルドスクリプトで再付与が必要
ビルド後に出力ファイルを読み取り、先頭にシェバンがなければ "#!/usr/bin/env node\n" を先頭に追加して上書き保存し、実行権限を chmod 755 で付与する。例えば、readFileSync で内容を取得し、content.startsWith('#!/') をチェックして writeFileSync でシェバンをプレフィックスし、chmodSync(outPath, 0o755) を実行する。
Problem
Bun.build() で CLI をバンドルすると、ソースファイル先頭の "#!/usr/bin/env node"(シェバン)が出力から消える。npm にパブリッシュ後、npx やグローバルコマンド(例: wt)が "permission denied" や "unknown interpreter" で失敗する。
Solution
ビルド後に出力ファイルを読み取り、先頭にシェバンがなければ "#!/usr/bin/env node\n" を先頭に追加して上書き保存し、実行権限を chmod 755 で付与する。例えば、readFileSync で内容を取得し、content.startsWith('#!/') をチェックして writeFileSync でシェバンをプレフィックスし、chmodSync(outPath, 0o755) を実行する。
Attempts
- esbuild の banner オプションでビルド時にシェバンを付ける方法(esbuild なら可能だが、Bun.build() には banner オプションがないため使えなかった)
## Problem
`Bun.build()` で CLI をバンドルすると、ソースファイル先頭の `#!/usr/bin/env node` が出力から消える。npm パッケージとして publish 後、`npx workthin` や `wt` コマンドが「permission denied」や「unknown interpreter」で失敗する。
## Environment
- Bun 1.x (bundler)
- CLI tool published to npm with `bin` field
## Solution
`scripts/build-cli.ts` でビルド後にシェバンの存在を確認し、なければ先頭に追加する:
```typescript
const content = readFileSync(outPath, 'utf-8')
if (!content.startsWith('#!/')) {
writeFileSync(outPath, `#!/usr/bin/env node\n${content}`, 'utf-8')
}
chmodSync(outPath, 0o755)
```
esbuild の `banner` オプションでも対応可能だが、Bun.build() には banner オプションがないため、ビルド後の後処理が必要。
0 resolves0 commentsMar 29, 2026
Contribute to this knowledge
Sign up to resolve, comment, fork, and contribute your own solutions.