Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: don't set JsInfo declarations and transitive_declarations in npm_link_package_store #1554

Merged
merged 1 commit into from
Mar 29, 2024

Conversation

gregmagolan
Copy link
Member

@gregmagolan gregmagolan commented Mar 29, 2024

While working on the rules_js 2.0 branch where I thought I needed to make changes to the JsInfo provider to get this perf improvement, I realized that the source of the issue is that npm_link_package_store sets declarations and transitive_declarations which it does not need to set since linked npm packages are already in runfiles for runtime dependencies and ts_project doesn't need them in declarations.

The perf improvement here is that npm_package (when include_runfiles is set to False) will no longer get all npm packages in its manifest. In rules_js 2.0, npm_package include_runfiles can flip to False and this perf improvement will be the default case.


Type of change

  • Performance (a code change that improves performance)

Test plan

  • Covered by existing test cases

@gregmagolan gregmagolan force-pushed the no_npm_link_package_store_declarations branch from 8e2370b to 33afa7f Compare March 29, 2024 00:06
@gregmagolan gregmagolan merged commit 46efd39 into main Mar 29, 2024
96 checks passed
@gregmagolan gregmagolan deleted the no_npm_link_package_store_declarations branch March 29, 2024 00:27
@gregmagolan gregmagolan mentioned this pull request May 15, 2024
21 tasks
dgp1130 added a commit to dgp1130/rules_prerender that referenced this pull request Jul 29, 2024
… removing workspace-local package dependencies.

`types_only` breaks in `@aspect_rules_js` v1.40.1 because declarations are dropped from `npm_link_package_store` in aspect-build/rules_js#1554, therefore we need a different approach.

Unfortunately there does not appear to be a clean way to depend on only the types of a module, so instead I added `prune_dependencies` which attempts to remove type-only dependencies after the fact. This allows `//packages/preact/...` to depend on the `rules_prerender` NPM package locally in the workspace, but then have that dependency removed. When the package is installed and linked in the user's workspace, `@user//:node_modules/@rules_prerender/preact` is linked against the user's `@user//:node_modules/rules_prerender` instead of `@rules_prerender//:node_modules/rules_prerender`.

`//tools/binaries/renderer` usage of `types_only` is not strictly necessary as it (intentionally) does have a value import of `rules_prerender`. It does technically depend on the local copy of `@rules_prerender//:node_modules/rules_prerender`, but this is never executed at runtime so it's not a significant problem. As long as we limit it to type-only imports, it should be fine.

`prune_dependencies` only works on an `npm_package`, meaning we can't use it the `:renderer` `ts_project`. I did consider adding another version of `prune_dependencies` which prunes `JsInfo` providers instead, however this seems to be a more complicated structure with file paths and nested providers which need to be pruned. Since it's not strictly necessary for `//tools/binaries/renderer`, I opted not to go down that route just yet, but it can be considered in the future.

I also briefy attempted creating a `@rules_prerender/renderer` package just to apply `prune_dependencies` to that. However `:renderer` depends on content outside its directory such as `//common:formatters`, so this needs to be included in the package as well, and an `npm_package` in `//tools/binaries/renderer/...` cannot include content outside of it. I then tried moving the `npm_package` to `//:renderer_pkg`, but this requires a `package.json` in the same directory, which would conflict with the `rules_prerender` package which has the same constraint. So there's no easy way to hack around this. Instead, we'll just rely on avoiding a value import of `rules_prerender` in the renderer.
dgp1130 added a commit to dgp1130/rules_prerender that referenced this pull request Jul 29, 2024
This rule is broken by the next version of `@aspect_rules_js` in aspect-build/rules_js#1554, so we have dropped all usages of it. This is no longer needed.
@dgp1130
Copy link
Contributor

dgp1130 commented Jul 29, 2024

Just FYI, I think there's a breaking change here which invalidates a types_only rule as suggested here. I had a custom implementation of this which is broken when upgrading to @aspect_rules_js v1.40.1.

I was able to fix things by depending on the regular NPM package (no limiting to only types) and then retroactively "pruning" the dependency by removing it from the NpmPackageInfo provider. It's not exactly elegant, but works well enough for my use case. Manually limiting to import type also works, but is harder to guarantee. I added some extra checks to ensure my package doesn't get duplicated on accident, which was the main thing types_only was trying to prevent.

dgp1130/rules_prerender@3893834...313314e

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants