Bundling
A plugin ships as one main.js, but you don't write it as one file. Split your source into as many modules as you want and bundle them. The app imports exactly one file (a data: URL import can't resolve relative imports), so bundling is how multi-file plugins work — the same model Obsidian and VS Code use.
esbuild
The template is set up with esbuild:
esbuild src/main.ts --bundle --format=esm --outfile=main.js --minify
That inlines every local import into main.js. Assets go in the same bundle, no second file to host:
# CSS as an injected string, images as data URIs
esbuild src/main.ts --bundle --format=esm --outfile=main.js \
--loader:.css=text --loader:.png=dataurl
Rules
- Output a single ES module that default-exports
{ activate }. - Don't bundle React or Glyph internals. The host provides what you need through
ctx. (When the API hands you a host object you'd otherwise import, mark it--external.) - Keep it readable.
--minifyis fine; obfuscation will be rejected in marketplace review. - The type-only
import type { ... } from "glyph"is dropped by the bundler — there's no runtimeglyphpackage; the types come fromtypes/glyph.d.tsin the template.