Created
November 11, 2021 10:00
-
-
Save ShogunPanda/752cce88659a09bff827ef8d2ecf8c80 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { dirname, sep, join, resolve } = require('path') | |
const { build } = require('esbuild') | |
const { readFile } = require('fs/promises') | |
// TODO: Check how to solve when [dir] or [hash] are used | |
function pinoPlugin(options) { | |
options = { transports: [], ...options } | |
return { | |
name: 'pino', | |
setup(currentBuild) { | |
const pino = dirname(require.resolve('pino')) | |
const threadStream = dirname(require.resolve('thread-stream')) | |
// Adjust entrypoints if it is an array | |
let entrypoints = currentBuild.initialOptions.entryPoints | |
if (Array.isArray(entrypoints)) { | |
let outbase = currentBuild.initialOptions.outbase | |
// Find the outbase | |
if (!outbase) { | |
const hierarchy = entrypoints[0].split(sep) | |
let i = 0 | |
outbase = '' | |
let nextOutbase = '' | |
do { | |
outbase = nextOutbase | |
i++ | |
nextOutbase = hierarchy.slice(0, i).join(sep) | |
} while (entrypoints.every(e => e.startsWith(`${nextOutbase}/`))) | |
} | |
const newEntrypoints = {} | |
for (const entrypoint of entrypoints) { | |
const destination = (outbase ? entrypoint.replace(`${outbase}/`, '') : entrypoint).replace(/.js$/, '') | |
newEntrypoints[destination] = entrypoint | |
} | |
entrypoints = newEntrypoints | |
} | |
// Now add our endpoints | |
const userEntrypoints = Object.entries(entrypoints) | |
const customEntrypoints = { | |
'thread-stream-worker': join(threadStream, 'lib/worker.js'), | |
'pino-worker': join(pino, 'lib/worker.js'), | |
'pino-pipeline-worker': join(pino, 'lib/worker-pipeline.js'), | |
'pino-file': join(pino, 'file.js') | |
} | |
// TODO: Add files in options.transport as well using require.resolve | |
currentBuild.initialOptions.entryPoints = { ...entrypoints, ...customEntrypoints } | |
// // Add a loader for all entrypoints to add the banner | |
currentBuild.onResolve({ filter: /\.js$/ }, args => { | |
if (args.kind === 'entry-point') { | |
const absolutePath = resolve(process.cwd(), args.path) | |
// Find in the entrypoints the one which has this definition in order to get the folder | |
const destination = userEntrypoints.find(pair => resolve(process.cwd(), pair[1]) === absolutePath) | |
if (destination) { | |
return { path: join(args.resolveDir, args.path), pluginData: { pinoBundlerOverride: destination[0] } } | |
} | |
} | |
return undefined | |
}) | |
// Prepend our overrides | |
const banner = `/* Start of pino-webpack-bundler additions */ | |
function pinoWebpackBundlerAbsolutePath(p) { | |
try { | |
return require('path').join(__dirname, p) | |
} catch(e) { | |
// This is needed not to trigger a warning if we try to use within CJS - Do we have another way? | |
const f = new Function('p', 'return new URL(p, import.meta.url).pathname'); | |
return f(p) | |
} | |
} | |
` | |
currentBuild.onLoad({ filter: /\.js$/ }, async args => { | |
if (!args.pluginData || !args.pluginData.pinoBundlerOverride) { | |
return undefined | |
} | |
const contents = await readFile(args.path, 'utf8') | |
// Find how much the asset is nested | |
const prefix = | |
args.pluginData.pinoBundlerOverride | |
.split(sep) | |
.slice(0, -1) | |
.map(() => '..') | |
.join(sep) || '.' | |
const declarations = Object.keys(customEntrypoints) | |
.map( | |
id => | |
`'${id === 'pino-file' ? 'pino/file' : id}': pinoWebpackBundlerAbsolutePath('${prefix}${sep}${id}.js')` | |
) | |
.join(',') | |
const overrides = `\nglobalThis.pinoBundlerOverrides = {${declarations}};\n/* End of pino-webpack-bundler additions */\n\n` | |
return { | |
contents: banner + overrides + contents | |
} | |
}) | |
} | |
} | |
} | |
build({ | |
entryPoints: { | |
main: 'src/index.js', | |
}, | |
bundle: true, | |
platform: 'node', | |
outdir: 'dist', | |
plugins: [pinoPlugin({ transport: 'pino-pretty' })] | |
}).catch(() => process.exit(1)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@davipon
You're welcome, your feedback made my day!
Thanks for the plugin, I will take a look soon.
Also, definitely create the PR, so we can list it.
CC: @mcollina