Skip to content

Commit 796fa30

Browse files
wan9chiclaude
andcommitted
fix(napi): keep vite_task_client_napi type-defs out of consumer bindings
This crate is embedded as a cdylib artifact dependency of `vite_task`. napi-derive's `type-def` feature is force-enabled by feature unification with consumers that need it, so it would otherwise write this crate's `#[napi]` items (RunnerClient/load) into the consumer's shared NAPI_TYPE_DEF_TMP_FOLDER, which @napi-rs/cli sweeps into the consumer's generated binding as dead exports (the symbols live in the separately-loaded addon, not the consumer's .node). build.rs redirects this crate's type-def emission to an isolated sink and prunes any stale entry a pre-redirect build left in the consumer's (reused) folder. The public JS surface is the hand-written @voidzero-dev/vite-task-client package, so these generated defs are never needed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 6e634c6 commit 796fa30

1 file changed

Lines changed: 32 additions & 0 deletions

File tree

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,37 @@
11
extern crate napi_build;
22

3+
use std::{env, fs, path::PathBuf};
4+
35
fn main() {
46
napi_build::setup();
7+
8+
// Keep this crate's napi-derive type-defs out of any consumer's generated
9+
// binding.
10+
//
11+
// `vite_task_client_napi` is embedded as a cdylib *artifact* dependency of
12+
// `vite_task`. napi-derive's `type-def` feature is force-enabled by feature
13+
// unification with consumers that need it (e.g. vite-plus's CLI binding), so
14+
// disabling the feature here has no effect. By default napi-derive then
15+
// writes this crate's `#[napi]` items (`RunnerClient`/`load`) into the
16+
// consumer's shared `NAPI_TYPE_DEF_TMP_FOLDER`, which `@napi-rs/cli` sweeps
17+
// into the consumer's `index.cjs`/`index.d.cts` as dead exports (the symbols
18+
// live in the separately-loaded addon, not the consumer's `.node`). The
19+
// public JS surface is the hand-written `@voidzero-dev/vite-task-client`
20+
// package, so these generated defs are never needed.
21+
//
22+
// `@napi-rs/cli` reuses that folder across builds without pruning it, so
23+
// first remove any entry a pre-redirect build left there, then redirect this
24+
// crate's emission to an isolated, clearly-named sink. The override applies
25+
// only to this crate's rustc invocation, where the napi-derive proc-macro
26+
// reads the env at expansion time, so consumers' own type-defs are
27+
// unaffected.
28+
println!("cargo::rerun-if-env-changed=NAPI_TYPE_DEF_TMP_FOLDER");
29+
let pkg = env::var("CARGO_PKG_NAME").expect("CARGO_PKG_NAME not set");
30+
if let Ok(consumer_folder) = env::var("NAPI_TYPE_DEF_TMP_FOLDER") {
31+
let _ = fs::remove_file(PathBuf::from(consumer_folder).join(&pkg));
32+
}
33+
let sink = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR not set"))
34+
.join("discarded-napi-type-defs");
35+
fs::create_dir_all(&sink).expect("failed to create napi type-def sink dir");
36+
println!("cargo::rustc-env=NAPI_TYPE_DEF_TMP_FOLDER={}", sink.display());
537
}

0 commit comments

Comments
 (0)