fastify / fastify-swagger-ui

Serve Swagger-UI for Fastify
MIT License
137 stars 40 forks source link

ReferenceError: __dirname is not defined in ES module scope #153

Closed MaximeBernard closed 3 months ago

MaximeBernard commented 4 months ago

Prerequisites

Fastify version

4.27.0

Plugin version

3.0.0

Node.js version

22.2.0

Operating system

macOS

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

14.5

Description

I'm trying to run the plugin with esbuild. At first, I had issues with the static folder. So I added a copy. My package.json looks like this:

{
  "scripts": {
    "build": "esbuild && cp -R ./node_modules/@fastify/swagger-ui/static dist",
    "start": "node dist/main.mjs"
  }
}

But I get this error

[node] file:///Users/me/service/dist/main.mjs:37584
[node]       const logoContent = await fsPromises.readFile(path.join(__dirname, "./static/logo.svg"));
[node]                                                               ^
[node]
[node] ReferenceError: __dirname is not defined in ES module scope
[node]     at fastifySwaggerUi2 (file:///Users/me/service/dist/main.mjs:37584:63)
[node]     at Plugin.exec (file:///Users/me/service/dist/main.mjs:38008:32)
[node]     at Boot._loadPlugin (file:///Users/me/service/dist/main.mjs:38518:14)
[node]     at process.processTicksAndRejections (node:internal/process/task_queues:82:21)

Do you plan to handle ESM? Is there any workaround?

From what I read, this is just

import { fileURLToPath } from 'url';
import { dirname } from 'path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

This looks simple but I might not have the whole picture.

Link to code that reproduces the bug

No response

Expected Behavior

No response

jsumners commented 4 months ago

That sounds like a problem with your tooling. The source file in this project is not an ESM style file: https://github.com/fastify/fastify-swagger-ui/blob/758abaed570cce1a42e12e4b5cfd86b5e94d2efc/index.js#L1-L35

For what it's worth, on Node.js 20 and greater:

const dirname = import.meta.dirname
MaximeBernard commented 3 months ago

Thank you but that was my initial question: any plan to handle ESM or is it intended to stay in CommonJS?

Since fastify is ESM-ready, I was expecting this to be as well.

mcollina commented 3 months ago

This is 100% esm ready. You can consume this library in any ESM project.

However, you are transpiling this code to esm, using esbuild, which does not support transpiling commonjs into esm.

My understanding is that rollup does this correctly. I recommend you to change your bundling strategy.