Skip to content

build(build-tools): rename typeCompatibility to .cts for future ESM flip#27377

Open
tylerbutler wants to merge 3 commits into
microsoft:mainfrom
tylerbutler:build-tools-typeCompat-cts
Open

build(build-tools): rename typeCompatibility to .cts for future ESM flip#27377
tylerbutler wants to merge 3 commits into
microsoft:mainfrom
tylerbutler:build-tools-typeCompat-cts

Conversation

@tylerbutler
Copy link
Copy Markdown
Member

Description

Renames build-tools/packages/build-tools/src/common/typeCompatibility.tstypeCompatibility.cts so it always emits CommonJS output (.cjs + .d.cts) regardless of the package's module type.

Why now (when the package is still CJS)

This is preparatory work for an eventual flip of @fluidframework/build-tools to "type": "module". Today the rename is a no-op behaviorally:

  • The package is still CJS, so emit ends up at the same location either way.
  • The single intra-package re-export in index.ts is updated to from "./common/typeCompatibility.cjs" (TypeScript's node16 moduleResolution maps the .cjs specifier to the .cts source).

But it lets us land the .cts rename + the long explanatory docstring on its own, separately from the eventual package.json type/exports flip, which will rely on this file being the require condition entry point for type-only consumers.

Background

The generated type test files across the repo do:

import type { TypeOnly, MinimalType, FullType, requireAssignableTo } from "@fluidframework/build-tools";

These tests are dual-compiled (ESM + CJS). When the CJS pass runs against an ESM-only build-tools, TypeScript throws TS1479 ("ESM module cannot be imported with require"). The standard fix is to expose a CJS-typed entry point via exports.require. Producing one requires a .cts source file — done here. The matching package.json exports map will come with the ESM flip PR.

A long docstring at the top of the renamed file explains all of the above for future readers.

Validation

From build-tools/packages/build-tools:

  • pnpm run clean && pnpm run tsc — clean; emit contains only typeCompatibility.cjs / .d.cts (no stale .js).
  • pnpm run eslint — clean.
  • pnpm run build:test && pnpm test:mocha — 137/137 passing.
  • pnpm build core-utils from the repo root — full client-release-group build still succeeds; type-test compilation in downstream packages is unaffected.

Minor incidental change

tsconfig.json"include" now lists both .ts and .cts. Required because TypeScript's default glob does not pick up .cts files.

Reviewer Guidance

The review process is outlined on this wiki page.

The file content is unchanged apart from the leading docstring. The only behavioral change is the emit extension. The follow-up ESM-flip PR will add the matching exports map entries.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 21, 2026

Hi! Thank you for opening this PR. Want me to review it?

Based on the diff (75 lines, 3 files), I've queued these reviewers:

  • Correctness — logic errors, race conditions, lifecycle issues
  • Security — vulnerabilities, secret exposure, injection
  • API Compatibility — breaking changes, release tags, type design
  • Performance — algorithmic regressions, memory leaks
  • Testing — coverage gaps, hollow tests

How this works

  • Adjust the reviewer set by ticking/unticking boxes above. Reviewer toggles alone don't trigger anything.

  • Tick Start review below to dispatch the review fleet.

  • After review finishes, tick Start review again to request another run — it auto-resets after each dispatch.

  • This comment updates as new commits land; your reviewer selections are preserved.

  • Start review

@tylerbutler tylerbutler marked this pull request as ready for review May 21, 2026 17:01
Copilot AI review requested due to automatic review settings May 21, 2026 17:01
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Prepares @fluidframework/build-tools for a future ESM flip by moving the type-test compatibility exports into a .cts source file so the emitted artifacts remain CommonJS (.cjs + .d.cts) regardless of package module type.

Changes:

  • Rename typeCompatibility.ts to typeCompatibility.cts and add an explanatory top-level docstring describing the ESM/CJS type-test motivation and constraints.
  • Update the root type-only re-export to target the .cjs specifier (so TS node16 resolution maps it back to the .cts source and later to .d.cts).
  • Expand the package tsconfig.json include globs to compile .cts sources.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
build-tools/packages/build-tools/tsconfig.json Include src/**/*.cts so the renamed .cts file participates in compilation/emit.
build-tools/packages/build-tools/src/index.ts Re-export type utilities via ./common/typeCompatibility.cjs to align with the .cts.cjs/.d.cts emit strategy.
build-tools/packages/build-tools/src/common/typeCompatibility.cts Move the type-test compatibility utilities to .cts and document why this is needed for the eventual ESM flip.

Comment thread build-tools/packages/build-tools/src/index.ts Outdated
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.

2 participants