Skip to content

SolidJS Devtools '/production' export #9564

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

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

oscartbeaumont
Copy link
Contributor

@oscartbeaumont oscartbeaumont commented Aug 14, 2025

Align the SolidJS Query Devtools package with the React one by including the '/production' export which allows bundling TanStack Query Devtools in production builds.

Summary by CodeRabbit

  • New Features

    • Added a dedicated production entry for the devtools, enabling SSR-safe, on-demand (client-only) loading of components.
    • Exposed a typed options export for the devtools panel to improve TypeScript support.
  • Chores

    • Restructured package exports to provide clearer entry points for default and production usage.
    • Updated build configuration to generate outputs for both default and production entries.

Copy link

nx-cloud bot commented Aug 14, 2025

🤖 Nx Cloud AI Fix Eligible

An automatically generated fix could have helped fix failing tasks for this run, but Self-healing CI is disabled for this workspace. Visit workspace settings to enable it and get automatic fixes in future runs.

To disable these notifications, a workspace admin can disable them in workspace settings.


View your CI Pipeline Execution ↗ for commit d089b91

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

☁️ Nx Cloud last updated this comment at 2025-08-18 18:10:13 UTC

Copy link

pkg-pr-new bot commented Aug 14, 2025

More templates

@tanstack/angular-query-devtools-experimental

npm i https://pkg.pr.new/@tanstack/angular-query-devtools-experimental@9564

@tanstack/angular-query-experimental

npm i https://pkg.pr.new/@tanstack/angular-query-experimental@9564

@tanstack/eslint-plugin-query

npm i https://pkg.pr.new/@tanstack/eslint-plugin-query@9564

@tanstack/query-async-storage-persister

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

@tanstack/query-broadcast-client-experimental

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

@tanstack/query-core

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

@tanstack/query-devtools

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

@tanstack/query-persist-client-core

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

@tanstack/query-sync-storage-persister

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

@tanstack/react-query

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

@tanstack/react-query-devtools

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

@tanstack/react-query-next-experimental

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

@tanstack/react-query-persist-client

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

@tanstack/solid-query

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

@tanstack/solid-query-devtools

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

@tanstack/solid-query-persist-client

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

@tanstack/svelte-query

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

@tanstack/svelte-query-devtools

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

@tanstack/svelte-query-persist-client

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

@tanstack/vue-query

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

@tanstack/vue-query-devtools

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

commit: d089b91

Copy link

codecov bot commented Aug 14, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 8.51%. Comparing base (0991576) to head (4239a34).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main   #9564       +/-   ##
==========================================
- Coverage   45.14%   8.51%   -36.64%     
==========================================
  Files         208       4      -204     
  Lines        8316      47     -8269     
  Branches     1878      11     -1867     
==========================================
- Hits         3754       4     -3750     
+ Misses       4115      35     -4080     
+ Partials      447       8      -439     
Components Coverage Δ
@tanstack/angular-query-devtools-experimental ∅ <ø> (∅)
@tanstack/angular-query-experimental ∅ <ø> (∅)
@tanstack/eslint-plugin-query ∅ <ø> (∅)
@tanstack/query-async-storage-persister ∅ <ø> (∅)
@tanstack/query-broadcast-client-experimental ∅ <ø> (∅)
@tanstack/query-codemods ∅ <ø> (∅)
@tanstack/query-core ∅ <ø> (∅)
@tanstack/query-devtools ∅ <ø> (∅)
@tanstack/query-persist-client-core ∅ <ø> (∅)
@tanstack/query-sync-storage-persister ∅ <ø> (∅)
@tanstack/query-test-utils ∅ <ø> (∅)
@tanstack/react-query ∅ <ø> (∅)
@tanstack/react-query-devtools 8.51% <100.00%> (-1.49%) ⬇️
@tanstack/react-query-next-experimental ∅ <ø> (∅)
@tanstack/react-query-persist-client ∅ <ø> (∅)
@tanstack/solid-query ∅ <ø> (∅)
@tanstack/solid-query-devtools ∅ <ø> (∅)
@tanstack/solid-query-persist-client ∅ <ø> (∅)
@tanstack/svelte-query ∅ <ø> (∅)
@tanstack/svelte-query-devtools ∅ <ø> (∅)
@tanstack/svelte-query-persist-client ∅ <ø> (∅)
@tanstack/vue-query ∅ <ø> (∅)
@tanstack/vue-query-devtools ∅ <ø> (∅)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@TkDodo
Copy link
Collaborator

TkDodo commented Aug 14, 2025

