Files
wasm/scripts/build-quantus.sh
rob thijssen e8bf9e20c7 fix(quantus-crypto): strip wasm-bindgen's fetch-based init from the shipped glue
The package could not be bundled. Every webpack consumer failed with:

  Module not found: Error: Can't resolve 'quantus_crypto_bg.wasm'
    in node_modules/@quantus/crypto/generated

wasm-bindgen's async `__wbg_init` contains

  module_or_path = new URL('quantus_crypto_bg.wasm', import.meta.url);

and webpack resolves `new URL(..., import.meta.url)` statically, at build time,
whether or not the branch can run. The file is not in the package — the wasm
ships base64'd in bytes.js, which is the entire point of this package — so the
build failed on a code path we never call.

node never sees it, which is why ten Rust tests, twelve consumer assertions and a
browser probe all passed while the package was unusable in a bundler. It took a
real extension build to surface, and that is the useful lesson: this package's
consumers bundle, and nothing in its own test suite does.

So the dead init is removed after bindgen runs. Shipping a second copy of the
wasm to satisfy a path we do not use would be the wide fix; deleting generated
code we never call is the narrow one.

The stripper asserts the shape it expects and throws if wasm-bindgen changes it,
rather than silently no-opping — a build that quietly stopped stripping would
ship the broken package again. It also re-checks that no reference to the .wasm
filename survives.

Published as 0.1.1.

Refs quantus/wasm#1, quantus/extension#2

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012uDUodEcRbBwNRi3UCmw8f
2026-09-15 11:53:18 +03:00

60 lines
2.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# Copyright 2026 @quantus/crypto authors & contributors
# SPDX-License-Identifier: Apache-2.0
# Builds packages/quantus-crypto. Deliberately NOT part of build-wasm.sh: that
# script drives the nightly-2022-06-24 + xargo build that `wasm-crypto` needs,
# and this crate needs a modern compiler (inline `const {}` blocks, Rust >= 1.79).
# Keeping the two builds separate is what lets wasm-crypto stay byte-identical to
# upstream. See quantus/wasm#1.
#
# There is no asm.js step here. wasm2js over ML-DSA would be enormous and slow,
# and every context we ship into sets 'wasm-unsafe-eval', so wasm is always
# available where this runs.
set -e
PKG=quantus-crypto
CRATE=quantus_crypto
BINDGEN_VER=0.2.128
WASM=packages/$PKG/build-wasm/${CRATE}_bg.wasm
OPT=packages/$PKG/build-wasm/${CRATE}_opt.wasm
echo "*** Building Rust sources"
# The toolchain comes from packages/quantus-crypto/rust-toolchain.toml, which
# pins the same channel the chain builds its runtime with.
(cd packages/$PKG && cargo build --target wasm32-unknown-unknown --release --locked)
echo "*** Converting to WASM"
./bindgen-quantus/wasm-bindgen \
packages/$PKG/target/wasm32-unknown-unknown/release/$CRATE.wasm \
--out-dir packages/$PKG/build-wasm \
--target web
# The glue is a build artifact but is checked in, so the package can be built
# without a Rust toolchain — the same reasoning as upstream checking in an empty
# bytes.js. Copy it back so the two never drift.
# Must run before the glue is copied into src/generated — see the script's own
# comment for why the fetch path cannot ship.
node ./scripts/strip-wasm-fetch-init.mjs packages/$PKG/build-wasm/$CRATE.js
echo "*** Updating checked-in bindings"
cp packages/$PKG/build-wasm/$CRATE.js packages/$PKG/src/generated/$CRATE.js
cp packages/$PKG/build-wasm/$CRATE.d.ts packages/$PKG/src/generated/$CRATE.d.ts
# binaryen-quantus, not binaryen. Upstream pins version_105 (2021), which predates
# the externref tables wasm-bindgen 0.2.128 emits: it "optimises" the table into
# something that fails at instantiation with
# `WebAssembly.Table.grow(): failed to grow table by 4`. The wasm is valid before
# wasm-opt and broken after, and nothing in the build says so — it only surfaces
# when a consumer tries to init. Same shape of problem as the two bindgens.
echo "*** Optimising WASM output"
./binaryen-quantus/bin/wasm-opt $WASM -Oz -o $OPT
# Must come before packing: tsc clears build/, which is where bytes.js lands.
./scripts/build-quantus-js.sh
echo "*** Packing WASM into baseX"
PKG_NAME=$PKG CRATE_NAME=$CRATE node ./scripts/pack-quantus-base.mjs