pinojs / pino

🌲 super fast, all natural json logger
http://getpino.io
MIT License
14.16k stars 876 forks source link

Module not found: Error: Can't resolve 'pino-pretty' in #688

Open uwajacques opened 5 years ago

uwajacques commented 5 years ago

I seem to be getting Module not found: Error: Can't resolve 'pino-pretty' warnings even though prettyPrint is set to false. Is there anyway to turn them off?

mcollina commented 5 years ago

Can you paste a full stack trace?

davidmarkclements commented 5 years ago

@uwajacques did you manage to resolve this?

imcotton commented 4 years ago

Have just bumping into this with rollup setup, in such case, one need to settreeshake.moduleSideEffects to false, hope this helps.

mattyod commented 4 years ago

It is caused by this line: https://github.com/pinojs/pino/blob/master/lib/tools.js#L159

Perhaps it should just be a dependency?

Webpack warning is:

WARNING in /Users/user/project/node_modules/pino/lib/tools.js
Module not found: Error: Can't resolve 'pino-pretty' in '/Users/user/project/node_modules/pino/lib'
 @ /Users/user/project/node_modules/pino/lib/tools.js
 @ /Users/user/project/node_modules/pino/pino.js
 @ ./src/lib/logger.js
...
imcotton commented 4 years ago

Oh, forgot to mention, in rollup setup you need to exclude pino-pretty as well, like below

{

    treeshake: {
        moduleSideEffects: false,
    },

    plugins: [
        commonjs({
            exclude: [
                'node_modules/pino-pretty/**',
            ],
        }),
    ],

}

Webpack might need something similar as well.

jsumners commented 4 years ago

Perhaps it should just be a dependency?

https://github.com/pinojs/pino/pull/699

moeriki commented 4 years ago

For those arriving here looking for a rollup solution…

          {
            plugins: [
              resolve(),
              commonjs({
                ignore: ['pino-pretty'],
              }),
            ],
          }

Just make sure to never set pino prettyPrint to true at runtime :)

bdchauvette commented 4 years ago

In webpack, you can use the externals option:

module.exports = {
  // ...
  externals: ['pino-pretty'],
};
davidmarkclements commented 4 years ago

Does anyone want to send a PR to document this?

jeremy0x commented 3 months ago

I had the same issue in my Next.js project and fixed it by adding pino-pretty to the externals in the webpack config:

// next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (config) => {
    config.externals.push('pino-pretty', /* add any other modules that might be causing the error */);
    return config;
  },
};

module.exports = nextConfig;
magnusriga commented 1 month ago

Finally, after a lot of trial-and-error I figured out how to make pino work in a Next.js monorepo (Turborepo), with transports, pino-pretty, and functions for messageFormat, customPrettifier, and so on (i.e. non-streamable types).

The setup:

@workspace/apps/appname/next.config.mjs

  webpack(
    config,
    // { buildId, dev, isServer, defaultLoaders, nextRuntime, webpack },
  ) {
    config.resolve.fallback = {
      ...config.resolve.fallback,

      fs: false, // the solution
    };

    // NOTE: Must use this instead of serverExternalPackages | serverComponentsExternalPackages
    // because node:crypto for some reason only works below.
    // Also, when the below is defined, it overrides the serverExternalPackages,
    // so pino and pino-pretty must be included here.
    config.externals.push({
      'node:fs': 'commonjs fs',
      'node:crypto': 'commonjs crypto',
      argon2: 'argon2',
      pino: 'pino',
      'thread-stream': 'thread-stream',
      'pino-worker': 'pino-worker',
      'pino-file': 'pino-file',
      'pino-pretty': 'pino-pretty',
    });
    return config;
  },

@workspace/logger/pino.ts

import pino from 'pino';

const transport = pino.transport({
  targets: [
    {
      target: 'pino/file',
      options: { destination: `./logs/pino.log` },
      level: 'warn',
    },
    {
      target: `@<workspace>/logger/transports/pino-pretty-transport`,
      options: {
        colorize: true,
      },
    },
    {
      target: '@logtail/pino',
      options: { sourceToken: process.env.LOGTAIL_SOURCE_TOKEN },
    },
  ],
  options: {
    colorize: true,
  },
});

export const logger = pino(
  {
    level: process.env.NODE_ENV === 'production' ? 'warn' : 'trace',
    // redact,
   // other options
  },
  transport,
);

@workspace/logger/ transports/pino-pretty-transport.mjs

import pretty from 'pino-pretty';

function getPrettyStream(options) {
  return pretty({
    ...options,
    colorize: true,
    translateTime: 'SYS:standard',
    // ignore: 'pid,hostname',
    // levelFirst: true,
    // messageKey: 'msg',
    // timestampKey: 'time',
    // levelKey: 'level',

    // messageFormat: (log, messageKey, levelLabel, { colors }) => {
    //   // `colors` is a Colorette object with colors enabled based on `colorize` option.
    //   const req = log['req'];
    //   const reqUrl = req instanceof Request ? req.url : null;

    //   return `This is a ${colors.red('colorized')}, custom message: ${log[messageKey]}, ${levelLabel} ${log['pid'] ? ` - ${log['pid']}` : ''} - ${reqUrl ? ` - url: ${reqUrl}` : ''}${log[''] ? ` - ${log['pid']}` : ''}`;
    // },

    customPrettifiers: {
      // The argument for this function will be the same
      // string that's at the start of the log-line by default:
      timestamp: (timestamp) => `🕰 ${timestamp}`,

      // The argument for the level-prettifier may vary depending
      // on if the levelKey option is used or not.
      // By default this will be the same numerics as the Pino default:
      // level: (logLevel) => `LEVEL: ${logLevel}`,

      // level provides additional data in `extras`:
      // * label => derived level label string
      // * labelColorized => derived level label string with colorette colors applied based on customColors and whether colors are supported
      // level: (logLevel, key, log, { label, labelColorized, colors }) =>
      //   `LEVEL: ${logLevel} LABEL: ${label} COLORIZED LABEL: ${labelColorized}`,

      hostname: (hostname) => `MY HOST: ${hostname}`,

      pid: (pid) => `${pid}`,

      name: (name, key, log, { colors }) => `${colors.blue(String(name))}`,

      caller: (caller, key, log, { colors }) =>
        `${colors.greenBright(String(caller))}`,

      myCustomLogProp: (value, key, log, { colors }) =>
        `My Prop -> ${colors.bold(String(value))} <--`,
    },
  });
}

export default (options) => {
  const prettyStream = getPrettyStream(options);
  return prettyStream;
};

@workspace/logger/ transports/package.json

{
  "exports": {
    "./pino": "./src/pino.ts",
    "./transports/*": "./src/transports/*.mjs"
  },
}

@workspace/apps/appname/anyfile.ts

import { logger } from '@workspace/logger/pino';

logger.error(new Error('foobar'));

I think that is it. It fully works on my end with that setup.