but if that is desired there is currently no way for the developer to override it.

that’s not true, we have documentation on how to lazy load devtools in production:

https://tanstack.com/query/v5/docs/framework/react/devtools#devtools-in-production

@oscartbeaumont
Copy link
Contributor Author

Ahh, I came from the SolidJS side which doesn't have a similar feature and assumed it was unimplemented. Sorry!

Will update this PR to implement the /production export similar to what React does instead.

Copy link

coderabbitai bot commented Aug 18, 2025

Walkthrough

Exports in packages/solid-query-devtools/package.json were restructured to nested "." and "./production" entries, with updated build paths and an explicit "./package.json". A new src/production.tsx adds client-only dynamic wrappers for devtools components and re-exports a type. tsup.config.ts now builds two entries: index.tsx and production.tsx.

Changes

Cohort / File(s) Summary
Exports restructuring
packages/solid-query-devtools/package.json
Replaced flat exports with nested "." and "./production" maps; updated paths to build/index/* and build/production/*; changed custom-condition sources to .tsx; added "./package.json" export.
New production entry module
packages/solid-query-devtools/src/production.tsx
Added client-only dynamic wrappers: SolidQueryDevtools and SolidQueryDevtoolsPanel via lazy imports of ./devtools and ./devtoolsPanel; re-exported DevtoolsPanelOptions type.
Build config updates
packages/solid-query-devtools/tsup.config.ts
Switched to multiple entries: src/index.tsx and src/production.tsx; retained existing options and output to build/.

Sequence Diagram(s)

sequenceDiagram
  participant Consumer
  participant NodeResolver as Package Exports Resolver
  participant Env as Runtime (SSR/Client)
  participant Browser as ClientOnly Wrapper
  participant Devtools as Devtools Modules

  Consumer->>NodeResolver: import from "solid-query-devtools"
  NodeResolver-->>Consumer: Resolve "." or "./production" export paths

  alt Using "./production"
    Consumer->>Env: Render <SolidQueryDevtools/...>
    note over Env: SSR-safe placeholders
    Env->>Browser: On client, mount component
    Browser->>Devtools: dynamic import('./devtools' / './devtoolsPanel')
    Devtools-->>Browser: Loaded component
    Browser-->>Consumer: Render devtools
  else Using "."
    Consumer->>Env: Use base entry outputs
    Env-->>Consumer: Load corresponding build/index/* files
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

A rabbit taps the export map, click-click—neat!
New paths burrow deep where prod and dev now meet.
Two entries baked, tsup warms the build-burrow’s glow,
Client-only nibbles make SSR run slow? No!
With panels popped and types in tow—let’s go! 🐇✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
packages/solid-query-devtools/src/index.tsx (2)

12-13: Expose the optional fallback prop in the public type (nice-to-have)

clientOnly supports a fallback prop at runtime, but the exported type is typeof SolidQueryDevtoolsCompPanel (which doesn’t include fallback). Consider reflecting fallback in the type to improve DX.

You can adjust the typing like this (adds one import outside this hunk):

+import type { Component, JSX } from 'solid-js'
+import type { DevtoolsPanelOptions } from './devtoolsPanel'

Then change the export to:

-export const SolidQueryDevtoolsPanel: typeof SolidQueryDevtoolsCompPanel =
-  clientOnly(() => import('./devtoolsPanel'))
+export const SolidQueryDevtoolsPanel: Component<
+  DevtoolsPanelOptions & { fallback?: JSX.Element }
+> = clientOnly(() => import('./devtoolsPanel'))

Alternatively, keep current typing but document that a fallback prop is accepted at runtime.


12-13: Plan the Solid “/production” entrypoint for parity with React docs

Given the discussion, please confirm a /production export for Solid mirrors React’s pattern (docs link in PR comments). If that’s part of this effort, ensure package.json exports and docs are updated accordingly so consumers have a documented path to include the panel in production.

Happy to draft the exports map and doc snippet for Solid’s /production entrypoint if you want.

packages/react-query-devtools/src/index.ts (1)

13-14: Call out potential behavior change for consumers rendering the Panel unconditionally

Previously, ReactQueryDevtoolsPanel would no-op in production; now it will render. If any consumers relied on the old behavior, this is a visible change. Consider a changelog note and confirm the intended semver impact. Also ensure the docs clearly show how to include the Panel in production (and how to keep it out if desired).

I can propose a short changelog entry and doc update to the “Devtools in production” section covering the Panel specifically.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 2989e69 and 228139f.

📒 Files selected for processing (2)
  • packages/react-query-devtools/src/index.ts (1 hunks)
  • packages/solid-query-devtools/src/index.tsx (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/solid-query-devtools/src/index.tsx (2)
packages/solid-query-devtools/src/devtoolsPanel.tsx (1)
  • SolidQueryDevtoolsPanel (43-85)
packages/solid-query-devtools/src/clientOnly.tsx (1)
  • clientOnly (17-43)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Test
  • GitHub Check: Preview
🔇 Additional comments (2)
packages/solid-query-devtools/src/index.tsx (1)

12-13: Un-gating SolidQueryDevtoolsPanel via clientOnly is SSR-safe and matches the PR goal

Always using clientOnly(() => import('./devtoolsPanel')) removes the dev-only guard while keeping SSR safety (server returns fallback). This lets consumers opt-in to include the panel in production, as intended.

packages/react-query-devtools/src/index.ts (1)

13-14: Directly exposing ReactQueryDevtoolsPanel is straightforward and aligns with the opt-in production usage

Removing the NODE_ENV guard for the Panel export enables intentional inclusion in production builds while keeping ReactQueryDevtools itself gated. This matches the intent of the PR.

@oscartbeaumont
Copy link
Contributor Author

oscartbeaumont commented Aug 18, 2025

This should be updated and ready to go but could be worth getting a review from anyone with better expirence on package.json exports as i'm far from an expert on them.

I will fix up the CodeRabbit comments and test failure in the morning!

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🔭 Outside diff range comments (1)
packages/solid-query-devtools/tsup.config.ts (1)

23-25: Refactor tsup outDir to match nested export paths

The override tsup_option.outDir = 'build' flattens both entry outputs into build/, which conflicts with your package.json exports (./build/index/... vs ./build/production/...) and risks overwriting files. Update the config so each entry emits into its own subfolder:

• File: packages/solid-query-devtools/tsup.config.ts
• Lines: 23–25

Apply this diff:

-  tsup_options.forEach((tsup_option) => {
-    tsup_option.outDir = 'build'
-  })
+  tsup_options.forEach((tsup_option, i) => {
+    const entry = preset_options.entries?.[i]?.entry
+    if (typeof entry === 'string') {
+      // derive "index" or "production" from "src/<name>.tsx"
+      const base = entry.split('/').pop()?.replace(/\.(t|j)sx?$/, '')
+      if (base) tsup_option.outDir = `build/${base}`
+    }
+  })

This aligns outputs with your export map:

  • exports["."].*./build/index/...
  • exports["./production"].*./build/production/...
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 228139f and d089b91.

📒 Files selected for processing (3)
  • packages/solid-query-devtools/package.json (1 hunks)
  • packages/solid-query-devtools/src/production.tsx (1 hunks)
  • packages/solid-query-devtools/tsup.config.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/solid-query-devtools/src/production.tsx (1)
packages/solid-query-devtools/src/clientOnly.tsx (1)
  • clientOnly (17-43)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Preview
  • GitHub Check: Test
🔇 Additional comments (4)
packages/solid-query-devtools/tsup.config.ts (1)

5-14: Good call adding a second entry for production wrappers

Adding src/production.tsx as its own entry aligns with the new ./production export block and enables distinct build outputs. Keeping dev_entry: true for both entries is consistent with the development sub-exports.

packages/solid-query-devtools/src/production.tsx (1)

12-12: Re-export of DevtoolsPanelOptions is correct

Keeping the type re-export here ensures parity with the main entry and helps consumers avoid deep imports.

packages/solid-query-devtools/package.json (2)

40-58: Exports restructure for “.” looks consistent with multi-entry output

The nested build/index/... targets match the intent to separate artifacts by entry. This aligns with adding src/index.tsx as its own entry.


78-78: Explicit ./package.json export is a good addition

This improves compatibility with tooling that reads package metadata via the exports map.

Comment on lines +59 to 77
"./production": {
"@tanstack/custom-condition": "./src/production.tsx",
"solid": {
"development": "./build/production/dev.jsx",
"import": "./build/production/index.jsx"
},
"development": {
"import": {
"types": "./build/production/index.d.ts",
"default": "./build/production/dev.js"
},
"require": "./build/production/dev.cjs"
},
"import": {
"types": "./build/production/index.d.ts",
"default": "./build/production/index.js"
},
"require": "./build/production/index.cjs"
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Production export block LGTM; ensure top-level fields are aligned and build outputs land in the nested folders

The ./production block mirrors the root export and points to build/production/... as expected. Combined with the current tsup config, ensure each entry emits into its own subdir (see tsup.config.ts comment).

Also, the top-level main, module, and types fields still point to ./build/index.* (without the extra directory level). With nested outputs, these should be updated to the new locations to avoid resolution breakage for tools that still read these fields.

[ suggest_essential_refactor ]

Apply these top-level updates (outside the changed hunk) to keep everything consistent:

{
  "main": "./build/index/index.cjs",
  "module": "./build/index/index.js",
  "types": "./build/index/index.d.ts"
}

And run this check to surface any discrepancies:

Expected: top-level main/module/types paths should correspond to the ./build/index/index.* files referenced under the . export.


🏁 Script executed:

#!/bin/bash
set -euo pipefail

cd packages/solid-query-devtools

echo "Top-level fields:"
jq -r '.main, .module, .types' package.json

echo
echo "Exports for root entry:"
jq -r '.exports["."].import.default, .exports["."].require, .exports["."].development.import.default, .exports["."].import.types' package.json

Length of output: 502


Align top-level main/module/types with nested exports

The verification shows your root exports land in ./build/index/..., but the top-level fields still point to ./build/index.*. Update these to avoid resolution mismatches:

In packages/solid-query-devtools/package.json, change:

--- package.json
@@ Lines 59-77
-  "main": "./build/index.cjs",
-  "module": "./build/index.js",
-  "types": "./build/index.d.ts",
+  "main": "./build/index/index.cjs",
+  "module": "./build/index/index.js",
+  "types": "./build/index/index.d.ts"

After applying, re-run the jq check to confirm:

cd packages/solid-query-devtools
jq -r '.main, .module, .types, .exports["."].import.default, .exports["."].require, .exports["."].development.import.default, .exports["."].import.types' package.json

Expected output paths should all reference ./build/index/index.*.

🤖 Prompt for AI Agents
In packages/solid-query-devtools/package.json around lines 59 to 77, the
package's nested exports point to files under ./build/index/... but the
top-level "main", "module", and "types" fields (and several nested export paths)
still reference the old ./build/production/* locations; update the top-level
fields "main", "module", and "types" to ./build/index/index.cjs,
./build/index/index.js, and ./build/index/index.d.ts respectively, and change
the export entries (.exports["."].import.default, .exports["."].require,
.exports["."].development.import.default, .exports["."].import.types) to
reference ./build/index/index.* so all paths consistently use
./build/index/index.*, then re-run the provided jq command to verify the outputs
point to ./build/index/index.* as expected.

Comment on lines +2 to +3
import type SolidQueryDevtoolsComp from './devtools'
import type SolidQueryDevtoolsCompPanel from './devtoolsPanel'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Type-only default imports with typeof cause a TS error; annotate with the default export type instead

import type SolidQueryDevtoolsComp from './devtools' creates a type-only symbol. Using typeof SolidQueryDevtoolsComp then refers to a value that does not exist at runtime, which is a TypeScript error. The same applies to devtoolsPanel.

Annotate the exports with the default export’s type directly, and adjust the imports accordingly.

Apply this diff:

-import type SolidQueryDevtoolsComp from './devtools'
-import type SolidQueryDevtoolsCompPanel from './devtoolsPanel'
+import type { default as SolidQueryDevtoolsComp } from './devtools'
+import type { default as SolidQueryDevtoolsCompPanel } from './devtoolsPanel'

-export const SolidQueryDevtools: typeof SolidQueryDevtoolsComp = clientOnly(
+export const SolidQueryDevtools: SolidQueryDevtoolsComp = clientOnly(
   () => import('./devtools'),
 )
 
-export const SolidQueryDevtoolsPanel: typeof SolidQueryDevtoolsCompPanel =
-  clientOnly(() => import('./devtoolsPanel'))
+export const SolidQueryDevtoolsPanel: SolidQueryDevtoolsCompPanel = clientOnly(
+  () => import('./devtoolsPanel'),
+)

Also applies to: 5-10

🤖 Prompt for AI Agents
In packages/solid-query-devtools/src/production.tsx lines 2–3 (and similarly
lines 5–10), the code uses type-only default imports and then refers to typeof
on those names which fails at runtime; replace the type-only default imports
with a type import that references the module's default export type (e.g.,
import type { default as X } from './module') and annotate the exported values
with that imported type instead of using typeof, updating both devtools and
devtoolsPanel imports/exports accordingly.

@oscartbeaumont oscartbeaumont changed the title Allow including devtools panel in production builds SolidJS Devtools '/production' export Aug 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants