Skip to content

Add a no-bundler example - #1574

Merged
tanem merged 1 commit into
masterfrom
no-bundler-example
Aug 4, 2026
Merged

Add a no-bundler example#1574
tanem merged 1 commit into
masterfrom
no-bundler-example

Conversation

@tanem

@tanem tanem commented Aug 4, 2026

Copy link
Copy Markdown
Owner

Dropping the UMD builds in 12.0.0 left script-tag users with a four-line esm.sh snippet in MIGRATION.md and no worked example. examples/no-bundler is the self-hosting half: a static page that imports dist/svg-injector.mjs by URL from a copy sitting next to it, injects an SVG, and shows that there is no window.SVGInjector.

Also adds a Without a bundler subsection under README Installation covering both forms, and links the example from the MIGRATION.md UMD entry.

Not a Vite app

It is the first example that is not a Vite app, and has to be. The plan was to keep it a Vite app and hide the library in public/, on the assumption that Vite leaves a public/ asset alone. It does not: Vite bundles every <script type="module"> in index.html whatever its src resolves to. Measured on Vite 8.2.0:

src result
./app.mjs build fails, Failed to resolve ./app.mjs from index.html
/app.mjs build succeeds, but emits a bundled chunk into <head> and leaves the original tag in the body, so the module runs twice

So npm run build is node build.js, which copies index.html, svg.svg and the library's .mjs into dist/. That is what a self-hosting consumer does anyway, and it makes the "no bundler" claim true of the example itself rather than only of the page it serves. npm start serves dist/ with serve, already a root devDependency.

Two details of the copy, both noted in the example README:

  • The library is read from node_modules/@tanem/svg-injector/dist/svg-injector.mjs by path, because the exports map makes every path inside the package private apart from the root entry and package.json.
  • svg-injector.mjs.map is copied with it, because the .mjs ends with a sourceMappingURL comment.

All the harness needs from an example is an npm run build that fills <example>/dist/. AGENTS.md now says so, and records the exception.

Verification

npm test green. The new test asserts the negative directly: no request under assets/, and a real request for svg-injector.mjs. Every other example ships a Vite chunk there, so its absence is what says the page really resolved the library by URL in the browser.

Checked by hand in Chrome 151 as well: three requests — page, module, SVG — and no console output.

🤖 Generated with Claude Code

Dropping the UMD builds in 12.0.0 left script-tag users with a four-line
esm.sh snippet in MIGRATION.md and no worked example. This is the
self-hosting half: a static page that imports dist/svg-injector.mjs by
URL from a copy sitting next to it.

It is the first example that is not a Vite app, and has to be. Vite
bundles every `<script type="module">` in index.html whatever its src
resolves to, `public/` included: on Vite 8.2.0 a relative src fails the
build outright, and an absolute one emits a chunk into <head> while
leaving the original tag in place, so the module runs twice. Its
`npm run build` copies the page and the library into dist/ instead,
which is what a self-hosting consumer does anyway.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@tanem
tanem merged commit 6404bc8 into master Aug 4, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant