query icon indicating copy to clipboard operation
query copied to clipboard

feat(angular-query): move devtools to conditional sub-paths

Open arnoud-dv opened this issue 6 months ago • 3 comments

Breaking changes

Import paths

withDevtools moved to subpath

Most applications, to completely tree shake devtools from production builds

import { withDevtools } from '@tanstack/angular-query-experimental/devtools'

If you want to also use devtools in production builds

import { withDevtools } from '@tanstack/angular-query-experimental/devtools/production'

injectDevtoolsPanel moved to main package

Most applications, to completely tree shake devtools panel from production builds

import { injectDevtoolsPanel } from '@tanstack/angular-query-experimental/devtools-panel'

If you want to also use devtools panel in production builds

import { injectDevtoolsPanel } from '@tanstack/angular-query-experimental/devtools-panel/production'

angular-query-devtools-experimental package

After moving injectDevtoolsPanel to the main package, the angular devtools package is obsolete.

Improvements and fixes

Subpath exports

Experience with subpath exports paves the way to add functionality such as RxJs integration without needing to have the whole Angular TanStack Query package depend on RxJs.

Isolating devtools to a subpath reliably fixes #9078, where esbuild was generating chunks even when devtools were not used at all. While these chunks were not adding to the main bundle size it unnecessarily increased build time and deployment size.

Conditional exports

The devtools subpath exports further utilize conditional exports. For development builds, the function is exported normally. For production builds a tiny stub function is exported, resulting in excellent tree shaking without having to configure environments.

Dependency injection in the devtools callback

Fixes #8824 After no longer running the options computation function in the injection context it was no longer possible to use dependency injection to inject values. The withDevtools function now has a deps option to automatically inject dependencies and pass it as a parameter to the computation function. This solves this issue while not injecting a value each time the computation function is run which would be the case if the function would run in the injection context. This is similar to and internally uses deps on Angular's useFactory.

withDevtools(
  (devToolsOptionsManager: DevtoolsOptionsManager) => ({
    loadDevtools: devToolsOptionsManager.loadDevtools(),
  }),
  {
    // `deps` is used to inject and pass `DevtoolsOptionsManager` to the `withDevtools` callback.
    deps: [DevtoolsOptionsManager],
  },
)

Adds a check if devtools were already provided

Fixes #8705

arnoud-dv avatar Jun 11 '25 21:06 arnoud-dv

View your CI Pipeline Execution ↗ for commit 1f2db27426a35e45904678e9cd6b9dd91c590247

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 1m 25s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 8s View ↗

☁️ Nx Cloud last updated this comment at 2025-09-15 20:47:05 UTC

nx-cloud[bot] avatar Jun 11 '25 21:06 nx-cloud[bot]

Codecov Report

:x: Patch coverage is 92.30769% with 8 lines in your changes missing coverage. Please review. :white_check_mark: Project coverage is 45.75%. Comparing base (ca56514) to head (1f2db27). :warning: Report is 2 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #9270      +/-   ##
==========================================
+ Coverage   45.51%   45.75%   +0.23%     
==========================================
  Files         209      213       +4     
  Lines        8379     8427      +48     
  Branches     1895     1913      +18     
==========================================
+ Hits         3814     3856      +42     
- Misses       4118     4124       +6     
  Partials      447      447              
Components Coverage Δ
@tanstack/angular-query-experimental 87.06% <92.30%> (+0.06%) :arrow_up:
@tanstack/eslint-plugin-query 83.24% <ø> (ø)
@tanstack/query-async-storage-persister 43.85% <ø> (ø)
@tanstack/query-broadcast-client-experimental 24.39% <ø> (ø)
@tanstack/query-codemods 0.00% <ø> (ø)
@tanstack/query-core 97.48% <ø> (ø)
@tanstack/query-devtools 3.48% <ø> (ø)
@tanstack/query-persist-client-core 79.60% <ø> (ø)
@tanstack/query-sync-storage-persister 84.61% <ø> (ø)
@tanstack/query-test-utils 77.77% <ø> (ø)
@tanstack/react-query 96.00% <ø> (ø)
@tanstack/react-query-devtools 10.00% <ø> (ø)
@tanstack/react-query-next-experimental ∅ <ø> (∅)
@tanstack/react-query-persist-client 100.00% <ø> (ø)
@tanstack/solid-query 78.13% <ø> (ø)
@tanstack/solid-query-devtools ∅ <ø> (∅)
@tanstack/solid-query-persist-client 100.00% <ø> (ø)
@tanstack/svelte-query 87.58% <ø> (ø)
@tanstack/svelte-query-devtools ∅ <ø> (∅)
@tanstack/svelte-query-persist-client 100.00% <ø> (ø)
@tanstack/vue-query 71.10% <ø> (ø)
@tanstack/vue-query-devtools ∅ <ø> (∅)
:rocket: New features to boost your workflow:
  • :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • :package: JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

codecov[bot] avatar Jun 11 '25 21:06 codecov[bot]

More templates

@tanstack/angular-query-experimental

