This commit is contained in:
Claude committed 2026-10-11 11:39:28 +00:00
commit f4d8a428ac
4 files changed
+38 -6

No files matched your search

+1 -1
View File
@@ -18,7 +18,7 @@ it's missing or a different version.
Build, then serve:
```sh
cargo xtask web # → <target>/web/{index.html, worker.js, lightcraft_web.js, lightcraft_web_bg.wasm}
cargo xtask web # → <target>/web-site/{index.html, worker.js, lightcraft_web.js, lightcraft_web_bg.wasm}
cargo xtask web --serve # build, then serve on http://127.0.0.1:8080/ (or `--serve 9000`)
cargo xtask web --dev # unoptimized build with debug info (faster to compile, slow to run)
```
+11 -1
View File
@@ -15,8 +15,18 @@ if [ "${1:-}" != "--skip-build" ]; then
(cd "$ROOT" && cargo xtask web)
fi
SITE="$CARGO_TARGET_DIR/web"
SITE="$CARGO_TARGET_DIR/web-site"
[ -f "$SITE/index.html" ] || { echo "error: $SITE/index.html missing; run without --skip-build" >&2; exit 1; }
# Guard against Cargo build artifacts leaking into the release (issue #793): cross-compiling writes
# the selected profile's *host* artifacts (build scripts, proc-macros, deps/, build/, .fingerprint/)
# to <target>/<profile>/, so if SITE ever points at a profile directory again the zip would carry
# ~113 MB of build output. Fail loudly instead.
for d in deps build .fingerprint; do
if [ -e "$SITE/$d" ]; then
echo "error: $SITE/$d exists — $SITE holds Cargo build artifacts, not just the site (issue #793)" >&2
exit 1
fi
done
# Paths must be relative so the site works under any prefix.
if grep -Eq '(src|href)="/[^/]' "$SITE/index.html"; then
echo "error: $SITE/index.html has root-absolute URLs; it would break when served from a sub-path" >&2
+1 -1
View File
@@ -31,7 +31,7 @@ commands:
Lightroom parity summary; --write refreshes the summary table in the document
wasm cargo check --target wasm32-unknown-unknown for the wasm-safe crates (+ the web app)
web [--serve [port]] [--dev]
build the browser app (apps/lightcraft-web) into <target>/web/;
build the browser app (apps/lightcraft-web) into <target>/web-site/;
--serve serves it on http://127.0.0.1:<port> (default 8080)
ci fmt --check, clippy -D warnings, heif, test, parity refs, layers, assets, wasm (stops at first failure)
corpus [--download]
+25 -3
View File
@@ -1,5 +1,5 @@
//! `cargo xtask web`: build `apps/lightcraft-web` for wasm32 and bundle it with `wasm-bindgen`
//! into `<target>/web/` (index.html + worker.js + lightcraft_web.js + lightcraft_web_bg.wasm),
//! into `<target>/web-site/` (index.html + worker.js + lightcraft_web.js + lightcraft_web_bg.wasm),
//! with gzip and brotli precompressed copies (`*.gz`, `*.br`) next to each file.
//! `--serve [port]` then serves that folder with a tiny static HTTP server (std only) that sends
//! the cross-origin isolation headers (COOP/COEP) and the precompressed files when the browser
@@ -13,6 +13,13 @@ use std::process::Command;
use crate::{cargo, metadata, root, run as step};
const TARGET: &str = "wasm32-unknown-unknown";
/// Cargo profile for the optimized (`--dev` off) browser build; see `[profile.web]` in `Cargo.toml`.
const WEB_PROFILE: &str = "web";
/// Directory under `<target>` that receives the bundle. It must **not** be a Cargo profile name:
/// cross-compiling with `--target wasm32-unknown-unknown` makes Cargo write the selected profile's
/// *host* artifacts (build scripts, proc-macros, `deps/`, `build/`, `.fingerprint/`) to
/// `<target>/<profile>/`, and `packaging/web/package.sh` zips the whole bundle directory (issue #793).
const SITE_DIR: &str = "web-site";
const CHINESE_FONT_FILE: &str = "lightcraft_zh_hans.otf";
const CHINESE_FONT_LICENSE_FILE: &str = "OFL-noto-sans-cjk-sc.txt";
@@ -100,14 +107,14 @@ pub fn run(args: &[&str]) -> Result<(), String> {
check_bindgen(&want)?;
let meta = metadata()?;
let target_dir = PathBuf::from(meta["target_directory"].as_str().ok_or("cargo metadata: no target_directory")?);
let profile = if dev { "dev" } else { "web" };
let profile = if dev { "dev" } else { WEB_PROFILE };
let mut c = cargo();
c.args(["build", "-p", "lightcraft-web", "--lib", "--target", TARGET, "--profile", profile]);
step(c, &format!("cargo build -p lightcraft-web --target {TARGET} --profile {profile}"))?;
let wasm = target_dir.join(TARGET).join(if dev { "debug" } else { profile }).join("lightcraft_web.wasm");
let out = target_dir.join("web");
let out = target_dir.join(SITE_DIR);
std::fs::create_dir_all(&out).map_err(|e| format!("{}: {e}", out.display()))?;
let mut b = Command::new("wasm-bindgen");
b.arg(&wasm).args(["--target", "web", "--no-typescript", "--out-name", "lightcraft_web", "--out-dir"]).arg(&out);
@@ -287,6 +294,21 @@ mod tests {
assert!(v.starts_with("0.2."), "{v}");
}
#[test]
fn site_dir_is_not_a_cargo_profile() {
// Cross-compiling writes the selected profile's *host* artifacts (build scripts,
// proc-macros, `deps/`, `build/`, `.fingerprint/`) to `<target>/<profile>/`, so the bundle
// must not live in a profile directory or `packaging/web/package.sh` would zip them
// (issue #793).
let manifest = std::fs::read_to_string(root().join("Cargo.toml")).unwrap();
let is_profile = |name: &str| {
let header = format!("[profile.{name}]");
manifest.lines().any(|l| l.trim() == header)
};
assert!(is_profile(WEB_PROFILE), "`{WEB_PROFILE}` is no longer a profile in Cargo.toml");
assert!(!is_profile(SITE_DIR), "`{SITE_DIR}` is a Cargo profile name; pick a different bundle directory");
}
#[test]
fn wasm_mime() {
assert_eq!(mime(Path::new("a/lightcraft_web_bg.wasm")), "application/wasm");