microsoft / microsoft/vscode-documentdb

@microsoft/vscode-ext-webview: ship an ESM (dual ESM+CJS) build

Open
#824 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
31
Forks
22
Avg merge
2d 20h
Merged PRs (30d)
21

Description

Summary

@microsoft/vscode-ext-webview (in packages/vscode-ext-webview) is currently CommonJS only: no "type": "module", no import condition in exports, and its entry barrels re-export through tslib's dynamic __exportStar (a runtime for..in copy). We should ship a dual ESM + CJS build so bundlers can resolve the package's named exports statically.

Motivation

This is a hygiene and robustness item, not a bug fix. To be clear: the recent Cosmos DB webview failure (microsoft/vscode-cosmosdb#3217) turned out to be an unrelated dev-server port collision, not a packaging problem. But the CJS-only shape has real, remaining downsides:

  • Bundlers cannot statically analyze __exportStar re-exports. Vite's dep optimizer can only emit export default require_x() (zero named exports), and correctness depends entirely on Vite's needsInterop rewrite firing. It does fire today, but it is a single point of failure.
  • Consumers pay a __commonJSMin lazy-wrapper per module and lose tree-shaking across the barrel.
  • One genuine failure mode is reproducible in isolation: mark react external and bundle the CJS package to ESM, and rolldown emits a bare require("react") that throws "Calling require for 'react' in an environment that doesn't expose the require function". Not the default config, but a real trap for other consumers.
  • Consumers currently need optimizeDeps.include workarounds purely because the package is CJS (see the three subpaths added in microsoft/vscode-cosmosdb#3217).

The starter kit (tnaum-ms/vscode-webview-starter-kit) uses webpack, so this class of problem never surfaces there, and package CI does not currently cover the Vite / rolldown path.

Proposed plan

  1. Add an ESM build alongside CJS; wire exports conditions (types first, then import to ESM, require to CJS) for all four subpaths (., ./host, ./react, ./webview). Watch for the dual-package hazard on anything holding module state (the WeakMap in react/connection.ts, getWebviewConnection, is the one to check).
  2. In the ESM output use static export { X } from './...' instead of __exportStar, so every bundler resolves names statically.
  3. Consider renaming the emitted subpath entry file so its basename does not collide with the real react package (for example emit ./react from dist/react-surface.js); keep the public ./react subpath unchanged. Cosmetic today, but it makes bundler output far easier to read when debugging.
  4. Add a bundler smoke-test matrix to CI: vite serve plus vite build (with code splitting), webpack, and esbuild, each asserting the named exports resolve at runtime. This is the check that would have made the recent investigation unnecessary.
  5. Once shipped, consumers can drop their optimizeDeps.include entries (cosmosdb: remove the three ext-webview subpaths added in #3217).

References

  • Consumer migration that surfaced this: microsoft/vscode-cosmosdb#3217

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/vscode-ext-webview, reviewing its entry barrels, package metadata, build configuration, and react/connection.ts, especially the WeakMap state. Check how the four public subpaths are currently emitted and exported, then run the existing package checks before adding the proposed Vite, webpack, and esbuild smoke tests. Done means dual ESM/CJS outputs, correct conditional exports, static ESM names, and passing runtime checks without relying on consumer workarounds.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript, vite, webpack
Domain
build-system, testing-qa, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.