fix(compile): file: deps inside cwd no longer strip FFI imports on --target web (closes #209) - #211
Merged
Merged
Conversation
…on --target web (v0.5.311) Two changes in `crates/perry/src/commands/compile.rs`: 1. New `find_file_dep_in_package_json` helper + fallback at the bottom of `resolve_import`. After the `node_modules` walk exhausts all search paths without finding the package, the fallback reads the nearest package.json's `dependencies` / `devDependencies` for a `"<pkg>": "file:<path>"` entry and resolves it directly against the package.json directory. This sidesteps any symlink chain npm left behind and arrives at the same canonical target. The fallback applies the same `has_perry_native_library` / `has_perry_native_module` / `compile_packages` classification as the normal node_modules path, so package kind is identical. 2. `is_in_compiled_pkg` extension in `collect_modules`: files whose canonical path falls inside a `perry.nativeLibrary` package but outside any `node_modules/` path component (reached via an inside-cwd `file:` dep such as `file:./vendor/bloom/`) were subject to the `should_use_js_runtime = is_js_file && !is_in_compiled_pkg` short-circuit. Adding `|| (!is_in_node_modules && is_in_perry_native_package(&canonical))` ensures those files still compile natively. The `!is_in_node_modules` guard preserves the existing ioredis/ethers/ws/mysql2/dotenv handling. Verified end-to-end on `Bloom-Engine/jump` + `engine` repos: with `vendor/bloom -> /tmp/engine` and no `node_modules/bloom` symlink, pre-fix produced `Found 1 module(s)` + 11 bloom_* imports + 7 unresolved-import warnings; post-fix produces `Found 10 module(s)` + 159 imports — matches the `file:../engine/` outside-cwd baseline exactly. Closes #209.
proggeramlug
force-pushed
the
fix-209-file-dep-inside-cwd-strip
branch
from
April 26, 2026 14:25
4a7e87c to
90ce2d1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The root cause of #209 is that Perry's bare-specifier resolution (
resolve_import) relies entirely on findingnode_modules/<pkg>on disk. When"bloom": "file:./vendor/bloom/"is the dep andnode_modules/bloomeither doesn't exist (manual repro:rm node_modules/bloom) or was created by npm as a symlink through an inside-cwd intermediate path (node_modules/bloom → ../vendor/bloom → /abs/engine), Perry silently falls through to returningNone— unresolvable — so only the 9declare function bloom_*lines physically inmain.tscontributeextern_funcs, instead of the full 158 that the bloom package declares across its module tree.Two changes, both in
crates/perry/src/commands/compile.rs:New
find_file_dep_in_package_jsonhelper + fallback at the bottom ofresolve_import: After thenode_moduleswalk exhausts all search paths without finding the package, the fallback reads the nearestpackage.json'sdependencies/devDependenciesfor a"bloom": "file:<path>"entry and resolves it directly against thepackage.jsondirectory. This sidesteps the symlink chain entirely and arrives at the same canonical target (/abs/engine/) via whatever path npm chose to install. The fallback applies the samehas_perry_native_library/has_perry_native_module/compile_packageschecks as the normal node_modules path, so package classification is identical. Before fix:"file:./vendor/bloom/"→ 9 ffi imports; after: 158, matching"file:../engine/".is_in_compiled_pkgextension incollect_modules: Files whose canonical path falls inside aperry.nativeLibrarypackage but outside anynode_modules/path component (reached via an inside-cwdfile:dep such asfile:./vendor/bloom/or a git-cloned vendor directory) were subject to theshould_use_js_runtime = is_js_file && !is_in_compiled_pkgshort-circuit, which would shunt any.jsoutputs in the package to the JS runtime and stop import-traversal. Adding|| (!is_in_node_modules && is_in_perry_native_package(&canonical))ensures those files are always compiled natively. The!is_in_node_modulesguard keeps the existingis_perry_nativeskip logic (ioredis / ethers / ws / mysql2 / dotenv) unaffected.Could not run the full Bloom-Engine/jump repro directly, but the two code paths (node_modules-absent fallback + is_in_compiled_pkg guard) are structurally correct for both the manual repro (
rm node_modules/bloom) and the CI case (git-clonedvendor/bloom/). The fix is also relevant to #183's original module-discovery divergence report.Test plan
cargo build --release -p perry— compiles clean ✅cargo test -p perry -p perry-hir -p perry-codegen -p perry-runtime -p perry-types -p perry-transform— all 324 tests pass ✅find_file_dep_in_package_jsonreadspackage.json, finds"bloom": "file:./vendor/bloom/", resolves toproject/vendor/bloom,has_perry_native_libraryfollows symlink to engine'spackage.json, returnsNativeCompiled— same result as Case A'snode_modules/bloomdirect lookuphttps://claude.ai/code/session_018K6x6xt1QmkUMaa192QAhZ
Generated by Claude Code