Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
uwajacques opened this issue Aug 1, 2019 · 11 comments
Open

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

uwajacques opened this issue Aug 1, 2019 · 11 comments

Comments

@uwajacques
Copy link

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
Copy link
Member

mcollina commented Aug 1, 2019

Can you paste a full stack trace?

@davidmarkclements
Copy link
Member

@uwajacques did you manage to resolve this?

@imcotton
Copy link

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

@mattyod
Copy link

mattyod commented Dec 12, 2019

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
Copy link

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
Copy link
Member

Perhaps it should just be a dependency?

#699

@moeriki
Copy link

moeriki commented Jan 24, 2020

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
Copy link

In webpack, you can use the externals option:

module.exports = {
  // ...
  externals: ['pino-pretty'],
};

@davidmarkclements
Copy link
Member

Does anyone want to send a PR to document this?

@jeremy0x
Copy link

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
Copy link

magnusriga commented Aug 20, 2024

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

  • A lot of guides talk about adding pino and pino-pretty to serverExternalPackages (or experimental.serverComponentsExternalPackages if on v14). That does not work if also using config.externals.push in the webpack callback.
  • So, comment out serverExternalPackages and stick to only using config.externals.push, since the latter allows including node:crypto (among others) and the former did not.
  • If you include both, it seems config.externals.push overwrites serverExternalPackages, and thus it is not enough to include pino and pino-pretty in serverExternalPackages. Here is the relevant code:
  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

  • The important part here, is to add the right path to target. I could not make a relative path work, so I landed on using the package from node_modules this way: @<workspace>/logger/transports/pino-pretty-transport.
  • If you are not using a monorepo, I guess it will be easier to just do a relative import within the local project.
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

  • The pino-pretty transport file had to be mjs, I could not make it work as .ts.
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

  • Make sure to export the right files:
{
  "exports": {
    "./pino": "./src/pino.ts",
    "./transports/*": "./src/transports/*.mjs"
  },
}

@workspace/apps/appname/anyfile.ts

  • To use the logger:
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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants