fastify / fastify-cli

Run a Fastify application with one command!
MIT License
657 stars 163 forks source link

Logger not loading after conversion to ES module #678

Closed cunum closed 8 months ago

cunum commented 11 months ago

Prerequisites

Fastify version

4.24.3

Plugin version

5.9.0

Node.js version

19.5.0

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

13.4.1

Description

I'm currently switching from CommonJS modules to ES modules and encountering some issues with my Fastify-Cli project.

I'm using a custom logging module which I'm setting when running the command

fastify start -P -L ./utils/multi-stream-logger.js -o app.js

Problem is it doesn't work anymore as a ES module, error is:

Error [ERR_REQUIRE_ESM]: require() of ES Module multi-stream-logger.js from fastify-cli/util.js not supported.

Instead change the require of multi-stream-logger.js in fastify-cli/util.js to a dynamic import() which is available in all CommonJS modules.
    at requireModule (fastify-cli/util.js:29:12)
    at runFastify (fastify-cli/start.js:98:16) {
  code: 'ERR_REQUIRE_ESM'

Steps to Reproduce

Set an ES module custom logger instead of a CommonJS module and run:

fastify start -P -L ./logger.js -o app.js

Expected Behavior

A custom logger can be configured as ES module or CommonJS module in fastify-cli.

Also ".cjs" and ".mjs" file extensions of the logging module should be supported, which seems not to be the case. I tried renaming my logger to .cjs to use the file as CommonJS module to make it work but the module couldn't be found like that.

yellow13441 commented 11 months ago

I've encountered the same problem today, loading aditional logger configuration file seems not supported in ES module projects(with type: "module" in nearest package.json) yet.

Here is how I fixed the logger customizing issue, instead of specifying an external logger configuration file, we could set FastifyServerOptions in our app.js/app.ts file.

  1. If your project was automatically generated by fastify-cli with it's template, you should find the code like below in your app.js or app.ts file.

    app.ts (in my ts project)

    // Pass --options via CLI arguments in command to enable these options.
    const options: AppOptions = {
    logger: {
        level: 'info',
        customLevels: {
            test: 99
        }
    }
    }

    or app.js

    // Pass --options via CLI arguments in command to enable these options.
    module.exports.options = {
    logger: {
     level: 'info',
    }
  2. Append -o flag in your fastify-cli command, eg. fastify start -o -P app.js

Wish this could help you with your logger issue.

cunum commented 11 months ago

Thanks for your solution, unfortunately my multi-stream-logger.js is rather complex, I import several libraries there in order to log to console and file system simultaneously and perform log rotation of the written log files. So it's not doable via options.

My current temporary solution is I simply use this one file as CommonJS module, the rest of the files in my project are ES modules now. As the ".cjs" file extension didn't work, I created a new folder and put the multi-stream-logger.js in there together with a new package.json file with the following content (only this one line):

{ "type": "commonjs" } That way all files in that folder are interpreted as CommonJS modules and the multi-stream-logger.js import worked.

mhamann commented 9 months ago

Just ran into this same issue. Our start command uses the Fastify CLI to load a specific logging module, which is a CJS file. However, it seems like the fastify cli is rewriting the filename to assume a ".js" extension? So then Node thinks it needs to be a module, but is being loaded by a synchronous, CommonJS require(), and thus it doesn't work.