Skip to content

Phase 2: Migrate build tooling from webpack to Rspack (spike Rsbuild first) #73

Description

@amcclain

Follow-on to #72 (Phase 1 cleanup - complete that first so the port carries only re-verified config). Full analysis with ecosystem research, feature-portability table, and honest risk ledger: bundler-migration-analysis.md (branch claude/webpack-vite-migration-2mcey2).

Summary of the recommendation (Aug 2026)

Migrate to Rspack, prototyping with Rsbuild (its higher-level wrapper). Rspack is a Rust-based, webpack-API-compatible bundler: our config model, loaders, dev-server/proxy setup, and - critically - the "transpile raw hoist-react TS from node_modules alongside the app" distribution model carry over nearly unchanged. SWC replaces Babel (~5-10x on transpile-bound work) and built-in React Fast Refresh replaces today's SCSS-only HMR / full-page live reloads.

Not Vite today - re-evaluate ~mid-2027. Vite 8's Oxc transformer cannot yet lower TC39 stage-3 decorators (collides with the hoist-react #4333 migration), its HTML/dep model inverts ours (raw-TS framework dep = dev request waterfall until Bundled Dev Mode stabilizes), and default dev is still unbundled vs. bundled prod. All actively closing; the Rspack port doubles as the work plan if the calculus flips.

Sequencing vs. the decorators migration (hoist-react #4333 / dev-utils #66): not a blocker in either direction - SWC natively supports legacy decorators (its default, heavily battle-tested mode) and 2023-11. Bundler-first spends near-zero app-facing change budget (no app source touched); decorators-first validates only one transpiler×decorator combination. Either order works; never ship both in the same release window.

Spike scope (go/no-go with real numbers, ~1-2 wks)

Build a configureRsbuild() (fallback: raw Rspack config) in this repo and validate against Toolbox:

  • All 10 Toolbox entry points discovered from src/apps/*, per-app HTML + manifest.json generation
  • Raw-TS transpilation of @xh/hoist + @xh/package-template via builtin:swc-loader include paths (pnpm symlink-resolution parity with v14 behavior)
  • inlineHoist mode (alias mechanics for @xh/hoist, react, react-dom, ag-grid-react)
  • Decorator parity gates: run hoist-react #4333's Phase 0 spike runner (22 runtime gates) against SWC output - legacy mode now, 2023-11 after #4333; set class-field semantics (useDefineForClassFields equivalent) explicitly
  • xh* DefinePlugin globals, changelog .xhtmp alias, Blueprint icon stubs (as plain resolve.alias entries), FontAwesome via transformImport, SCSS pipeline, markdown-as-text (+ ?url), moment IgnorePlugin, public-dir copy
  • Dev server: proxy to Grails, per-app historyApiFallback, HTTPS options, overlay
  • React Fast Refresh behavior with Hoist idioms (hoistCmp.factory element-factory exports and model files may fall back to full reload - measure actual behavior)
  • SWC minifier parity with our Terser stance (post-Phase 1: Cleanup release - shed obsolete build config, gate polyfill-layer removal #72 stance, i.e. whatever mangle decision Phase 1 lands on)
  • Prod build output diff vs. webpack build (chunking, hashed names, CSS extraction, bundle sizes)
  • Measurements: cold dev-server start, incremental rebuild, HMR round-trip, prod build time, peak memory (current baseline requires --max_old_space_size=3072)

Ship

  • New dev-utils major exporting both configureWebpack (frozen, maintenance) and the new function; env-option surface kept recognizably the same (~30 options, most 1:1)
  • Migrate Toolbox, then customer apps opportunistically
  • Update hoist-react docs/version-compatibility.md (new row + any pairing constraints)
  • Soak time before/after any decorators release (separate windows rule)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions