Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: pinojs/pino
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v7.1.0
Choose a base ref
...
head repository: pinojs/pino
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v7.2.0
Choose a head ref
  • 3 commits
  • 7 files changed
  • 2 contributors

Commits on Nov 10, 2021

  1. feat: Support bundlers. (#1209)

    * feat: Support bundlers.
    
    * test: Added bundlers support tests.
    
    * docs: Added bundling docs.
    ShogunPanda authored Nov 10, 2021
    Copy the full SHA
    4e08b37 View commit details
  2. Copy the full SHA
    96f01c9 View commit details
  3. Bumped v7.2.0

    mcollina committed Nov 10, 2021
    Copy the full SHA
    12d4dce View commit details
Showing with 157 additions and 8 deletions.
  1. +6 −0 README.md
  2. +30 −0 docs/bundling.md
  3. +6 −2 lib/transport.js
  4. +3 −2 lib/worker-pipeline.js
  5. +3 −2 lib/worker.js
  6. +3 −2 package.json
  7. +106 −0 test/transport/bundlers-support.test.js
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -92,6 +92,12 @@ In many cases, Pino is over 5x faster than alternatives.

See the [Benchmarks](docs/benchmarks.md) document for comparisons.

### Bundling support

Pino supports to being bundled using tools like webpack or esbuild.

See [Bundling](docs/bundling.md) document for more informations.

<a name="team"></a>
## The Team

30 changes: 30 additions & 0 deletions docs/bundling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Bundling

Due to its internal architecture based on Worker Threads, it is not possible to bundle Pino *without* generating additional files.

In particular, a bundler must ensure that the following files are also bundle separately:

* `lib/worker.js` from the `thread-stream` dependency
* `file.js`
* `lib/worker.js`
* `lib/worker-pipeline.js`
* Any transport used by the user (like `pino-pretty`)

Once the files above have been generated, the bundler must also add information about the files above by injecting a code which sets `__bundlerPathsOverrides` in the `globalThis` object.

The variable is a object whose keys are identifier for the files and the the values are the paths of files relative to the currently bundle files.

Example:

```javascript
// Inject this using your bundle plugin
globalThis.__bundlerPathsOverrides = {
'thread-stream-worker': pinoWebpackAbsolutePath('./thread-stream-worker.js')
'pino/file': pinoWebpackAbsolutePath('./pino-file.js'),
'pino-worker': pinoWebpackAbsolutePath('./pino-worker.js'),
'pino-pipeline-worker': pinoWebpackAbsolutePath('./pino-pipeline-worker.js'),
'pino-pretty': pinoWebpackAbsolutePath('./pino-pretty.js'),
};
```

Note that `pino/file`, `pino-worker`, `pino-pipeline-worker` and `thread-stream-worker` are required identifiers. Other identifiers are possible based on the user configuration.
8 changes: 6 additions & 2 deletions lib/transport.js
Original file line number Diff line number Diff line change
@@ -81,6 +81,8 @@ function transport (fullOptions) {
const { pipeline, targets, options = {}, worker = {}, caller = getCaller() } = fullOptions
// This function call MUST stay in the top-level function of this module
const callerRequire = createRequire(caller)
// This will be eventually modified by bundlers
const bundlerOverrides = '__bundlerPathsOverrides' in globalThis ? globalThis.__bundlerPathsOverrides : {}

let target = fullOptions.target

@@ -89,15 +91,15 @@ function transport (fullOptions) {
}

if (targets) {
target = join(__dirname, 'worker.js')
target = bundlerOverrides['pino-worker'] || join(__dirname, 'worker.js')
options.targets = targets.map((dest) => {
return {
...dest,
target: fixTarget(dest.target)
}
})
} else if (fullOptions.pipeline) {
target = join(__dirname, 'worker-pipeline.js')
target = bundlerOverrides['pino-pipeline-worker'] || join(__dirname, 'worker-pipeline.js')
options.targets = pipeline.map((dest) => {
return {
...dest,
@@ -109,6 +111,8 @@ function transport (fullOptions) {
return buildStream(fixTarget(target), options, worker)

function fixTarget (origin) {
origin = bundlerOverrides[origin] || origin

if (isAbsolute(origin) || origin.indexOf('file://') === 0) {
return origin
}
5 changes: 3 additions & 2 deletions lib/worker-pipeline.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict'

const EE = require('events')
const { realImport, realRequire } = require('real-require')
const { pipeline, PassThrough } = require('stream')

// This file is not checked by the code coverage tool,
@@ -13,11 +14,11 @@ module.exports = async function ({ targets }) {
let fn
try {
const toLoad = 'file://' + t.target
fn = (await import(toLoad)).default
fn = (await realImport(toLoad)).default
} catch (error) {
// See this PR for details: https://github.com/pinojs/thread-stream/pull/34
if ((error.code === 'ENOTDIR' || error.code === 'ERR_MODULE_NOT_FOUND')) {
fn = require(t.target)
fn = realRequire(t.target)
} else {
throw error
}
5 changes: 3 additions & 2 deletions lib/worker.js
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@

const pino = require('../pino.js')
const build = require('pino-abstract-transport')
const { realImport, realRequire } = require('real-require')

// This file is not checked by the code coverage tool,
// as it is not reliable.
@@ -13,11 +14,11 @@ module.exports = async function ({ targets }) {
let fn
try {
const toLoad = 'file://' + t.target
fn = (await import(toLoad)).default
fn = (await realImport(toLoad)).default
} catch (error) {
// See this PR for details: https://github.com/pinojs/thread-stream/pull/34
if ((error.code === 'ENOTDIR' || error.code === 'ERR_MODULE_NOT_FOUND')) {
fn = require(t.target)
fn = realRequire(t.target)
} else {
throw error
}
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pino",
"version": "7.1.0",
"version": "7.2.0",
"description": "super fast, all natural json logger",
"main": "pino.js",
"type": "commonjs",
@@ -109,9 +109,10 @@
"pino-abstract-transport": "v0.5.0",
"pino-std-serializers": "^4.0.0",
"quick-format-unescaped": "^4.0.3",
"real-require": "^0.1.0",
"safe-stable-stringify": "^2.1.0",
"sonic-boom": "^2.2.1",
"thread-stream": "^0.12.0"
"thread-stream": "^0.13.0"
},
"tsd": {
"directory": "test/types"
106 changes: 106 additions & 0 deletions test/transport/bundlers-support.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
'use strict'

const os = require('os')
const { join } = require('path')
const { readFile } = require('fs').promises
const { watchFileCreated } = require('../helper')
const { test } = require('tap')
const pino = require('../../pino')

const { pid } = process
const hostname = os.hostname()

test('pino.transport with destination overriden by bundler', async ({ same, teardown }) => {
globalThis.__bundlerPathsOverrides = {
foobar: join(__dirname, '..', 'fixtures', 'to-file-transport.js')
}

const destination = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
const transport = pino.transport({
target: 'foobar',
options: { destination }
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})

globalThis.__bundlerPathsOverrides = undefined
})

test('pino.transport with worker destination overriden by bundler', async ({ same, teardown }) => {
globalThis.__bundlerPathsOverrides = {
'pino-worker': join(__dirname, '..', '..', 'lib/worker.js')
}

const destination = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
const transport = pino.transport({
targets: [
{
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination }
}
]
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})

globalThis.__bundlerPathsOverrides = undefined
})

test('pino.transport with worker-pipeline destination overriden by bundler', async ({ same, teardown }) => {
globalThis.__bundlerPathsOverrides = {
'pino-pipeline-worker': join(__dirname, '..', '..', 'lib/worker-pipeline.js')
}

const destination = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
const transport = pino.transport({
pipeline: [
{
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination }
}
]
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})

globalThis.__bundlerPathsOverrides = undefined
})