Skip to content

Modernize tooling, require React 18 and fix cache boundary bugs - #6

Merged
devmaxxx merged 1 commit into
masterfrom
chore/modernize-react18-tsdown
Oct 16, 2026
Merged

devmaxxx merged 1 commit into
masterfrom
chore/modernize-react18-tsdown

Conversation

@devmaxxx

Copy link
Copy Markdown
Owner

Summary

Audit of the package: tooling brought up to date, React 18 made the minimum, the bugs below fixed, and an end-to-end suite added.

Tooling

  • microbundle-crl → tsdown: ESM + CJS with type declarations through exports, checked by publint.
  • yarn → pnpm workspace; the CRA example is now a Vite app that imports the built package.
  • react-scripts/Jest → Vitest; new Playwright e2e suite against the example in Chromium, Firefox and WebKit.
  • ESLint 6 → ESLint 10 flat config; Travis → GitHub Actions (React 18.0 / 18.3 / 19 unit matrix, CLI on Node 18–24, e2e).
  • html-validate checks the source and the built index.html.

Bug fixes

  • generate-build-meta crashed (mkdirp was never a dependency), had no shebang, and exited 0 on failure. It now uses only Node built-ins (no runtime dependencies left) and supersedes the mkdirp fix from Fix: fix mkdirp error #5.
  • Focus and every state update started a new polling interval without clearing the old one; polling kept running while the window was blurred and ignored later duration/auto changes.
  • clearCacheAndReload stored the old version, and a meta file without version reloaded forever with auto.
  • Without auto, the new version was stored before the user reloaded, so a plain reload hid the update.
  • An error thrown while loading was swallowed; errors now reach the parent boundary through getDerivedStateFromError.
  • The meta file was always fetched from the site root; ./, ../, absolute paths and URLs are honoured, and an SPA fallback answering meta.json with HTML is detected instead of parsed.
  • lazyRetry(fn, 0) retried forever and made one attempt fewer than asked.
  • Error checkers built from a /g regexp answered differently on each call.
  • Stale-chunk errors not recognised before: Vite CSS preload, native import() in Chrome/Firefox/Safari (including Safari's 'text/html' is not a valid JavaScript MIME type when the chunk URL returns HTML — found by the WebKit e2e run), webpack CSS chunks.
  • A throwing debug callback could leave the fallback up forever.

Breaking changes

  • react >= 18 peer; the CLI needs Node.js >= 18.3.
  • lazyRetry(fn, retries) now makes retries extra attempts (default: 3 attempts in total instead of 2).
  • See "Migrating from 0.2" in the README.

Test plan

  • pnpm test — lint + html-validate, build + publint, typecheck, 43 unit tests, 21 e2e tests (7 scenarios × 3 browsers)
  • Unit tests on React 18.0.0, 18.3.1 and 19.3.1
  • CLI on Node 18.20 with and without --destination, failure path exits 1
  • CI green on this PR

Replace microbundle-crl, CRA, yarn and Travis with tsdown (ESM + CJS with
types through exports), a Vite example in a pnpm workspace, Vitest,
Playwright, ESLint flat config and GitHub Actions. React 18 is now the
minimum peer version.

Fix bugs found in the audit:
- generate-build-meta crashed because mkdirp was never a dependency, had no
  shebang, and exited 0 when it could not write the file
- focus and every state update started a new polling interval without
  clearing the old one, and polling kept running while the window was blurred
- clearCacheAndReload stored the old version, and a meta file without a
  version reloaded forever with auto
- without auto, the new version was stored before the user reloaded, so a
  plain reload hid the update
- an error thrown while loading was swallowed; errors are now rethrown to the
  parent boundary through getDerivedStateFromError
- the meta file was always fetched from the site root; relative paths and
  URLs are now honoured, and an SPA fallback answering with HTML is detected
- lazyRetry(fn, 0) retried forever and made one attempt fewer than asked
- error checkers built from a /g regexp answered differently on each call
- chunk errors from Vite, native import() in Chrome, Firefox and Safari, and
  webpack CSS chunks were not recognised

BREAKING CHANGE: React >= 18 and Node.js >= 18.3 for the CLI are required,
and lazyRetry's retries now counts extra attempts.
@devmaxxx
devmaxxx merged commit b352f8d into master Oct 16, 2026
9 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.

1 participant