Skip to content

Library-build path: --external, --dts, --library- #94 - #90

Merged
gronke merged 5 commits into
mainfrom
feat/library-build-mode
Sep 4, 2026
Merged

gronke merged 5 commits into
mainfrom
feat/library-build-mode

Conversation

@gronke

@gronke gronke commented Sep 4, 2026

Copy link
Copy Markdown
Owner

build gains a library path: an npm package as output rather than a deployable site, so a TypeScript element library builds with web-modules as the only compiler, no Node toolchain.

  • --external <spec> (repeatable; web_modules.external) marks a bare import intentionally unresolved: a peer dependency's import … from "lit" survives the unresolved-import check and stays bare in the output. A bare name covers its subpaths, so --external lit also allows lit/decorators.js.
  • --dts / --no-dts (web_modules.dts) emits a .d.ts beside each compiled module via isolatedDeclarations, which existed and was tested but had no caller. Every module boundary must carry an explicit type, so a source that omits one fails the build; a bundling build skips it.
  • --library (alias --no-page; web_modules.library / noPage) skips the synthesized fallback index.html and the standalone importmap.json a library build would only delete. The .web-modules-out marker survives, so a rebuild in place works; a source-provided index.html is still emitted. Deliberately not a --force bypass of ensure_replaceable: that guard is what makes a mistyped --out . safe.

The docs also record a property found along the way: a /*! @license */ above a type-only declaration that erases is kept, where tsc drops it with the declaration.

A library with a peer dependency must emit `import … from "lit"` without vendoring it.
The build otherwise fails any bare import the generated import map cannot resolve, which is right for an application and wrong for a library.

`--external <spec>` (repeatable, also a `web_modules.external` package.json key) registers a specifier as intentionally unresolved: it is dropped from the unresolved-import check - and since nothing vendors it, the emitted code keeps the bare import verbatim. A bare name covers its subpaths, so `--external lit` also allows `lit/decorators.js`.
`emit_dts` (isolatedDeclarations via oxc) was implemented and tested but only a library call: no CLI flag, no manifest key, and the build never invoked it, so a TypeScript library still had to run `tsc --emitDeclarationOnly` for its typings.

`--dts` / `--no-dts` (and a `web_modules.dts` package.json key) emit a `.d.ts` beside each compiled module, so a TS library builds with no Node toolchain at all.
isolatedDeclarations requires an explicit type at every module boundary, so it is opt-in by nature — a source that omits one fails the build.
A bundling build skips it, since the modules are inlined.
A library build produces modules, not a deployable page, yet every build synthesized a fallback `index.html` (a shell pointing at an `app.js` that does not exist) and a standalone `importmap.json`.
A library build only deleted them afterward, and deleting them took the `.web-modules-out` marker with them, forcing an `rm -rf` on the next build.

`--library` (alias `--no-page`, also a `web_modules.library` / `noPage` key) skips both.
A source-provided `index.html` is still emitted, and the marker is untouched, so a rebuild into the same directory just works.
Deliberately not a `--force` that bypasses `ensure_replaceable`: that guard is what makes a mistyped `--out .` safe, and the root cause is the scaffolding, not the guard.
Document `--external`, `--dts` and `--library` in a "Library builds" section, add `dts` to the processor-toggle list, and record that a legal comment above a type-only declaration that erases (a leading `interface`/`type`) is preserved, where `tsc` drops it with the declaration — a licence-preservation property.
The library-build insertion placed emit_dts_sidecar between emit_winner and its doc comment, merging the two blocks and leaving emit_winner undocumented.
@gronke
gronke merged commit 08db3ee into main Sep 4, 2026
9 checks passed
@gronke
gronke deleted the feat/library-build-mode branch September 4, 2026 08:15
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.

1 participant