feat(dev-server): default linux dev to the rspack server - #1229
Merged
Conversation
The rspack config hardcoded the three dev knobs to their macOS values, so `ORGII_RSPACK=true` on Linux produced a bundle WebKitGTK cannot boot. Port the gates from config/webpack.config.js (lines 35-48) verbatim: - eagerDevApp -> DefinePlugin ORGII_DEV_EAGER_APP, so src/index.tsx inlines App via `webpackMode: "eager"` instead of emitting a runtime chunk that WebKitGTK fails to load. - retryMainScriptLoad -> HtmlWebpackPlugin `inject: false` plus the option the index.html retry loader reads. - devtool -> `cheap-source-map` when eager, keeping main.js well under the ~80 MB WebKitGTK limit that eval-* source maps would blow past. Platform selection is unchanged: createFrontendScriptName still defaults Linux to the webpack server, and `ORGII_RSPACK=true` opts in. Verified on Linux (X11, WebKitGTK 2.50.4) against the webpack dev server on the same machine, run sequentially: cold compile 9.8 s vs 22.6 s (webpack had a warm 2.4 GB filesystem cache, rspack none), HMR 0.55 s vs 1.95 s, peak RSS 1.67 GiB vs 3.51 GiB, main.js 27.0 MB vs 32.9 MB. A real `ORGII_RSPACK=true pnpm tauri:dev` boot renders the full IDE UI, so lazy-loaded chunks resolve under WebKitGTK, and two consecutive edits hot replaced without a page reload (workspace tree state survived). Pre-commit hook ran. Total eslint: 0, total circular: 0
config/rspack.config.js now carries the WebKitGTK eager-App + retry-loader path, verified against a real Tauri boot on WebKitGTK 2.50.4: full IDE UI rendered, lazy chunks resolved, HMR confirmed a hot replace (state kept). Measured on Linux, 2026-09-02, same commit, both bundlers cold with no cache, sequential runs: cold compile 3.2s vs 18.0s, HMR 0.40-0.45s vs 1.9-3.1s, idle RSS 1.41GiB vs 3.55GiB, 'pnpm tauri:dev' main.js ready 3.7s (webpack's last recorded run: 27.9s). Windows keeps the webpack default: it has not been exercised on rspack. ORGII_RSPACK=false / --webpack / 'pnpm tauri:dev:webpack' still opt out. Pre-commit hook ran. Total eslint: 0, total circular: 0
Harry19081
self-requested a review
September 3, 2026 03:59
Harry19081
approved these changes
Sep 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Linux desktop development still runs the webpack dev server, while macOS has
been on rspack since #1174. On the current
developcommit that costs Linuxdevelopers, per measurement below: an 18.0 s cold compile, 1.9-3.1 s per HMR
round-trip, 3.55 GiB idle RSS, and
pnpm tauri:devnot servingmain.jsuntil ~27.9 s.
Linux was excluded from #1174 for a concrete reason, not an oversight:
config/rspack.config.jsdid not carry the three WebKitGTK accommodationsthat
config/webpack.config.jshas (lines 35-48, 589-590, 694-717). Linux devruns under WebKitGTK, which cannot load
Appas a runtime dynamic-importchunk (commit 291f95b) and stalls on the injected
<script>tag; and aneval-*devtool inlines every module's source intomain.js, pushing it pastthe ~80 MB WebKitGTK can load.
Solution
Two commits, in order:
feat(rspack-config): support the linux webkitgtk dev path— port thethree platform gates from
config/webpack.config.jsintoconfig/rspack.config.js:retryMainScriptLoad(external retrying loaderinstead of an injected
<script>, sohtml.inject: false),eagerDevApp(
Appinlined intomain.jsviawebpackMode: "eager", wired throughDefinePluginas the inlineprocess.env.ORGII_DEV_EAGER_APPexpressionthat
src/index.tsx:208constant-folds against), anddevtool: "cheap-source-map"when eager, so source maps go to separate.mapfiles.feat(dev-server): default linux dev to the rspack server— flipcreateFrontendScriptNameinscripts/dev/tauri-dev-processes.cjsfromrspack ?? platform === "darwin"torspack ?? platform !== "win32", andupdate its unit test.
Resulting invariant: macOS and Linux resolve to
dev:frontend:rspack, Windowsstays on
dev:frontend.ORGII_RSPACK=true/false,--rspack/--webpack, andpnpm tauri:dev:webpackstill override the platform default in bothdirections;
--lightstill wins over both.Windows is deliberately left on webpack because it has never been exercised on
rspack. Production builds are untouched — they stay on webpack.
Measured on Linux / WebKitGTK 2.50.4, same commit, both bundlers cold with no
cache, sequential runs (not concurrent, to avoid the contention swing #1174
documented):
pnpm tauri:devmain.js readyNote the rspack cold compile improved from the 9.8 s recorded on 2026-09-01 to
3.2 s today. That is not from this change —
develophas since migrated toTailwind CSS v4 and removed unused exports, shrinking the module graph. Both
bundlers benefit, so the comparison above still holds; only the absolute
numbers moved.
Potential risks
default. If a Windows developer opts in with
--rspack, the WebKitGTK gatescorrectly evaluate to false there, but nothing else has been exercised.
platforms while production builds stay on webpack, so "compiles in dev" no
longer implies "compiles in the production pipeline". This divergence was
introduced by build(dev-server): add rspack dev server, default on macos #1174; this PR widens it to Linux.
config/rspack.config.jsduplicatesaliases,
splitChunks, loader rules, and the env-key list fromconfig/webpack.config.jsby hand. A change to one that misses the otherproduces silent dev/prod drift.
repository-root
.envfile.config/webpack.config.js:599usesdotenv-webpackwithsystemvars: true, which reads both the.envfileand the process environment;
config/rspack.config.js:44-58uses ahand-written 12-key whitelist read straight off
process.env, andscripts/dev/rspack-server.jsnever loads dotenv. Shell-exported variablesstill work; only the
.envfile is missed. Blast radius is limited todevelopers who override the backend URL or run a self-hosted Supabase auth
project — the defaults (public OSS Supabase project, hosted login off) are
unaffected. This is platform-independent and has been live for macOS since
build(dev-server): add rspack dev server, default on macos #1174. It will be fixed in a separate PR rather than folded in here.
boot and three HMR round-trips, not a multi-hour session, so memory drift or
HMR degradation over a working day is unknown.
ORGII_RSPACK_CACHE=persistent, so every cold start pays the full ~3.2 s.That is still well under webpack's warm-cache time, so this is a tradeoff,
not a regression.
createFrontendScriptNameexpression, and any individual developer can opt out immediately today with
pnpm tauri:dev:webpackwithout a code change.Verification
All on Linux, WebKitGTK 2.50.4 (
libwebkit2gtk-4.0-37and4.1-0are both2.50.4-0ubuntu0.22.04.1on this machine), against this branch rebased ontoorigin/develop.node --test scripts/dev/tauri-dev-processes.test.cjs— 12/12 pass.createFrontendScriptName:linuxanddarwin→dev:frontend:rspack,win32→dev:frontend;{rspack: false, platform: "linux"}→dev:frontend.devtool: cheap-source-map,html.inject: false,html.retry: true,process.env.ORGII_DEV_EAGER_APP: "true".pnpm dev:frontend:rspackcold, no cache — compiled in 3,159 ms, 8011modules, no errors or warnings; served
main.jsat 26,999,850 B.pnpm dev:frontend(webpack) cold,node_modules/.cache/webpackremoved —compiled in 18,016 ms; the comparison numbers in Solution come from these
two runs plus three HMR round-trips each.
WebKit2.WebView, not a Tauriprocess):
0 ms watchdog → 1 ms loader attempt → 30 ms fetch → 973 ms loaded,load-failed: None,scripts: [](confirming the retry-loader blobpath rather than an injected tag),
rootChildren: 2,rootHtmlLen: 92757— React mounted a 92 KB DOM. The console errors in thatrun are all
Tauri IPC unavailable, expected with no__TAURI_INTERNALS__.pnpm tauri:devboot: launcher selected the Rspack dev server;[DevStartup +3.71s] main.js HTTP ready→frontend ready; opening WebView;cargo
Finished dev profile in 12.91s;[DevStartup +115.21s] backend HTTP server ready. The twoerrormatches in that log are false positives — theRust type name
ScanErrorinside a warning snippet.GNOME white-bar artifact), session list, populated file tree, editor pane
with syntax highlighting, Git/AGENT timelines, status bar. Confirms lazy
chunks beyond the eager
Appresolve under WebKitGTK. No image is embeddedbecause this is a dev-tooling change with no UI diff to show; the capture was
a liveness check, and both bundlers render the same UI.
npx eslinton the three changed files — 0 errors (3 warnings are"file ignored by config", not findings).
npx prettier --checkflagsscripts/dev/tauri-dev-processes.test.cjsatlines 113-120, inside a test this PR does not touch.
git show origin/develop:scripts/dev/tauri-dev-processes.test.cjsfails the samecheck, so it is pre-existing and deliberately left alone rather than
smuggled in as unrelated formatting.
pnpm installwas required (develop addedsass-embedded); it leftpnpm-lock.yamlunchanged, so this PR carries no dependency change.Not run: Windows on rspack; any multi-hour session; production build paths
(unchanged by this PR); the
.env-file path described under Potential risks.