Sitecore / Sitecore/content-sdk
Import-map codegen ignores tsconfig `extends`, emitting type-only imports as runtime values
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
- In a Content SDK Next.js app, move the app's
compilerOptionsinto a shared package and reference it from the app'stsconfig.jsonvia"extends": "@acme/typescript-config/base.json"(leaving onlybaseUrl/pathsinline). - Ensure some component in the import-map scan paths has a plain (non-
import type) import of an interface, used only in type positions. - Run
sitecore-tools project build, thennext build. - The generated
.sitecore/import-map.tscontains the interface as avalue: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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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