Skip to content

feat!: let plugins expose subpath entry points via plugin:<id>/<subpath> - #113

Merged
oglassdev merged 5 commits into
mainfrom
feat/plugin-specifiers
Oct 8, 2026
Merged

oglassdev merged 5 commits into
mainfrom
feat/plugin-specifiers

Conversation

@oglassdev

Copy link
Copy Markdown
Contributor

A plugin could expose only one module to pack sources, its config, so plugins with a larger authoring API couldn't split it into entry points. Window wants its low-level API at plugin:window/raw beside plugin:window. The # specifiers also read like package-internal imports when they're really provided by the host.

Plugins can now declare extra modules in rpp.json:

{ "config": "src/config.ts", "exports": { "./raw": "src/raw.ts" } }

Pack sources and rpp.config.ts import them as plugin:<name>/<subpath>, and plugin:<name> still means the config module. Every import uses a scheme now:

Before After
#rpp rpp
#rpp/config rpp:config
#rpp/jsx rpp:jsx
#plugins/<name> plugin:<name>

This is a breaking change with no alias: #rpp and #plugins/ no longer resolve. Bundle errors for them name the new specifiers. Published plugin archives import #rpp, so they have to be republished (Window included).

Closes #112.

Details

  • exports keys must be ./<relative path>. Undeclared subpaths fail in both the bundler and tsc, since codegen writes one exact paths entry per module. Entries that share a package directory bundle shared modules once.
  • rpp plugin pack builds each export to dist/exports/<subpath>.js, adds a .d.ts stub and isolated declarations for it, aliases plugin:<self>/<subpath>, and rewrites exports in the packed manifest. Facade chunks (pure re-exports) no longer fail packing for lacking a source map.
  • Internal virtual modules moved to rpp:internal/* so they don't sit next to user-facing rpp: modules.
  • I tested scheme specifiers through tsconfig paths under moduleResolution: "Bundler" on TypeScript 5 and 7, including rpp:jsx/jsx-runtime.

Validation

  • Tests pass for rpp-js, rpp --features js and rpp-cli. New tests cover subpath module sharing, packing exports, importing a subpath from a discovered file, the rename hint, codegen paths and the packed manifest.
  • just lint, just fmt-check and just check-features pass. I didn't run verify-jvm locally; the JVM example's import change is covered in CI.

AGENTS.md still says the SDK is imported as #rpp. I left it alone because it shouldn't change without being asked.

🤖 Generated with Claude Code

Plugins declare extra entry modules in rpp.json `exports`, imported as
`plugin:<name>/<subpath>` next to `plugin:<name>` for the config module.
The SDK moves to `rpp`, `rpp:config` and `rpp:jsx`; internal virtual
modules move under `rpp:internal/`. The `#rpp` and `#plugins/`
specifiers no longer resolve, and bundle errors for them point at the new
names.

Closes #112
- Resolve chunk source map sources against the map's directory, so nested
  export maps point at the original files.
- Bundle type-only entries, which produce no source map.
- Resolve a plugin's own plugin:<id>[/<subpath>] modules when loading it
  without discovery, and map them in plugin-project codegen.
A plugin without discovery that imports its own config module needs the
config SDK the module imports.
@oglassdev
oglassdev merged commit 121b31a into main Oct 8, 2026
9 of 11 checks passed
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.

Plugin subpath entry points and a plugin: specifier scheme

1 participant