Skip to content

fix(dev): Linux tauri:dev startup failures (WebKitGTK load + i18n mount race)#498

Open
Raymond8196 wants to merge 2 commits into
org2AI:developfrom
Raymond8196:fix/dev-init-webkit-chunk
Open

fix(dev): Linux tauri:dev startup failures (WebKitGTK load + i18n mount race)#498
Raymond8196 wants to merge 2 commits into
org2AI:developfrom
Raymond8196:fix/dev-init-webkit-chunk

Conversation

@Raymond8196

@Raymond8196 Raymond8196 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #508 — on Linux, pnpm tauri:dev fails to reach the main UI due to two
related dev-only startup failures.

Two coordinated, dev-only commits; production builds are untouched.

Commit 1 — fix(dev): keep App bundled into main.js so WebKitGTK can load it

Since e06f4b471, 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".

  • src/index.tsx: in dev, mark the App import with
    /* webpackMode: "eager" */. App is bundled into main.js instead of
    being a separate runtime chunk, while import() keeps its Promise-returning
    semantics (so App module-tree eval still runs after the runtime-identity
    config). Production keeps the normal dynamic import.
  • webpack.config.js: dev devtool switches from
    eval-cheap-module-source-map to cheap-source-map (separate lazily-loaded
    .map file), keeping the executable main.js at ~41MB with line-level
    debuggability. Cost: incremental dev rebuilds are marginally slower.

Commit 2 — fix(dev): await i18n before React mount to avoid store-undefined crash

On a slow cold start the parallel init Promise.all loses the 10s
Promise.race; the rejection was swallowed and React mounted before
i18n.init() completed, crashing the first useTranslation() call on
i18next's not-yet-initialized this.store.

i18n is not degradable (App calls useTranslation() unconditionally at
render), so pull i18nReady out of the bounded race and await it
unconditionally after the degradable ops settle. It still starts at module
load and runs parallel to the other ops, so the await only blocks when
locale bundles are genuinely still loading. On rejection, surface the
emergency error UI instead of mounting a guaranteed-to-crash React tree.

Production safety

  • webpackMode: "eager" is gated behind isDev (compile-time). Production
    keeps the normal dynamic import.
  • The devtool change is dev-only: useDevSourceMaps = !isProduction && ...,
    so production devtool stays false.
  • The i18n await change is runtime code but correct regardless of build:
    i18n must be initialized before React renders useTranslation() consumers.

Test plan

  • pnpm tauri:dev on Linux reaches the main UI (no "Initialization Failed")
  • First cold launch no longer crashes with hasLanguageSomeTranslations;
    no manual reload needed
  • eslint src/index.tsx — clean
  • tsc --noEmit — no new errors (3 pre-existing errors in
    src/modules/ProjectManager/ are unrelated to this change)
  • Reviewer: confirm pnpm tauri:dev on macOS is unaffected
  • Reviewer: confirm production build (pnpm tauri:build) is unaffected

Verified on Ubuntu 22.04 / WebKitGTK. Regression range: since e06f4b471.

@Raymond8196
Raymond8196 marked this pull request as draft July 23, 2026 12:02
Since e06f4b4 ("isolate dual-instance cloud collaboration"), App is
loaded via a runtime dynamic `import("@src/App")`, which webpack emits
as a separate chunk. WebKitGTK (Linux dev) cannot load that chunk:
under eval-cheap-module-source-map the App chunk inlines every module's
source and balloons to ~77MB, and the WebView fails the dynamic import
at runtime → "Initialization Failed" that blocks the whole app. Even
after moving the source map out of the chunk (37MB standalone), WebKitGTK
still fails the *runtime dynamic* import — the trigger is the loading
mechanism, not only the size.

Two coordinated dev-only changes; production is untouched:

- src/index.tsx: in dev, mark the App import with
  `/* webpackMode: "eager" */`. App is no longer emitted as a separate
  runtime chunk — it is bundled into main.js — while `import()` keeps its
  Promise-returning semantics, so the runtime-identity setup still runs
  before the App module tree evaluates. Production keeps the normal
  dynamic import (prod minifies and ships no eval source maps, so the
  App chunk stays small there).

- webpack.config.js: dev `devtool` switches from
  `eval-cheap-module-source-map` to `cheap-source-map`. Since App now
  lives inside main.js, eval mode would inline every module's source
  into main.js (~80MB, still un-loadable). cheap-source-map writes the
  map to a separate lazily-loaded .map file instead, keeping the
  executable main.js at ~41MB. Line-level debuggability is unchanged.
  Cost: incremental dev rebuilds are marginally slower (a .map file is
  written each time).

Verified on Linux: `pnpm tauri:dev` reaches the main UI instead of the
"Initialization Failed" emergency screen. main.js is ~41MB and App is no
longer a 404'd/oversized runtime chunk.
On slow cold starts the parallel init Promise.all lost the 10s
Promise.race against INIT_TIMEOUT_MS; the rejection was swallowed and
React mounted before i18n.init() completed. The first useTranslation()
then hit i18next's not-yet-initialized this.store → "undefined is not an
object (evaluating 'this.store.hasLanguageSomeTranslations')".

i18n is not degradable — App renders useTranslation() unconditionally —
so pull i18nReady out of the bounded race and await it unconditionally
after the degradable ops settle. It still starts at module load and runs
parallel to the other ops, so the await only blocks when locale bundles
are genuinely still loading. A rejection now surfaces the emergency error
UI instead of mounting a guaranteed-to-crash React tree.
@Raymond8196
Raymond8196 force-pushed the fix/dev-init-webkit-chunk branch from 92ef89b to 1aa39a3 Compare July 24, 2026 03:29
@Raymond8196 Raymond8196 changed the title fix(dev): keep App bundled into main.js so WebKitGTK can load it fix(dev): Linux tauri:dev startup failures (WebKitGTK load + i18n mount race) Jul 24, 2026
@Raymond8196
Raymond8196 marked this pull request as ready for review July 24, 2026 03:35
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.

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

1 participant