npm i https://pkg.pr.new/@tanstack/angular-query-experimental@9270
@tanstack/eslint-plugin-query

npm i https://pkg.pr.new/@tanstack/eslint-plugin-query@9270
@tanstack/query-async-storage-persister

npm i https://pkg.pr.new/@tanstack/query-async-storage-persister@9270
@tanstack/query-broadcast-client-experimental

npm i https://pkg.pr.new/@tanstack/query-broadcast-client-experimental@9270
@tanstack/query-core

npm i https://pkg.pr.new/@tanstack/query-core@9270
@tanstack/query-devtools

npm i https://pkg.pr.new/@tanstack/query-devtools@9270
@tanstack/query-persist-client-core

npm i https://pkg.pr.new/@tanstack/query-persist-client-core@9270
@tanstack/query-sync-storage-persister

npm i https://pkg.pr.new/@tanstack/query-sync-storage-persister@9270
@tanstack/react-query

npm i https://pkg.pr.new/@tanstack/react-query@9270
@tanstack/react-query-devtools

npm i https://pkg.pr.new/@tanstack/react-query-devtools@9270
@tanstack/react-query-next-experimental

npm i https://pkg.pr.new/@tanstack/react-query-next-experimental@9270
@tanstack/react-query-persist-client

npm i https://pkg.pr.new/@tanstack/react-query-persist-client@9270
@tanstack/solid-query

npm i https://pkg.pr.new/@tanstack/solid-query@9270
@tanstack/solid-query-devtools

npm i https://pkg.pr.new/@tanstack/solid-query-devtools@9270
@tanstack/solid-query-persist-client

npm i https://pkg.pr.new/@tanstack/solid-query-persist-client@9270
@tanstack/svelte-query

npm i https://pkg.pr.new/@tanstack/svelte-query@9270
@tanstack/svelte-query-devtools

npm i https://pkg.pr.new/@tanstack/svelte-query-devtools@9270
@tanstack/svelte-query-persist-client

npm i https://pkg.pr.new/@tanstack/svelte-query-persist-client@9270
@tanstack/vue-query

npm i https://pkg.pr.new/@tanstack/vue-query@9270
@tanstack/vue-query-devtools

npm i https://pkg.pr.new/@tanstack/vue-query-devtools@9270

commit: 1f2db27

pkg-pr-new[bot] avatar Jun 11 '25 21:06 pkg-pr-new[bot]

Walkthrough

Modularizes Angular devtools into dedicated devtools and devtools-panel submodules with production stubs and lazy dynamic imports; removes the legacy @tanstack/angular-query-devtools-experimental package and its build/config; updates package exports, examples, tests, and many autogenerated Angular docs and metadata.

Changes

