Skip to content

docs: note that TypeScript applies the browser condition only on opt-in - #731

Merged
sroussey merged 1 commit into
claude/wonderful-turing-rjtcnx-ai-typesfrom
claude/optimistic-goldberg-9x9lby-browser-conditions
Aug 9, 2026
Merged

docs: note that TypeScript applies the browser condition only on opt-in#731
sroussey merged 1 commit into
claude/wonderful-turing-rjtcnx-ai-typesfrom
claude/optimistic-goldberg-9x9lby-browser-conditions

Conversation

@sroussey

@sroussey sroussey commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

The manifest fix in #717 is complete and uniform — every condition branch now pairs its types target with the implementation beside it, and ExportTypesPairing.test.ts enforces that across all 163 branches. But a correct manifest is only half of the story.

TypeScript's condition set is ["import", "types"] under moduleResolution: "bundler" and ["node", "import", "types"] under node16/nodenext. "browser" is in neither, and TypeScript only applies it when the consumer names it in customConditions. So a plain bundler-mode consumer still bundles dist/browser.js while tsc resolves the outer "types" and type-checks it against the node declarations — no error anywhere, and symbols the browser bundle genuinely omits (_testOnly, OpenAI_ImageValidation, OpenAI_ModelSearch in @workglow/openai/ai) still autocomplete and compile, then read undefined at runtime.

The correct manifests do not fix that on their own; they move the drift from the manifest to the consumer's tsconfig. This PR says so where the rule is stated.

Changes

  • docs/technical/19-build-system.md — a paragraph in Conditional Exports stating the opt-in, with the tsconfig snippet and examples/web/tsconfig.json as the in-repo example.
  • docs/technical/18-multi-runtime-abstraction.md — one sentence on the same claim in the resolution-rules paragraph, linking to the section above.
  • packages/test/src/test/util/ExportTypesPairing.test.ts — one assertion that examples/web sets customConditions: ["browser"]. It is the repo's only browser-bundled TypeScript project and it imports packages carrying browser conditions (@workglow/util, @workglow/indexeddb/storage, @workglow/tf-mediapipe/ai); deleting that one line silently reverts it to node declarations with nothing failing. Verified by mutation — removing the line fails the test.

Deliberately not added: a test that string-matches the doc prose. Nothing under packages/test reads docs/, and such a test breaks on rewording without catching any real defect.

Known follow-up (separate repo)

/home/user/builder's packages/app is exactly the consumer described above: tsconfig.app.json is moduleResolution: "bundler" with no customConditions, and it imports @workglow/anthropic/ai, @workglow/deepseek/ai, @workglow/openai/ai and @workglow/tf-mediapipe/ai. It (and the six other bundler-mode tsconfigs there) should gain "customConditions": ["browser"] — a separate PR in a separate repo.

Also out of scope: converging the node and browser barrels (dropping _testOnly from node barrels, exporting browser-safe modules from browser barrels). That is a public-API change across at least 8 provider packages and would obscure the manifest-correctness verification this branch already carries.

Verification

command result
bun scripts/test.ts util vitest 50 files passed, 731 passed / 10 skipped
bunx prettier --check (18, test file) clean
bunx prettier --check docs/technical/19-build-system.md fails — pre-existing, verified unclean on the base commit with the change stashed; the added paragraph itself is prettier-stable
bunx eslint …/ExportTypesPairing.test.ts --max-warnings 0 clean
bunx tsc --showConfig -p examples/web/tsconfig.json customConditions present

One deviation from the plan: tsconfig.json is JSONC (examples/web/tsconfig.json carries /* Bundler mode */ comments), so a bare JSON.parse throws. The test strips comments first via a small local helper.


Generated by Claude Code

Correct `exports` manifests pair each condition's `types` with the
implementation beside it, but TypeScript's own condition set is
["import", "types"] under moduleResolution "bundler" and
["node", "import", "types"] under node16/nodenext — "browser" is in
neither. A browser app therefore bundles dist/browser.js while tsc
type-checks it against the node declarations unless the consumer sets
customConditions: ["browser"].

Document that in the Conditional Exports section and in the
multi-runtime resolution rules, and pin examples/web's opt-in with an
assertion so deleting that one line fails loudly instead of silently
reverting the example project to node declarations.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013oVdDSRMJeALBPLDQf3DgH
@sroussey
sroussey merged commit fcda0c0 into claude/wonderful-turing-rjtcnx-ai-types Aug 9, 2026
9 of 10 checks passed
@sroussey
sroussey deleted the claude/optimistic-goldberg-9x9lby-browser-conditions branch August 9, 2026 19:03
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