Sitecore / Sitecore/content-sdk

Import-map codegen ignores tsconfig `extends`, emitting type-only imports as runtime values

Open Beginner friendly
#565 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
37
Forks
41
Avg merge
2d 3h
Merged PRs (30d)
22

Description

Describe the bug

sitecore-tools project build (writeImportMap) reads the app's tsconfig via ts.readConfigFile() and passes config.compilerOptions directly to ts.transpileModule() (see _getImportMap in packages/content/src/tools/codegen/import-map.ts).

ts.readConfigFile does not resolve extends. When compilerOptions live in a shared config package — e.g. "extends": "@acme/typescript-config/base.json", the standard Turborepo monorepo pattern — the transpile step runs with almost no compiler options (no jsx, module, etc.). Type-only imports are then no longer elided during transpilation, and the generated .sitecore/import-map.ts imports interfaces and uses them as runtime values.

next build then fails type checking with:

.sitecore/import-map.ts:191:42
Type error: 'NavigationFields' only refers to a type, but is being used as a value here.

  189 |     module: '@acme/ui/src/components/GlobalHeader/GlobalHeader.props',
  190 |     exports: [
> 191 |       { name: 'NavigationFields', value: NavigationFields },

(NavigationFields is an export interface — a type-only export.)

To Reproduce

  1. In a Content SDK Next.js app, move the app's compilerOptions into a shared package and reference it from the app's tsconfig.json via "extends": "@acme/typescript-config/base.json" (leaving only baseUrl/paths inline).
  2. Ensure some component in the import-map scan paths has a plain (non-import type) import of an interface, used only in type positions.
  3. Run sitecore-tools project build, then next build.
  4. The generated .sitecore/import-map.ts contains the interface as a value: entry and type checking fails.

Reverting to fully inline compilerOptions in the app tsconfig.json produces a correct import map (type-only imports elided), confirming the unresolved extends is the cause.

Expected behavior

The codegen should resolve extends when loading the tsconfig. Notably, the same package already does this correctly elsewhere: tools/codegen/utils.ts has loadCompilerOptions(), which uses ts.parseJsonConfigFileContent() (resolves extends) with sane fallbacks. _getImportMap could reuse that helper instead of the raw ts.readConfigFile() result.

Version

@sitecore-content-sdk/* 2.2.1 (latest at time of writing), TypeScript 5.x, Next.js Pages Router, npm workspaces + Turborepo monorepo.

Workaround

Duplicate the shared compilerOptions inline in each app's tsconfig.json alongside extends (the inline copy is what the codegen sees; extends still serves tsc/editors).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in packages/content/src/tools/codegen/import-map.ts at _getImportMap, then compare its tsconfig loading with loadCompilerOptions() in tools/codegen/utils.ts. Reproduce with a tsconfig that extends a shared package and run sitecore-tools project build followed by next build. Done means the generated .sitecore/import-map.ts no longer emits type-only interfaces as runtime values when compilerOptions come from extends.

Written by the indexing model from the issue text.

Assessment

Tech stack
next.js, typescript
Domain
build-system, tooling
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
75/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.