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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions