UNPKG

bun-plugin-pino

Version:

Bundle Pino logger dependencies with Bun

98 lines (79 loc) 3.38 kB
import { stat } from 'node:fs/promises'; import path from 'node:path'; import type { BunPlugin } from 'bun'; export type BunPluginPinoOpts = { transports?: string[]; logging?: 'default' | 'plain' | 'quiet' }; export function bunPluginPino({ transports = [], logging = 'default' }: BunPluginPinoOpts = {}): BunPlugin { return { name: 'pino', async setup(build) { const yellow = (str: string) => (logging === 'default' ? `\u001b[33m${str}\u001b[0m` : str); const green = (str: string) => (logging === 'default' ? `\u001b[32m${str}\u001b[0m` : str); const print = (msg: string) => { if (logging !== 'quiet') console.log(msg); }; if (build.config.format === 'cjs') { throw new Error('CJS is not supported'); } if (build.config.target === 'browser') { throw new Error('Bundling for browsers is not supported'); } const outdir = build.config.outdir || ''; const pino = path.dirname(Bun.resolveSync('pino', import.meta.dir)); const threadStream = path.dirname(Bun.resolveSync('thread-stream', import.meta.dir)); const depmap: Record<string, string> = { 'thread-stream-worker': path.join(threadStream, 'lib/worker.js'), 'pino-worker': path.join(pino, 'lib/worker.js'), 'pino/file': path.join(pino, 'file.js'), }; /** worker-pipeline.js was removed in Pino v9.1 */ try { const pinoPipelineWorker = path.join(pino, 'lib/worker-pipeline.js'); await stat(pinoPipelineWorker); depmap['pino-pipeline-worker'] = pinoPipelineWorker; } catch (err) { // Ignored } for (const transport of transports) { depmap[transport] = Bun.resolveSync(transport, import.meta.dir); } print(green('\nBundling Pino dependencies...\n')); for (const [key, entry] of Object.entries(depmap)) { const naming = `${key.replace('/', '-')}.js`; const outpath = path.relative(process.cwd(), path.join(outdir, naming)); print(` ${yellow(key)}\n ${path.relative(process.cwd(), entry)} -> ${outpath}\n`); const { sourcemap, minify } = build.config; await Bun.build({ entrypoints: [entry], outdir, naming, target: build.config.target, format: build.config.format, sourcemap, minify, }); } let injected = false; const dirname = build.config.target === 'node' ? 'import.meta.dirname' : 'import.meta.dir'; build.onLoad({ filter: /[\/|\\]pino\.js$/ }, async (args) => { if (injected) return; injected = true; const lines: string[] = []; lines.push('(() => {'); lines.push(" const path = require('node:path');"); lines.push(' const overrides = {'); for (const dep of Object.keys(depmap)) { lines.push(` '${dep}': path.resolve(${dirname}, '${dep.replace('/', '-')}.js'),`); } lines.push('};'); lines.push( ' globalThis.__bundlerPathsOverrides = { ...(globalThis.__bundlerPathsOverrides || {}), ...overrides };' ); lines.push('})();'); lines.push(await Bun.file(args.path).text()); print(`${green('Done')}\n`); return { contents: lines.join('\n') }; }); }, }; } export default bunPluginPino;