Description
On Linux, pnpm tauri:dev fails to reach the main UI. Two related but
distinct startup failures block the app:
- "Initialization Failed" — WebKitGTK cannot load the App module chunk.
- i18n crash requiring reload — even when the chunk loads, a slow cold
start lets React mount before i18n.init() completes, crashing with
undefined is not an object (evaluating 'this.store.hasLanguageSomeTranslations').
Both are dev-only regressions that do not affect production builds.
Steps to Reproduce
Run on Linux (WebKitGTK-based WebView):
pnpm install
pnpm tauri:dev
Symptom 1 (Initialization Failed): The window shows the emergency
"Initialization Failed" screen instead of the main UI.
Symptom 2 (i18n crash): On a cold first launch the app throws
undefined is not an object (evaluating 'this.store.hasLanguageSomeTranslations')
and the user is forced to reload; after reload it works (cache is warm,
init finishes within the timeout).
Expected Behavior
pnpm tauri:dev should reach the main UI directly on the first launch,
without the emergency screen and without needing a manual reload.
Actual Behavior
Root cause 1 — App chunk un-loadable by WebKitGTK
Since e06f4b471 ("isolate dual-instance cloud collaboration"), App is
loaded via a runtime dynamic import("@src/App"), which webpack emits as
a separate chunk. Under eval-cheap-module-source-map that chunk inlines
every module's source and balloons to ~77MB; WebKitGTK fails the runtime
dynamic import → "Initialization Failed". Even after moving the source
map out of the chunk, WebKitGTK still fails the runtime dynamic import
— the trigger is the loading mechanism, not only the size.
Root cause 2 — i18n loses the init race
src/index.tsx wraps the parallel init in a 10s Promise.race:
const initPromise = Promise.all([
i18nReady, // async: loads locale JSON → i18n.init()
initTheme(),
initializeTauriAPIs(),
initBackgroundImage(),
appModulePromise,
]);
await Promise.race([initPromise, timeoutPromise]); // 10s
// rejection swallowed → React mounts
On a slow cold start the race is lost; the rejection is swallowed and
React mounts before i18n.init() completes. The first useTranslation()
call then hits i18next's not-yet-initialized this.store → crash.
i18n is not degradable (App calls useTranslation() unconditionally
at render), so it must be ready before mount.
Environment
- OS: Ubuntu 22.04 (WebKitGTK)
- App version / commit: current
develop (verified affected up to 20cbbd888)
- Runtime: dev (
pnpm tauri:dev); production builds are unaffected
Additional Context
Fix is on branch fix/dev-init-webkit-chunk (two commits):
2e38474e4 — dev-only: bundle App into main.js via
webpackMode: "eager"; switch dev devtool from
eval-cheap-module-source-map to cheap-source-map (separate .map
file) so the executable bundle stays ~41MB. Production is untouched
(prod keeps the normal dynamic import and devtool: false).
1aa39a30a — pull i18nReady out of the bounded Promise.race and
await it unconditionally after the degradable ops settle; on rejection
surface the emergency error UI instead of mounting a guaranteed-to-crash
React tree.
Description
On Linux,
pnpm tauri:devfails to reach the main UI. Two related butdistinct startup failures block the app:
start lets React mount before
i18n.init()completes, crashing withundefined is not an object (evaluating 'this.store.hasLanguageSomeTranslations').Both are dev-only regressions that do not affect production builds.
Steps to Reproduce
Run on Linux (WebKitGTK-based WebView):
Symptom 1 (Initialization Failed): The window shows the emergency
"Initialization Failed" screen instead of the main UI.
Symptom 2 (i18n crash): On a cold first launch the app throws
undefined is not an object (evaluating 'this.store.hasLanguageSomeTranslations')and the user is forced to reload; after reload it works (cache is warm,
init finishes within the timeout).
Expected Behavior
pnpm tauri:devshould reach the main UI directly on the first launch,without the emergency screen and without needing a manual reload.
Actual Behavior
Root cause 1 — App chunk un-loadable by WebKitGTK
Since
e06f4b471("isolate dual-instance cloud collaboration"), App isloaded via a runtime dynamic
import("@src/App"), which webpack emits asa separate chunk. Under
eval-cheap-module-source-mapthat chunk inlinesevery module's source and balloons to ~77MB; WebKitGTK fails the runtime
dynamic import → "Initialization Failed". Even after moving the source
map out of the chunk, WebKitGTK still fails the runtime dynamic import
— the trigger is the loading mechanism, not only the size.
Root cause 2 — i18n loses the init race
src/index.tsxwraps the parallel init in a 10sPromise.race:On a slow cold start the race is lost; the rejection is swallowed and
React mounts before
i18n.init()completes. The firstuseTranslation()call then hits i18next's not-yet-initialized
this.store→ crash.i18n is not degradable (App calls
useTranslation()unconditionallyat render), so it must be ready before mount.
Environment
develop(verified affected up to20cbbd888)pnpm tauri:dev); production builds are unaffectedAdditional Context
Fix is on branch
fix/dev-init-webkit-chunk(two commits):2e38474e4— dev-only: bundle App intomain.jsviawebpackMode: "eager"; switch devdevtoolfromeval-cheap-module-source-maptocheap-source-map(separate.mapfile) so the executable bundle stays ~41MB. Production is untouched
(prod keeps the normal dynamic import and
devtool: false).1aa39a30a— pulli18nReadyout of the boundedPromise.raceandawaitit unconditionally after the degradable ops settle; on rejectionsurface the emergency error UI instead of mounting a guaranteed-to-crash
React tree.