Skip to content

feat(warp): add moduleType: commonjs to CJS target in warp.config.yml#3872

Closed
deyaaeldeen wants to merge 1 commit intomainfrom
warp-cjs-module-type
Closed

feat(warp): add moduleType: commonjs to CJS target in warp.config.yml#3872
deyaaeldeen wants to merge 1 commit intomainfrom
warp-cjs-module-type

Conversation

@deyaaeldeen
Copy link
Copy Markdown
Member

Summary

The warp build tool in azure-sdk-for-js now supports an explicit moduleType field on targets in warp.config.yml. When a CJS target declares moduleType: commonjs and its program identity (excluding moduleType) matches an already-emitted ESM target, warp skips running tsc entirely and transforms the ESM output to CJS via esbuild instead. This dramatically speeds up CJS compilation.

Changes

  • Template (packages/rlc-common/src/metadata/buildWarpConfig.ts): Added moduleType: commonjs to the CJS target in WarpConfigTemplate
  • Test fixtures (81 files): Updated all generated warp.config.yml files to include the new field

Related

… template

The warp build tool now supports an explicit `moduleType` field on targets,
which enables esbuild ESM→CJS transform dedup (when a CJS target's program
identity matches an already-emitted ESM target, tsc is skipped and the ESM
output is transformed to CJS via esbuild instead).

This change adds `moduleType: commonjs` to the CJS target in the
WarpConfigTemplate, and updates all 81 generated test fixtures to match.

Related: Azure/azure-sdk-for-js#37893

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@MaryGao
Copy link
Copy Markdown
Member

MaryGao commented Mar 31, 2026

Need to merge SDK pr first: Azure/azure-sdk-for-js#37893

@qiaozha qiaozha added P1 priority 1 HRLC labels Apr 1, 2026
deyaaeldeen added a commit to Azure/azure-sdk-for-js that referenced this pull request Apr 3, 2026
…37893)

## Problem

Warp currently emits CommonJS output by setting `module: "CommonJS"` and
`moduleResolution: "Node10"` in CJS tsconfigs. This creates several
problems:

1. **IDE and tooling mismatch**: The tsconfig on disk says Node10, but
warp silently upgrades to Node16 at compile time. This means VS Code,
eslint, api-extractor, and any other tsc-based tool sees a different
module resolution than warp uses, causing phantom errors and
inconsistent behavior.

2. **Implicit virtual package.json**: Warp had an `inferModuleType`
function that detected `module: "CommonJS"` in the tsconfig and
implicitly injected a virtual `{"type":"commonjs"}` package.json —
behavior that was invisible and hard to debug.

3. **Blocks TypeScript v6/v7 migration**: TypeScript is deprecating
`moduleResolution: "Node10"` and `module: "CommonJS"`. Future TypeScript
versions will only support `Node16`/`NodeNext` module resolution. Our
current CJS tsconfigs would fail to parse.

## Solution

### Explicit `moduleType` in warp config

Instead of inferring CJS from the tsconfig, each warp target now
declares `moduleType: "commonjs"` explicitly. The tsconfig on disk uses
`module: "Node16"` / `moduleResolution: "Node16"` — the same resolution
that every tool sees. Warp injects the virtual `{"type":"commonjs"}`
package.json only when `moduleType` is set, making the behavior explicit
and auditable.

### esbuild CJS from TypeScript sources

When a CJS target has the same source graph as an already-emitted ESM
target (same files, same resolved imports, same emit options — differing
only in `moduleType`), warp skips tsc entirely and uses esbuild to build
CJS directly from the original `.ts` source files. For each source file,
esbuild strips types and emits CommonJS with `format: "cjs"`, `loader:
"ts"`. Declaration files (`.d.ts`, `.d.ts.map`) are copied from the ESM
output since they are identical between targets.

This approach has three key advantages over the previous ESM `.js` → CJS
`.js` transform:
- **Correct source maps**: Maps point directly to `.ts` sources, not
`.js` intermediaries
- **Preserves directory paths**: Subdirectory files get full relative
paths in source maps (e.g. `../../src/internal/helper.ts` instead of
`helper.js`)
- **Structured error handling**: Build failures are caught and returned
as `CompileResult` instead of propagating raw exceptions

## Changes

### Compiler
- `buildCjsFromSources`: New function replaces `transformEsmToCjs`.
Reads `.ts` source files from `rootDir`, runs `esbuild.transform` with
`format: "cjs"`, `loader: "ts"`, writes `.js` + `.js.map` to CJS
`outDir`, copies `.d.ts` from ESM output.
- `programIdentity` includes `moduleType` to prevent ESM/CJS dedup bugs
- CJS fast-path errors are caught and returned as structured
`CompileResult` failures
- Removed `inferModuleType` — no implicit behavior, no Node10 fallback
- Removed dead `json` option from `BuildOptions` (JSON output handled in
CLI only)

### Config
- All ~440 CJS `warp.config.yml` targets now have `moduleType: commonjs`
- `tsconfig.src.cjs.json` extends `tsconfig.src.esm.json` (only
overrides `outDir`)
- `warp.base.config.yml` sets `moduleType: commonjs` on the CJS target
(inherited by 340+ packages)
- Backward compatibility: `condition: "require"` infers `moduleType:
"commonjs"` when not set

### Worker & error handling
- `try/catch` around `runCompilation` in worker to prevent silent worker
death
- Worker crash results report `packageRoot` as `outDir` fallback (not
tsconfig path)

### Tests
- Source map tests verify CJS maps point to `.ts` sources
- Subdirectory source map path preservation (regression test for
basename bug)
- `sourceMappingURL` comment presence in CJS output
- Polyfill + dedup + CJS triple interaction test

## Related PRs

- Codegen (autorest.typescript):
Azure/autorest.typescript#3872

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
deyaaeldeen added a commit that referenced this pull request Apr 6, 2026
…r others

Azure monorepo packages now generate warp.config.yml files that use
`extends: ../../../warp.base.config.yml` instead of inlining the full
config. Non-Azure packages get the full inline config with
`moduleType: commonjs` on the CJS target for faster builds via
esbuild ESM-to-CJS transform.

Combines the approaches from #3872 and #3889.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@deyaaeldeen
Copy link
Copy Markdown
Member Author

Superseded by #3895 which combines this with #3889.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

HRLC P1 priority 1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants