Skip to content

Issue: ESM Compatibility - __dirname is not defined in dts-plugin #4550

@gdwneo

Description

@gdwneo

Describe the bug

Issue: ESM Compatibility - __dirname is not defined in dts-plugin

Description

When using @module-federation/dts-plugin@2.2.1, the build process throws a ReferenceError: __dirname is not defined error. This occurs because the DTS plugin's ESM module uses the CommonJS global variable __dirname, which is not available in ESM context.

Error Details

ReferenceError: __dirname is not defined
    at new DtsWorker (file:///path/to/node_modules/@module-federation/dts-plugin@2.2.1/node_modules/@module-federation/dts-plugin/dist/esm/consumeTypes-IRrP9NIN.mjs:157:49)
    at generateTypesInChildProcess (file:///path/to/node_modules/@module-federation/dts-plugin@2.2.1/node_modules/@module-federation/dts-plugin/dist/esm/consumeTypes-IRrP9NIN.mjs:194:9)
    at generateTypesAPI (file:///path/to/node_modules/@module-federation/dts-plugin@2.2.1/node_modules/@module-federation/dts-plugin/dist/esm/index.mjs:315:46)

Affected Files

  1. packages/dts-plugin/src/core/lib/DtsWorker.ts - Uses __dirname to construct worker file path
  2. Build output: dist/esm/consumeTypes-IRrP9NIN.mjs - ESM module lacks __dirname

Environment

  • Package: @module-federation/dts-plugin@2.2.1
  • Bundler: Vite 7.x (with @module-federation/vite@1.13.0)
  • Node.js: v24+
  • Package Manager: pnpm

Root Cause

In packages/dts-plugin/src/core/lib/DtsWorker.ts:

this.rpcWorker = createRpcWorker(path.resolve(__dirname, "./fork-generate-dts.js"), {}, void 0, true);

When this code is bundled as an ESM module, __dirname is not available. Additionally, the forked worker file extension should be .mjs instead of .js.

Proposed Solution

Following the pattern used in other Module Federation packages (e.g., @module-federation/storybook-addon/tsdown.config.ts using import.meta.dirname), provide a __dirname polyfill for ESM environments:

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

// ESM __dirname polyfill
const __dirname = dirname(fileURLToPath(import.meta.url));

And update the worker file path to:

this.rpcWorker = createRpcWorker(path.resolve(__dirname, "./fork-generate-dts.mjs"), {}, void 0, true);

Temporary Workaround

Use pnpm patch to fix:

--- a/dist/esm/consumeTypes-IRrP9NIN.mjs
+++ b/dist/esm/consumeTypes-IRrP9NIN.mjs
@@ -1,7 +1,11 @@
 import { a as cloneDeepOptions, n as RpcGMCallTypes, o as getDTSManagerConstructor, s as isDebugMode, t as exposeRpc, x as __exportAll } from "./expose-rpc-DsABkfLc.mjs";
 import path from "path";
+import { fileURLToPath } from "url";
 import { randomUUID } from "crypto";
 import * as child_process from "child_process";
 import * as process$2 from "process";
+
+// ESM __dirname polyfill
+const __dirname = path.dirname(fileURLToPath(import.meta.url));

And:

-    this.rpcWorker = createRpcWorker(path.resolve(__dirname, "./fork-generate-dts.js"), {}, void 0, true);
+    this.rpcWorker = createRpcWorker(path.resolve(__dirname, "./fork-generate-dts.mjs"), {}, void 0, true);

Impact

This issue affects all projects using Vite or other ESM-first bundlers with @module-federation/dts-plugin.

Related

  • Package: @module-federation/dts-plugin
  • Affected versions: 2.2.0, 2.2.1
  • Build tool configuration: packages/dts-plugin/tsdown.config.ts

Reproduction

N/A

Used Package Manager

pnpm

System Info

System:
    OS: macOS 26.3.1
    CPU: (8) arm64 Apple M1 Pro
    Memory: 443.00 MB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 24.12.0 - /Users/gedongwu/.nvm/versions/node/v24.12.0/bin/node
    npm: 11.6.2 - /Users/gedongwu/.nvm/versions/node/v24.12.0/bin/npm
    pnpm: 10.32.1 - /Users/gedongwu/.nvm/versions/node/v24.12.0/bin/pnpm
    Watchman: 2025.12.29.00 - /opt/homebrew/bin/watchman
  Browsers:
    Chrome: 145.0.7632.160
    Safari: 26.3.1

Validations

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