From f5d70476f078ec10441b96bde492586bb13c3dba Mon Sep 17 00:00:00 2001 From: Breadway Date: Thu, 23 Jul 2026 09:52:55 +0800 Subject: [PATCH] Fix standalone release build (custom-protocol feature was never enabled) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cargo build --release alone doesn't produce a working standalone binary in Tauri v2 — embedding the frontend vs. hitting devUrl at runtime is gated by the tauri/custom-protocol Cargo feature, not the debug/release profile. The scaffold never declared it, so even release builds tried to connect to localhost:1420. Added the standard default-on custom-protocol feature (cargo tauri dev strips it via --no-default-features for dev builds); a plain `cargo build --release --locked` in src/ now produces a real standalone binary with no dev-server dependency. Also fixes vite.config.js's file-watch ignore pattern, left stale by the src-tauri -> src rename: a bare "**/src/**" glob would have also matched frontend/src itself, so it's now an absolute path scoped to the Rust project dir specifically. --- frontend/vite.config.js | 12 ++++++++++-- src/Cargo.toml | 9 +++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/frontend/vite.config.js b/frontend/vite.config.js index 3ecfa0a..91d85bc 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -1,9 +1,17 @@ +import { fileURLToPath } from "node:url"; +import path from "node:path"; import { defineConfig } from "vite"; import { sveltekit } from "@sveltejs/kit/vite"; // @ts-expect-error process is a nodejs global const host = process.env.TAURI_DEV_HOST; +// The Rust/Tauri project dir (../src relative to this file) — an absolute +// path, not a bare "**/src/**" glob, because this repo has two directories +// named `src`: this one (frontend/src, which must be watched for HMR) and +// the sibling Rust crate (../src, which must not be). +const rustProjectDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../src"); + // https://vite.dev/config/ export default defineConfig(async () => ({ plugins: [sveltekit()], @@ -25,8 +33,8 @@ export default defineConfig(async () => ({ } : undefined, watch: { - // 3. tell Vite to ignore watching `src-tauri` - ignored: ["**/src-tauri/**"], + // 3. tell Vite to ignore watching the Tauri/Rust project dir + ignored: [`${rustProjectDir}/**`], }, }, })); diff --git a/src/Cargo.toml b/src/Cargo.toml index f0105fd..85c808a 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -17,6 +17,15 @@ crate-type = ["staticlib", "cdylib", "rlib"] [build-dependencies] tauri-build = { version = "2", features = [] } +[features] +# Default-on so a plain `cargo build --release` produces a standalone binary +# that embeds the built frontend instead of loading it from `devUrl` — +# `cargo tauri dev` strips this back off via `--no-default-features` so dev +# builds keep talking to the Vite dev server. See +# https://v2.tauri.app/reference/cargo-features/#custom-protocol +default = ["custom-protocol"] +custom-protocol = ["tauri/custom-protocol"] + [dependencies] tauri = { version = "2", features = ["protocol-asset"] } tauri-plugin-opener = "2"