Skip to content

[BUG]: Generator fails with ERR_UNSUPPORTED_DIR_IMPORT / SyntaxError on TypeScript 6.0+ #789

@jxn-30

Description

@jxn-30

Version

5.27.1

Describe the bug

The generator (i18n:once / i18n:watch) fails when TypeScript 6.0+ is installed in the project.

TypeScript 6.0 changed the default module option from CommonJS to esnext:

"module defaults to esnext: Similarly, the new default module is esnext, acknowledging that ESM is now the dominant module format."

The generator internally calls ts.createProgram without an explicit module option (in packages/generator/src/parse-language-file.mts). With TypeScript 6.0+, this now emits import/export statements instead of require() calls into the temp-output directory. When Node.js subsequently loads these files via dynamic import(), it treats them as ESM — which does not support bare directory imports (e.g. import { x } from '../../some/dir' without /index.js), causing the error below.

The bug affects any project where the base locale file (de/index.ts, en/index.ts, …) imports from another module, which includes:

  • Projects using the built-in typesafe-i18n namespace feature (sub-folders in the locale directory)
  • Projects using custom imports from outside the locale directory

Projects with all translations inline and no imports are not affected.

A possible fix seems to be a single line: adding module: ts.ModuleKind.CommonJS explicitly to the ts.createProgram call forces CJS output regardless of the TypeScript version's default:

 const program = ts.createProgram([languageFilePath], {
     outDir: tempPath,
     allowJs: true,
     resolveJsonModule: true,
     skipLibCheck: true,
     sourceMap: false,
     noLib: true,
+    module: ts.ModuleKind.CommonJS, // Ensure CJS output regardless of TS version defaults
 });

Reproduction

Minimal folder structure to reproduce:

src/
  i18n/
    de/
      settings/
        index.ts    ← any namespace or external import
      index.ts      ← imports from ./settings or another directory

With typescript >= 6.0.0 and node >= 22.12.0, running typesafe-i18n --no-watch fails.

Logs

[typesafe-i18n] ERROR: import failed for .../node_modules/typesafe-i18n/temp-output/0/i18n/de/index.js
Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import '.../node_modules/typesafe-i18n/temp-output/0/features/bookmarks/i18n'
is not supported resolving ES modules imported from .../node_modules/typesafe-i18n/temp-output/0/i18n/de/index.js

Config

{
    "$schema": "https://unpkg.com/typesafe-i18n@5.27.1/schema/typesafe-i18n.json",
    "adapters": [],
    "baseLocale": "de",
    "outputFormat": "TypeScript",
    "esmImports": ".js",
    "generateOnlyTypes": false,
    "runAfterGenerator": "yarn prettier:i18n"
}

Additional information

Temporary workaround via yarn patch (typesafe-i18n-npm-5.27.1-37bc79b222.patch):

diff --git a/cli/typesafe-i18n.mjs b/cli/typesafe-i18n.mjs
--- a/cli/typesafe-i18n.mjs
+++ b/cli/typesafe-i18n.mjs
@@ -22862,7 +22862,8 @@ var transpileTypescriptFiles = ...
     resolveJsonModule: true,
     skipLibCheck: true,
     sourceMap: false,
-    noLib: true
+    noLib: true,
+    module: ts.ModuleKind.CommonJS // Tell TS to use CommonJS imports
   });

This has sucessfully fixed the issue in a real-world repository: jxn-30/better-moodle@00c0843

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions