Skip to content

__dirname ReferenceError in Compiled Executable Using Deno Bundle and Compile with External Libraries #30604

@xpr0gamers

Description

@xpr0gamers

When bundling a Deno application into a single ESM file using deno bundle and then compiling it into an executable with deno compile, the resulting executable throws a ReferenceError: __dirname is not defined when executed.
This error originates from an external library (in this case, fastify-swagger), which relies on Node.js globals like __dirname that are not available or shimmed properly in the Deno environment.
The bundling process uses esbuild under the hood, which might not handle Node.js-specific globals like __dirname correctly for ESM formats or compiled executables, leading to runtime errors in dependencies.
Steps to Reproduce

  1. Create a Deno project that imports and uses fastify-swagger (or any library relying on __dirname).
  2. Bundle the project into a single ESM file:
    deno bundle --format=esm --output ./build/server.js --unstable-unsafe-proto --unstable-raw-imports ./src/program.ts
  3. Compile the bundled file into an executable (targeting e.g., aarch64-apple-darwin):
    deno compile --allow-all --env-file --no-check --output ./build/server --target aarch64-apple-darwin --unstable-unsafe-proto --unstable-raw-imports ./build/server.js
  4. Run the compiled executable: ./build/server
  5. Observe the error
    error: Uncaught ReferenceError: __dirname is not defined root: opts.baseDir || path.join(__dirname, "..", "static"),

Expected Behavior
The compiled executable should run without errors related to missing Node.js globals like __dirname. External libraries should either be compatible or have necessary shims applied during bundling/compilation.
Actual Behavior
The executable fails with a ReferenceError for __dirname in the external library (fastify-swagger).
Environment

Deno version: 2.4.5
OS: macOS on Apple Silicon
Target: aarch64-apple-darwin
Library: fastify-swagger

Possible Solution
Since deno bundle uses esbuild internally, consider integrating or allowing users to add esbuild plugins to shim Node.js globals like __dirname. For example, the esbuild-shim-plugin could be used to polyfill __dirname (along with __filename, require, etc.) during the bundling process. This would make the output more compatible with Node.js-style libraries in Deno executables.
If this is not feasible, providing documentation or built-in flags to handle such shims would be helpful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions