[rust-compiler] Switch to hmac-sha256 and bump napi/similar (#36809)

## Summary

Dependency maintenance for the Rust compiler crates.

### Fast Refresh hash: sha2 + hmac → hmac-sha256
The Fast Refresh source hash (`enableResetCacheOnSourceFileChanges`)
only needs an HMAC-SHA256 of the source text, matching the TS compiler's
`createHmac('sha256', code).digest('hex')`. RustCrypto's `sha2` + `hmac`
pulled in **11 crates** (`sha2`, `hmac`, `digest`, `block-buffer`,
`typenum`, `crypto-common`, `hybrid-array`, `const-oid`, `cpufeatures`,
`cmov`, `ctutils`) — generic-hashing / constant-time machinery that is
irrelevant for a non-security content fingerprint. This replaces them
with the single **zero-dependency** `hmac-sha256` crate: a net reduction
of **10 crates**.

HMAC-SHA256 is a standardized deterministic algorithm, so the emitted
hash is unchanged. A new unit test
`source_file_hash_matches_node_create_hmac` pins the result against
Node's `createHmac('sha256', code).digest('hex')` for several inputs.

### Other bumps
- `napi` / `napi-derive` 2 → 3
- `similar` 2 → 3 (dev-dependency)
- Drop the unused `react_compiler_lowering` dependency from
`react_compiler_ssa`

`cargo check --workspace --all-targets` passes, including the napi 3
native crate.
This commit is contained in:
Boshen
2026-06-17 16:07:24 -07:00
committed by GitHub
parent 450d1e694f
commit c8ae4d2ab4
6 changed files with 174 additions and 156 deletions
+134 -140
View File
@@ -2,15 +2,6 @@
# It is not intended for manual editing.
version = 4
[[package]]
name = "aho-corasick"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
dependencies = [
"memchr",
]
[[package]]
name = "bitflags"
version = "2.11.0"
@@ -18,12 +9,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
[[package]]
name = "block-buffer"
version = "0.10.4"
name = "bstr"
version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab"
dependencies = [
"generic-array",
"memchr",
"serde",
]
[[package]]
@@ -34,52 +26,24 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "convert_case"
version = "0.6.0"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
checksum = "affbf0190ed2caf063e3def54ff444b449371d55c58e513a95ab98eca50adb49"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "cpufeatures"
version = "0.2.17"
name = "ctor"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
dependencies = [
"generic-array",
"typenum",
]
checksum = "400a21f1014a968ec518c7ccdf9b4a4ed0cac8c56ccb6d604f8b91f00110501e"
[[package]]
name = "ctor"
version = "0.2.9"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
"subtle",
]
checksum = "01334b89b69ff726750c5ce5073fc8bd860e99aa9a8fc5ca11b04730e3aee97a"
[[package]]
name = "equivalent"
@@ -88,13 +52,91 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "generic-array"
version = "0.14.7"
name = "futures"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d"
dependencies = [
"typenum",
"version_check",
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
name = "futures-core"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
[[package]]
name = "futures-executor"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
[[package]]
name = "futures-macro"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "futures-sink"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
[[package]]
name = "futures-task"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
[[package]]
name = "futures-util"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
"pin-project-lite",
"slab",
]
[[package]]
@@ -104,13 +146,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
[[package]]
name = "hmac"
version = "0.12.1"
name = "hmac-sha256"
version = "1.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
dependencies = [
"digest",
]
checksum = "ec9d92d097f4749b64e8cc33d924d9f40a2d4eb91402b458014b781f5733d60f"
[[package]]
name = "indexmap"
@@ -130,17 +169,11 @@ version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
[[package]]
name = "libc"
version = "0.2.183"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
[[package]]
name = "libloading"
version = "0.8.9"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60"
dependencies = [
"cfg-if",
"windows-link",
@@ -154,15 +187,17 @@ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]]
name = "napi"
version = "2.16.17"
version = "3.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55740c4ae1d8696773c78fdafd5d0e5fe9bc9f1b071c7ba493ba5c413a9184f3"
checksum = "8e55037284865448ecf329baa86a4d05401f647ebde99f5747b640d32c2c5226"
dependencies = [
"bitflags",
"ctor",
"napi-derive",
"ctor 0.11.1",
"futures",
"napi-build",
"napi-sys",
"once_cell",
"nohash-hasher",
"rustc-hash",
]
[[package]]
@@ -173,12 +208,12 @@ checksum = "d376940fd5b723c6893cd1ee3f33abbfd86acb1cd1ec079f3ab04a2a3bc4d3b1"
[[package]]
name = "napi-derive"
version = "2.16.13"
version = "3.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cbe2585d8ac223f7d34f13701434b9d5f4eb9c332cccce8dee57ea18ab8ab0c"
checksum = "89b3f766e04667e6da0e181e2da4f85475d5a6513b7cf6a80bea184e224a5b42"
dependencies = [
"cfg-if",
"convert_case",
"ctor 1.0.7",
"napi-derive-backend",
"proc-macro2",
"quote",
@@ -187,33 +222,37 @@ dependencies = [
[[package]]
name = "napi-derive-backend"
version = "1.0.75"
version = "5.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1639aaa9eeb76e91c6ae66da8ce3e89e921cd3885e99ec85f4abacae72fc91bf"
checksum = "0d5af30503edf933ce7377cf6d4c877a62b0f1107ea05585f1b5e430e88d5baf"
dependencies = [
"convert_case",
"once_cell",
"proc-macro2",
"quote",
"regex",
"semver",
"syn",
]
[[package]]
name = "napi-sys"
version = "2.4.0"
version = "3.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "427802e8ec3a734331fec1035594a210ce1ff4dc5bc1950530920ab717964ea3"
checksum = "1f5bcdf71abd3a50d00b49c1c2c75251cb3c913777d6139cd37dabc093a5e400"
dependencies = [
"libloading",
]
[[package]]
name = "once_cell"
version = "1.21.4"
name = "nohash-hasher"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
[[package]]
name = "pin-project-lite"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
[[package]]
name = "proc-macro2"
@@ -334,13 +373,12 @@ dependencies = [
name = "react_compiler_reactive_scopes"
version = "0.1.0"
dependencies = [
"hmac",
"hmac-sha256",
"indexmap",
"react_compiler_ast",
"react_compiler_diagnostics",
"react_compiler_hir",
"serde_json",
"sha2",
]
[[package]]
@@ -350,7 +388,6 @@ dependencies = [
"indexmap",
"react_compiler_diagnostics",
"react_compiler_hir",
"react_compiler_lowering",
]
[[package]]
@@ -379,33 +416,10 @@ dependencies = [
]
[[package]]
name = "regex"
version = "1.12.3"
name = "rustc-hash"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe"
[[package]]
name = "same-file"
@@ -475,27 +489,19 @@ dependencies = [
]
[[package]]
name = "sha2"
version = "0.10.9"
name = "similar"
version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
checksum = "e6505efef05804732ed8a3f2d4f279429eb485bd69d5b0cc6b19cc02005cda16"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
"bstr",
]
[[package]]
name = "similar"
version = "2.7.0"
name = "slab"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa"
[[package]]
name = "subtle"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
[[package]]
name = "syn"
@@ -508,12 +514,6 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "typenum"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
[[package]]
name = "unicode-ident"
version = "1.0.24"
@@ -526,12 +526,6 @@ version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "walkdir"
version = "2.5.0"
@@ -12,4 +12,4 @@ indexmap = { version = "2", features = ["serde"] }
[dev-dependencies]
walkdir = "2"
similar = "2"
similar = "3"
@@ -9,5 +9,4 @@ react_compiler_diagnostics = { path = "../react_compiler_diagnostics" }
react_compiler_hir = { path = "../react_compiler_hir" }
indexmap = "2"
serde_json = "1"
sha2 = "0.10"
hmac = "0.12"
hmac-sha256 = "1"
@@ -181,6 +181,17 @@ pub struct OutlinedFunction {
}
/// Top-level entry point: generates code for a reactive function.
/// Computes the Fast Refresh source hash used to bust the memo cache when the
/// source file changes. Matches the TS compiler's
/// `createHmac('sha256', code).digest('hex')`: an HMAC-SHA256 keyed by the
/// source code, hashing empty data.
fn source_file_hash(code: &str) -> String {
hmac_sha256::HMAC::mac(b"", code.as_bytes())
.iter()
.map(|b| format!("{b:02x}"))
.collect()
}
pub fn codegen_function(
func: &ReactiveFunction,
env: &mut Environment,
@@ -194,15 +205,7 @@ pub fn codegen_function(
let fast_refresh_state: Option<(u32, String)> =
if cx.env.config.enable_reset_cache_on_source_file_changes == Some(true) {
if let Some(ref code) = cx.env.code {
use hmac::Hmac;
use hmac::Mac;
use sha2::Sha256;
type HmacSha256 = Hmac<Sha256>;
// Match TS: createHmac('sha256', code).digest('hex')
// Node's createHmac uses the code as the HMAC key and hashes empty data.
let mac = HmacSha256::new_from_slice(code.as_bytes())
.expect("HMAC can take key of any size");
let hash = format!("{:x}", mac.finalize().into_bytes());
let hash = source_file_hash(code);
let cache_index = cx.alloc_cache_index(); // Reserve slot 0 for the hash check
Some((cache_index, hash))
} else {
@@ -382,7 +385,9 @@ pub fn codegen_function(
arguments: vec![Expression::StringLiteral(
StringLiteral {
base: BaseNode::typed("StringLiteral"),
value: MEMO_CACHE_SENTINEL.to_string().into(),
value: MEMO_CACHE_SENTINEL
.to_string()
.into(),
},
)],
type_parameters: None,
@@ -4239,6 +4244,27 @@ mod tests {
use super::{UnsupportedOriginalNode, codegen_unsupported_original_node};
/// The Fast Refresh source hash must match Node's
/// `createHmac('sha256', code).digest('hex')` byte-for-byte, or hot-reload
/// cache invalidation would diverge from the TS compiler. Reference values
/// were computed with Node's `crypto` module.
#[test]
fn source_file_hash_matches_node_create_hmac() {
use super::source_file_hash;
assert_eq!(
source_file_hash("hello world"),
"0de8bee5d7f9c5d209f8c6fabed0ea84cb3fca1244e8ed38079a61b599a84c47"
);
assert_eq!(
source_file_hash(""),
"b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad"
);
assert_eq!(
source_file_hash("function App(){}"),
"d637acb4985c789d6622c70197db2b62dda282f16f3276aa810b598d6e6cab7b"
);
}
/// A modeled statement tag parses typed and is emitted directly.
#[test]
fn unsupported_original_node_modeled_statement_tag_emits_statement() {
@@ -6,5 +6,4 @@ edition = "2024"
[dependencies]
react_compiler_diagnostics = { path = "../react_compiler_diagnostics" }
react_compiler_hir = { path = "../react_compiler_hir" }
react_compiler_lowering = { path = "../react_compiler_lowering" }
indexmap = "2"
@@ -7,8 +7,8 @@ edition = "2024"
crate-type = ["cdylib"]
[dependencies]
napi = { version = "2", features = ["napi4"] }
napi-derive = "2"
napi = { version = "3", features = ["napi4"] }
napi-derive = "3"
react_compiler = { path = "../../../crates/react_compiler" }
react_compiler_ast = { path = "../../../crates/react_compiler_ast" }
serde = "1"