Skip to content

fix(common): add resolveJsonModule to ts-node compilerOptions (fixes #816)#2189

Open
just-jeb wants to merge 1 commit intomasterfrom
fix/816-resolve-json-module
Open

fix(common): add resolveJsonModule to ts-node compilerOptions (fixes #816)#2189
just-jeb wants to merge 1 commit intomasterfrom
fix/816-resolve-json-module

Conversation

@just-jeb
Copy link
Copy Markdown
Owner

Problem

Importing .json files in TypeScript webpack configs (e.g. import * as pkg from './package.json') fails with:

TS2732: Cannot find module './package.json'. Consider using '--resolveJsonModule' to import module with '.json' extension.

This happens because ts-node was not configured with resolveJsonModule: true when loading user webpack config files.

Root Cause

load-module.ts calls ts-node's register() with an explicit compilerOptions override. This override sets module: 'CommonJS' and types: ['node'] but does not include resolveJsonModule. As a result, even if the user's tsconfig.json has resolveJsonModule: true, it gets overridden to false (the default).

Fix

Add resolveJsonModule: true to the explicit compilerOptions passed to ts-node.register(). This is a safe, additive change — it only affects the ts-node compilation context used when loading user config files, not the application's own TypeScript compilation.

Verification

Confirmed TS2732 error without the fix and clean compile with it using the same import * as pkg from './package.json' pattern.

Adds integration test: custom-webpack: TS config with JSON import which builds the app using a webpack config that imports package.json.

Closes #816

@just-jeb
Copy link
Copy Markdown
Owner Author

Thanks for the PR!

After discussion, we have decided not to add resolveJsonModule: true at the builder level for now. The reasoning:

  • resolveJsonModule is a TypeScript compiler option that belongs in the user tsconfig.json. The builder already passes the user tsconfig to ts-node via the project option, so users can opt in by adding it there.
  • Silently injecting it could surprise users who have explicitly set it to false, or cause subtle behavioral differences.
  • If we decide to make it a default in the future, that would be a breaking change appropriate for a major version bump.

The workaround is straightforward: add resolveJsonModule: true to the tsconfig that your webpack config uses. We will update the docs to make this clearer.

Appreciate the contribution!

@just-jeb just-jeb closed this Apr 26, 2026
@just-jeb
Copy link
Copy Markdown
Owner Author

Correction to my previous comment: looking more carefully at the issue history, the reporter confirmed that adding resolveJsonModule to the user tsconfig does NOT fully solve it (it still fails for the karma builder). So the user-side workaround is incomplete.

The actual validated workarounds are:

  • Use require() instead of import for JSON files in webpack configs
  • Or fix it at the builder level by passing resolveJsonModule: true to ts-node

We are reconsidering the approach. Fixing it at the builder level is valid but would be a deliberate decision for a major version. Apologies for the premature close — we will reopen and track this properly.

@just-jeb just-jeb reopened this Apr 26, 2026
@just-jeb
Copy link
Copy Markdown
Owner Author

Updated analysis after reading the code:

The root cause is that _tsNodeRegister passes an explicit compilerOptions object to ts-node, which replaces rather than merges with the user's tsconfig compilerOptions. This means a user cannot work around the issue by adding resolveJsonModule: true to their own tsconfig — the builder overrides it regardless. The only user-side workaround is require() instead of import.

There are two possible approaches to fix this properly:

  1. Add resolveJsonModule: true to the explicit override — what this PR does. Simple, but opinionated.
  2. Read the user's tsconfig compilerOptions and merge them into the override — more principled, respects any option the user has set.

Both approaches could be a breaking change for setups that rely on the current minimal override behavior. We are deferring this to the next major version. Keeping this PR open as a reference implementation for when that time comes.

…816)

When a TypeScript webpack config imports a JSON file (e.g. `import * as pkg from './package.json'`),
ts-node throws TS2732 ('Cannot find module') if the project tsconfig uses moduleResolution:'node'
and does not set resolveJsonModule:true.

The root cause: the builder's ts-node registration overrides `module: 'CommonJS'` but never
sets `resolveJsonModule`. With moduleResolution:'node' (the Angular default before v17),
TypeScript requires an explicit `resolveJsonModule: true` to allow JSON imports.

Fix: add `resolveJsonModule: true` to the compilerOptions override in `_tsNodeRegister()`.
This is safe to always enable — it has no downside and works with all moduleResolution modes
(node, node16, bundler, etc.).

Reproduction: tsconfig with moduleResolution:node + TS webpack config importing package.json -> TS2732
Fix verifier: same config with resolveJsonModule injected by ts-node -> build succeeds

Integration test added: ts-config-json-module-import
@just-jeb just-jeb force-pushed the fix/816-resolve-json-module branch from 96f1f05 to b0bafff Compare April 26, 2026 14:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cannot find module package.json

1 participant