Skip to content

Release 2.5.0: Vite 8, tests, bug fixes, SSR and TypeScript types - #46

Merged
pmochine merged 12 commits into
masterfrom
modernisierung-2026-10
Oct 6, 2026
Merged

pmochine merged 12 commits into
masterfrom
modernisierung-2026-10

Conversation

@pmochine

@pmochine pmochine commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Prepares release 2.5.0: new build tooling, tests, bug fixes, server-side rendering, TypeScript types and stop(). Merge with a merge commit, so that the single commits stay.

Changes

  • Tooling: Vite 3 → 8, @vitejs/plugin-vue 6, vite-plugin-css-injected-by-js 5, regenerated lockfile. This fixes all 29 open Dependabot alerts. All of them were dev dependencies, and the package has no runtime dependencies.
  • Tests: a new Vitest test base with 55 tests and a TypeScript compile check. A CI workflow runs lint, the tests and npm pack --dry-run on Node 22 and 24.
  • Bug fixes:
    • The fade-in did not run in Vue 3, because the class is now fade-enter-from.
    • The resize listener stayed after unmount.
    • sources was sorted in place.
    • A load timer threw after unmount.
    • Blocked autoplay showed a stopped video and emitted playing.
    • A missing file emitted no error.
    • canplay after buffering paused the video.
    • URLs such as video.mp4?v=1.2 got the type video/2 and never played.
  • Server-side rendering (Getting warnigns and errors with Node@v16.17.0, Nuxt@3.0.0-rc.11 and vue-responsive-video-background-player@2.3.1 #39, Problem with nuxt in static mode when running production #28): hydration works without a mismatch. The server renders the video without a source, and the browser adds the right one after hydration.
  • New, backward compatible:
  • Package:
    • exports with separate .d.ts and .d.mts types.
    • Peer dependency vue ^3.2.0.
    • "type": "commonjs".
    • The publish script is removed, because npm ran it after every npm publish. prepack builds dist/.
  • Docs and cleanup:
    • README for Vue 3, Nuxt 3/4 and TypeScript, and a new CHANGELOG.md.
    • Rebuilt demo bundle.
    • Unused babel.config.js and mix-manifest.json removed.

See CHANGELOG.md for the full list.

Testing

  • npm run lint, npm test (55 tests and the type check), npm run build and npm pack --dry-run all pass in fresh clones on Node 22.12 and 24.
  • The packed tarball (7 files) was tested in a separate project with Vue 3.5.43 and Vue 3.2.0:
    • ESM import, CommonJS require and UMD global.
    • Server rendering in Node.
    • Client mount and hydration in jsdom, with the dev and the production build of Vue.
  • @arethetypeswrong/cli reports no problems. publint reports no errors.
  • tsc passes with TypeScript 5.9, 6.0 and 7.0 for bundler, node16 ESM and node16 CJS resolution. vue-tsc passes for template usage.
  • Checked in Chrome:
    • The fade-in works.
    • The source switches on resize.
    • Hydration of a server-rendered page works.
    • A 404 emits error.
    • Blocked autoplay keeps the poster.
    • The demo page plays.

Notes

  • One new moderate advisory remains (postcss-selector-parser, via eslint-plugin-vue 9). It is dev-only and affects only linting. The fix needs ESLint 9, and eslint-config-avidofood does not support ESLint 9 yet.
  • After the merge, GitHub Pages serves the rebuilt demo.

🤖 Generated with Claude Code

pmochine and others added 12 commits October 6, 2026 14:38
- Vite 3 -> 8, @vitejs/plugin-vue 3 -> 6, vite-plugin-css-injected-by-js 2 -> 5.
- Regenerate package-lock.json. This removes the vulnerable dev
  dependencies that Dependabot reports (vite, esbuild, rollup, postcss,
  nanoid, js-yaml, minimatch, brace-expansion, flatted).
- Rename vite.config.js to vite.config.mjs. Vite 8 loads a .js config in a
  package without "type": "module" as CommonJS, and the CSS plugin is ESM
  only. "type": "module" is not an option because it breaks require() of
  the UMD file.
- Select the build with --mode instead of the LIB_NAME variable. This also
  works on Windows.
- Remove the "publish" script. npm runs a script with that name after every
  npm publish, so it started a second publish. The new "prepack" script
  builds dist before npm pack and npm publish.
- Add eslint-plugin-vue and eslint-plugin-import, which the avidofood
  ESLint config needs, and add a "lint" script. ESLint stays on 8 because
  eslint-config-airbnb-base does not support ESLint 9.
- Add Vitest 5, @vue/test-utils and jsdom for the tests in the next commit.
- Add .nvmrc (Node 24). Vite 8 and Vitest 5 need Node 20.19+ or 22.12+.
- Normalize the repository URL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The tests describe the current behavior of the component: rendering,
responsive sources, resizing, playback and the plugin. jsdom has no media
playback, so tests/setup.js stubs play(), pause() and load().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Remove the resize listener on unmount. removeEventListener got a new
  throttled function, so the listener stayed after every unmount.
- Do not sort the sources prop in place. The array belongs to the parent.
- Fade in the video in Vue 3. Vue 3 renamed the class v-enter to
  v-enter-from, so the fade-in did not run.
- Clear the pending load timer on unmount and on a new source. Before, the
  timer threw a TypeError after unmount, and fast source changes loaded
  every source.
- Handle the promise of video.play(). If the browser blocks playback (for
  example iOS in Low Power Mode, or an unmuted video), the poster stays
  visible and the component emits error with the reason. The component
  emits playing after playback really started. An AbortError from a new
  load is ignored.
- Handle the ready event once per loaded video. The browser fires canplay
  again after the video waited for data. Before, this paused the video,
  and with autoplay set to false it stayed paused.
- Do not emit paused for the internal pause before autoplay.
- Emit error when the <source> fails, for example on a 404. The browser
  fires that error on the <source> element, not on the <video> element.
  The error event now carries the event or the play() error.
- Set the type attribute only for known extensions (mp4, m4v, webm, ogv,
  ogg, m3u8). Before, "video.mp4?v=1.2" got "video/2" and a URL without
  an extension got an invalid type, so the browser skipped the video.
- Rename $_innerWidth to _innerWidth, as the 2.4.0 notes already said.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The server does not know the window width. Before, the server rendered
the source for a 0px window, and the browser measured the real width in
beforeMount, before the hydrating render. Poster and <source> then did
not match the server HTML, so Nuxt and other SSR setups showed hydration
warnings. The browser also started to load the wrong video before the
app hydrated.

Now the server renders the video without a <source>. During hydration the
first render matches the server, and the width is measured in mounted.
Vue then adds the <source> with the right video, and the browser loads it
by itself. A client-only app still measures in beforeMount, so its first
render is unchanged.

The check for hydration reads this.$.vnode.el, the same value that Vue
uses to decide to hydrate. $el does not work, because it is null in dev
builds at that time. The new tests also pass with the production build of
Vue.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
stop() pauses the video and sets it back to the start. Call play() to
start it again. Before, the only way to restart a video was load(), which
waits one second and shows the poster.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Add hand-written types in src/index.d.ts: props, sources, events, the
  player methods and the Plugin. They also register VideoBackground in
  GlobalComponents for template type checks.
- The build copies the types to dist/index.d.ts (CommonJS) and
  dist/index.d.mts (ESM). Without "type": "module", TypeScript reads a
  .d.ts file as CommonJS, so one file for both builds would be wrong.
- Add "types" conditions to "exports", a top-level "types" field and
  "./package.json" to "exports".
- Declare vue ^3.2.0 as a peer dependency. Before, vue was only a dev
  dependency, so npm did not check the Vue version. The build uses
  createElementBlock, which Vue 3.2 introduced.
- Add bugs and homepage fields.
- npm test now also runs a compile check of the types with TypeScript 5.9.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This only states what Node already assumed. The UMD file is CommonJS and
the ESM build uses the .mjs extension. publint suggests the field, so that
Node does not have to detect the module type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Installation for Vue 3 with app.component() and app.use(). The old
  example used the Vue 2 API (Vue.component, Vue.use).
- Vue 2 users install the 1x dist-tag (1.3.5) instead of 1.3.1.
- Nuxt 3 and 4: a normal plugin works now, because the component renders
  on the server. <ClientOnly> stays as an option.
- New sections for TypeScript, development and the stop() method.
- Events: the payload of error, ready once per video, the blocked
  autoplay case.
- Supported type attributes and the HLS limit (#44), and a custom
  transition duration (#29).
- Replace w3schools links with MDN.
- Move the changelog from the README to CHANGELOG.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A minor release: new, backward-compatible features (TypeScript types,
stop(), the error payload) and bug fixes. No breaking change, see
CHANGELOG.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GitHub Pages serves demo/public/build/js/app.js from master, so the demo
shows the fixed fade-in after the merge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Runs lint, the tests, the type check and npm pack --dry-run on Node 22
and 24 for pushes to master and for pull requests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- babel.config.js used the Vue CLI Babel preset. The project builds with
  Vite and does not install @vue/cli-plugin-babel.
- mix-manifest.json came from Laravel Mix, which the project no longer
  uses. Nothing reads the file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pmochine
pmochine merged commit d1fddd6 into master Oct 6, 2026
2 checks passed
@pmochine
pmochine deleted the modernisierung-2026-10 branch October 7, 2026 11:40
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