Skip to content

vinext check should flag __dirname/__filename and suggest ESM path APIs #583

@southpolesteve

Description

@southpolesteve

Summary

vinext check should detect server-side uses of __dirname / __filename and tell users to migrate to an ESM-native path pattern.

Real-world case

This came up while testing the Platformatic Watt demo app (ecommerce branch):

That file uses __dirname to search for the app's data/ directory:

private findDataDir(): string {
  const candidates = [
    path.join(process.cwd(), 'data'),
    path.join(process.cwd(), '..', 'data'),
    path.join(__dirname, '..', 'data'),
    path.join(__dirname, 'data'),
  ]

  for (const dir of candidates) {
    if (fs.existsSync(path.join(dir, 'games.json'))) {
      return dir
    }
  }

  return path.join(process.cwd(), 'data')
}

The app works under Next.js, but this usage was the actual blocker under vinext/Vite SSR. vinext check did not flag it, so the compatibility report missed the real runtime risk.

Why this should be checked

__dirname / __filename are CommonJS globals, not ESM globals. Since vinext runs server modules through a Vite/ESM pipeline, these identifiers are a migration hazard even in otherwise normal Node-targeted server code.

This is not a Cloudflare-specific problem. It is a general Vite/ESM compatibility issue that users are likely to hit when migrating existing Next.js apps.

Proposed behavior

When vinext check scans app/server code and finds free uses of __dirname or __filename, report a warning with a migration hint.

Suggested guidance:

  • Prefer ESM path APIs instead of __dirname / __filename
  • For portable ESM: fileURLToPath(import.meta.url) + dirname(...)
  • On Node 22+: import.meta.dirname / import.meta.filename are also available

Example warning text:

__dirname / __filename are CommonJS globals and may not work under vinext's ESM server runtime. Prefer fileURLToPath(import.meta.url) / dirname(...) (or import.meta.dirname / import.meta.filename on Node 22+).

Why this matters

Even if vinext adds more runtime compatibility here, the check command should still surface legacy CJS path usage and steer users toward the ESM-native pattern up front.

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