Cohort / File(s) Summary
Devtools core & exports
packages/angular-query-experimental/src/devtools/*, packages/angular-query-experimental/package.json, packages/angular-query-experimental/src/index.ts
Add new devtools public module (types, withDevtools, production stub/index), optionalize @tanstack/query-devtools, add package exports for devtools/devtools-panel, remove top-level re-exports of devtools, add provideAngularQuery.
Devtools panel API & runtime
packages/angular-query-experimental/src/devtools-panel/*
Add devtools-panel types, runtime injectDevtoolsPanel implementation, production stub and production index, and re-export index.
Remove legacy devtools package
packages/angular-query-devtools-experimental/*
Delete legacy package manifest, source files, configs, tests, and build tooling; remove re-exports and example dependency.
Examples updated
examples/angular/*/src/app/app.config.ts, examples/angular/devtools-panel/*, examples/angular/devtools-panel/package.json
Update example imports to @tanstack/angular-query-experimental/devtools and .../devtools-panel; remove deprecated example dependency.
Tests adapted
packages/angular-query-experimental/src/__tests__/*
Update tests to new import locations, handle async dynamic imports, add lifecycle/platform scenarios, rename Devtools option fields (loadDeveloperToolsloadDevtools).
Docs: devtools guidance & index
docs/framework/angular/devtools.md, docs/framework/angular/reference/index.md, (removed) docs/.../functions/withdevtools.md
Rewrite devtools docs for DI-enabled withDevtools, add production import path guidance, remove old withDevtools doc, update index entries and public API listings.
Docs: autogenerated Angular references
docs/framework/angular/reference/**
Large batch of autogenerated metadata edits: DO NOT EDIT notices, inline “Defined in” links, unified type shapes, generic-arity fixes, literal renames (e.g., DeveloperToolsDevtools), and many page removals/relocations.
Examples: devtools-panel components
examples/angular/devtools-panel/src/app/components/*
Change import paths and dynamic import targets to new @tanstack/angular-query-experimental/devtools-panel.
Config & tooling
knip.json, package.json, codecov.yml, packages/angular-query-experimental/eslint.config.js
Add knip workspace entries for production entry points; remove pnpm override and codecov component for legacy devtools; simplify ESLint jsdoc rule.
Public API/type adjustments & annotations
packages/angular-query-experimental/src/*, many docs/...
Remove numerous @public JSDoc tags, adjust exported type aliases and generic arities (infinite/inject/mutation-related), and add new devtools types and overloads.
Misc: internals & doc snippets
packages/angular-query-experimental/src/inject-is-restoring.ts, packages/angular-query-experimental/src/mutation-options.ts, others
Internal token naming/documentation tweaks and JSDoc example reformatting.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor App as App bootstrap
  participant DI as Angular DI
  participant With as withDevtools
  participant Options as DevtoolsOptionsSignal
  participant Loader as DynamicImport(@tanstack/query-devtools)
  participant TD as TanstackQueryDevtools

  App->>DI: provideTanStackQuery(..., withDevtools(fn,{deps}))
  DI->>With: register providers & ENVIRONMENT_INITIALIZER
  With->>Options: derive reactive options (inject deps via DI)
  DI->>With: run initializer (browser only)
  alt loadDevtools true OR dev mode
    With->>Loader: import('@tanstack/query-devtools') (async)
    Loader-->>With: module
    With->>TD: new TanstackQueryDevtools(...) and mount to body
    Options-->>TD: apply updates reactively
  else skip
    With-->>DI: no-op (devtools not loaded)
  end
  DI->>TD: destroy on injector teardown
sequenceDiagram
  autonumber
  actor Component as Consumer
  participant Injector as Injector
  participant Fn as injectDevtoolsPanel
  participant Comp as computed options
  participant Loader as DynamicImport(@tanstack/query-devtools)
  participant Panel as TanstackQueryDevtoolsPanel

  Component->>Fn: call factory -> DevtoolsPanelOptions
  Fn->>Injector: runInInjectionContext (resolve DestroyRef, PLATFORM_ID)
  alt non-browser
    Fn-->>Component: return noop destroy
  else browser
    Fn->>Comp: compute options (hostElement?, client?, ...)
    alt hostElement appears & no panel
      Fn->>Loader: import('@tanstack/query-devtools') (async)
      Loader-->>Fn: module
      Fn->>Panel: new Panel(...) and mount(hostElement)
    else options change
      Fn->>Panel: update(client/errorTypes/onClose)
    else hostElement removed
      Fn->>Panel: destroy()
    end
    Injector->>Panel: ensure destroy on teardown
    Fn-->>Component: return destroy handle
  end

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • TanStack/query#9648 — Doc/example edits touching mutation-options examples; overlaps documentation changes in this PR.
  • TanStack/query#8817 — Prior work that changed DI behavior for devtools; conceptually related to DI-aware devtools loading and fixes.
  • (No further strongly code-linked PRs found.)

Suggested reviewers

  • TkDodo

"I nibble docs and hop between files,
I move the tools where production smiles.
If DI whispers yes, they'll wake and play,
else tucked away, they save the bundle's day.
A rabbit cheers—lazy imports all the way!" 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning While the devtools work is well scoped, the PR also contains several public API/type-surface changes that are not documented in the PR objectives and may be breaking, including mutationOptions overloads (mutation-options.ts), a change to CreateMutationResult to include BaseMutationNarrowing (types.ts), broad unification/retyping of query/infinite-query option types (query-options.ts, infinite-query-options.ts and related type-alias changes), and reducing generic arity in injectInfiniteQuery and related aliases; these type/signature changes go beyond the stated devtools/export objectives. Many documentation-only edits are fine, but the surfaced API/type changes should be explicitly justified or split out because they may affect downstream consumers. Request the author to either separate the unrelated public API/type changes into a distinct PR with rationale and migration notes or explicitly document and justify them in this PR (including compatibility tests and changelog entries); block merge until the scope and compatibility impact of those API/type changes are clarified and CI/tests run.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "feat(angular-query): move devtools to conditional sub-paths" is concise, follows conventional-commit style, and accurately summarizes the primary change (moving devtools to dedicated conditional sub-paths and related export/packaging work) as reflected across the diff. The title is specific to the main change and readable for teammates scanning history.
Linked Issues Check ✅ Passed The changes implement the linked-issue goals: conditional subpath exports, stubs, and making @tanstack/query-devtools optional to avoid emitting devtools chunks in production builds ([#9078]); adding DI-aware devtools options (deps support, DevtoolsOptionsManager and updated withDevtools API) to restore injection inside loadDevtools ([#8824]); and adding provider-scoped guards (DEVTOOLS_PROVIDED) plus lifecycle tests to avoid duplicate registrations and to support lazy-route/provider usage ([#8705]). Test additions and packaging/export edits in packages/angular-query-experimental align with these objectives and include explicit tests for injector lifecycle, platform gating, and dependency injection.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • [ ] 📝 Generate Docstrings
🧪 Generate unit tests
  • [ ] Create PR with unit tests
  • [ ] Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot] avatar Sep 02 '25 21:09 coderabbitai[bot]

I see this is in active development, thank you for your work @arnoud-dv 💪🏼

ThoSap avatar Sep 12 '25 17:09 ThoSap