Skip to content

fix(dev): Linux tauri:dev fails to start (Initialization Failed + i18n store-undefined crash) #508

Description

@Raymond8196

Description

On Linux, pnpm tauri:dev fails to reach the main UI. Two related but
distinct startup failures block the app:

  1. "Initialization Failed" — WebKitGTK cannot load the App module chunk.
  2. 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.

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