Skip to content

[v2] perf(devtools): avoid lucide barrel file - #2322

Merged
LeCarbonator merged 3 commits into
TanStack:alphafrom
43081j:jg/faster-tests-devtools
Aug 11, 2026
Merged

[v2] perf(devtools): avoid lucide barrel file#2322
LeCarbonator merged 3 commits into
TanStack:alphafrom
43081j:jg/faster-tests-devtools

Conversation

@43081j

@43081j 43081j commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

🎯 Changes

The lucide-solid entrypoint is a rather large barrel file. This means
it is fairly expensive to import, particularly in the tests (vitest)
since it needs to analyse and transform each imported file.

This adds a new ESLint rule to disallow importing icons from
lucide-solid and require they be imported directly from
lucide-solid/icons/{name}. It also applies that rule to the current
usages.

Locally, the test run now takes ~4s instead of ~8s.

This also switches from jsdom to real browser tests. We may need to alter the CI workflow to playwright install chromium for this to work.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • Refactor

    • Standardized icon loading across the form devtools interface.
    • Added linting guidance to encourage consistent icon imports.
    • No user-facing functionality or visual behavior changed.
  • Tests

    • Updated component testing to run in a real headless Chromium browser.
    • Improved test environment compatibility by removing obsolete resize-observer setup.
    • Added browser testing support for more realistic validation.

43081j added 2 commits August 11, 2026 10:42
The `lucide-solid` entrypoint is a rather large barrel file. This means
it is fairly expensive to import, particularly in the tests (vitest)
since it needs to analyse and transform each imported file.

This adds a new ESLint rule to disallow importing icons from
`lucide-solid` and require they be imported directly from
`lucide-solid/icons/{name}`. It also applies that rule to the current
usages.

Locally, the test run now takes ~4s instead of ~8s.
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key: "base_branches"
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • 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
📝 Walkthrough

Walkthrough

The change enforces direct Lucide icon imports and updates form-devtools Vitest configuration to use the Playwright provider with headless Chromium.

Changes

Lucide icon import enforcement

Layer / File(s) Summary
Direct icon import policy
eslint.config.js
ESLint rejects value imports of icon names from the lucide-solid barrel and suggests individual icon paths.
Form-devtools icon migration
packages/form-devtools/src/components/**/*.tsx, packages/form-devtools/src/hooks/createFieldListSearch.tsx
Existing Lucide imports now use individual lucide-solid/icons/* modules. Component behavior remains unchanged.

Browser-based Vitest configuration

Layer / File(s) Summary
Playwright browser test setup
package.json, packages/form-devtools/vite.config.ts
The Playwright provider is added. Vitest now runs browser tests in headless Chromium and resolves paths with import.meta.dirname.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Vitest
  participant Playwright
  participant Chromium
  Vitest->>Playwright: use the browser provider
  Playwright->>Chromium: launch headless Chromium
  Chromium-->>Vitest: execute browser tests
Loading

Suggested reviewers: lecarbonator

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the primary change: avoiding the lucide-solid barrel file in devtools.
Description check ✅ Passed The description explains the changes and motivation, completes the checklist, and identifies the work as dev-only with no release impact.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@nx-cloud

nx-cloud Bot commented Aug 11, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit d788e76

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

☁️ Nx Cloud last updated this comment at 2026-08-11 12:53:42 UTC

@pkg-pr-new

pkg-pr-new Bot commented Aug 11, 2026

Copy link
Copy Markdown
More templates

@tanstack/angular-form

npm i https://pkg.pr.new/@tanstack/angular-form@2322

@tanstack/form-core

npm i https://pkg.pr.new/@tanstack/form-core@2322

@tanstack/form-devtools

npm i https://pkg.pr.new/@tanstack/form-devtools@2322

@tanstack/lit-form

npm i https://pkg.pr.new/@tanstack/lit-form@2322

@tanstack/preact-form

npm i https://pkg.pr.new/@tanstack/preact-form@2322

@tanstack/react-form

npm i https://pkg.pr.new/@tanstack/react-form@2322

@tanstack/react-form-devtools

npm i https://pkg.pr.new/@tanstack/react-form-devtools@2322

@tanstack/react-form-nextjs

npm i https://pkg.pr.new/@tanstack/react-form-nextjs@2322

@tanstack/react-form-start

npm i https://pkg.pr.new/@tanstack/react-form-start@2322

@tanstack/solid-form

npm i https://pkg.pr.new/@tanstack/solid-form@2322

@tanstack/solid-form-devtools

npm i https://pkg.pr.new/@tanstack/solid-form-devtools@2322

@tanstack/svelte-form

npm i https://pkg.pr.new/@tanstack/svelte-form@2322

@tanstack/vue-form

npm i https://pkg.pr.new/@tanstack/vue-form@2322

commit: d788e76

@LeCarbonator

LeCarbonator commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Looks like you'll need the reference for the chromium binary after all.

This should be the correct ubuntu image.

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (alpha@07aa51c). Learn more about missing BASE report.
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@           Coverage Diff            @@
##             alpha    #2322   +/-   ##
========================================
  Coverage         ?   95.08%           
========================================
  Files            ?       64           
  Lines            ?     3461           
  Branches         ?      841           
========================================
  Hits             ?     3291           
  Misses           ?      163           
  Partials         ?        7           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 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.

@LeCarbonator
LeCarbonator merged commit d822f66 into TanStack:alpha Aug 11, 2026
8 of 9 checks passed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@eslint.config.js`:
- Line 25: Update the lucide-solid import selector in the ESLint configuration
to reject every value import, not only named imports whose names end with Icon.
Match value ImportSpecifier nodes without the imported-name restriction and add
equivalent selectors for value ImportNamespaceSpecifier and
ImportDefaultSpecifier while preserving type-import exemptions.

In `@packages/form-devtools/vite.config.ts`:
- Around line 73-76: Update the provider configuration in the Vite setup around
playwright so CI-distributed Nx Cloud agents use an available browser: either
ensure Google Chrome is installed in the linux-medium-js agent image before
tests, or switch the CI launch configuration to Playwright Chromium and install
that browser during setup. Preserve the existing local development behavior.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 4a252d72-8263-4322-8750-bbe453f81365

📥 Commits

Reviewing files that changed from the base of the PR and between 07aa51c and d788e76.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (20)
  • eslint.config.js
  • package.json
  • packages/form-devtools/src/components/fields/fieldDetails/FieldDetailSettingsActions.tsx
  • packages/form-devtools/src/components/fields/fieldDetails/FieldDetailSettingsMenu.tsx
  • packages/form-devtools/src/components/fields/fieldDetails/fieldErrors/ErrorExtraInfoPopover.tsx
  • packages/form-devtools/src/components/fields/fieldDetails/fieldErrors/FieldDetailErrorItem.tsx
  • packages/form-devtools/src/components/fields/fieldDetails/fieldErrors/FieldDetailErrorSourceText.tsx
  • packages/form-devtools/src/components/fields/fieldDetails/fieldErrors/FieldNoErrorsItem.tsx
  • packages/form-devtools/src/components/fields/leftPanel/FieldListItems.tsx
  • packages/form-devtools/src/components/fields/leftPanel/listSearch/FieldFilterChip.tsx
  • packages/form-devtools/src/components/fields/leftPanel/listSearch/FieldListSearch.tsx
  • packages/form-devtools/src/components/header/Header.tsx
  • packages/form-devtools/src/components/ui/accordion.tsx
  • packages/form-devtools/src/components/ui/copy-button.tsx
  • packages/form-devtools/src/components/ui/dropdown-menu.tsx
  • packages/form-devtools/src/components/ui/json-tree.tsx
  • packages/form-devtools/src/components/ui/select.tsx
  • packages/form-devtools/src/hooks/createFieldListSearch.tsx
  • packages/form-devtools/tests/test-setup.ts
  • packages/form-devtools/vite.config.ts
💤 Files with no reviewable changes (1)
  • packages/form-devtools/tests/test-setup.ts

Comment thread eslint.config.js
'error',
{
selector:
"ImportDeclaration[source.value='lucide-solid'][importKind!='type'] > ImportSpecifier[importKind!='type'][imported.name=/Icon$/]",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -nP --glob '*.{js,jsx,ts,tsx}' \
  "(import\s*\{[^}]+\bas\s+[^}]+\}\s*from\s*['\"]lucide-solid['\"]|import\s+\*\s+as\s+\w+\s+from\s*['\"]lucide-solid['\"]|import\s+\w+\s+from\s*['\"]lucide-solid['\"])" .

Repository: TanStack/form

Length of output: 151


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- eslint.config.js ---'
cat -n eslint.config.js | sed -n '1,55p'

printf '%s\n' '--- lucide-solid imports ---'
rg -n --glob '*.{js,jsx,ts,tsx}' "from ['\"]lucide-solid['\"]|import ['\"]lucide-solid['\"]" .

printf '%s\n' '--- relevant rule context ---'
rg -n -C 8 "lucide-solid|no-restricted-syntax|Icon\\$" eslint.config.js

Repository: TanStack/form

Length of output: 2448


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- available JavaScript parser ---'
node - <<'JS'
for (const name of ['espree', '`@typescript-eslint/parser`', 'esquery']) {
  try {
    console.log(name, require.resolve(name))
  } catch {
    console.log(name, 'unavailable')
  }
}
JS

printf '%s\n' '--- package metadata for lucide-solid ---'
rg -n -C 3 '"lucide-solid"|lucide-solid/' package.json packages pnpm-lock.yaml yarn.lock package-lock.json 2>/dev/null || true

Repository: TanStack/form

Length of output: 13257


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

pattern = re.compile(
    r"""^\s*import\s+(?P<clause>.+?)\s+from\s+['"]lucide-solid['"]\s*;?\s*$"""
)

forms = []
for path in Path(".").rglob("*"):
    if not path.is_file() or path.suffix not in {".js", ".jsx", ".ts", ".tsx"}:
        continue
    try:
        lines = path.read_text().splitlines()
    except UnicodeDecodeError:
        continue
    for number, line in enumerate(lines, 1):
        match = pattern.match(line)
        if match:
            forms.append((str(path), number, match.group("clause")))

print(f"direct lucide-solid imports: {len(forms)}")
for path, number, clause in forms:
    print(f"{path}:{number}: {clause}")
PY

Repository: TanStack/form

Length of output: 265


Restrict all value imports from lucide-solid.

The selector only matches named exports ending in Icon. Match all value ImportSpecifier nodes and add selectors for ImportNamespaceSpecifier and ImportDefaultSpecifier.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@eslint.config.js` at line 25, Update the lucide-solid import selector in the
ESLint configuration to reject every value import, not only named imports whose
names end with Icon. Match value ImportSpecifier nodes without the imported-name
restriction and add equivalent selectors for value ImportNamespaceSpecifier and
ImportDefaultSpecifier while preserving type-import exemptions.

Source: MCP tools

Comment on lines +73 to +76
// CI runners (ubuntu-latest) ship with Google Chrome preinstalled, so
// use it rather than downloading playwright's own browser build
provider: playwright(
process.env.CI ? { launchOptions: { channel: 'chrome' } } : {},

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

workflow_files="$(fd -t f -e yml -e yaml . || true)"

if [[ -z "$workflow_files" ]]; then
  printf '%s\n' 'No YAML workflow files found.'
  exit 0
fi

while IFS= read -r workflow; do
  printf '\n== %s ==\n' "$workflow"
  rg -n -C 5 \
    'runs-on:|ubuntu-latest|ubuntu-24\.04|form-devtools|test:lib|playwright install|google-chrome|chromium' \
    "$workflow" || true
done <<< "$workflow_files"

Repository: TanStack/form

Length of output: 14605


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '== workflow and CI configuration files =='
git ls-files | rg '(^|/)(\.github/workflows|.*(workflow|ci).*\.(yml|yaml)|package\.json|vite\.config\.(ts|js|mjs|cjs))$' || true

printf '%s\n' '== relevant package metadata =='
pkg='packages/form-devtools/package.json'
if [[ -f "$pkg" ]]; then
  cat -n "$pkg"
else
  printf 'Missing %s\n' "$pkg"
fi

printf '%s\n' '== Vite configuration =='
cat -n packages/form-devtools/vite.config.ts

printf '%s\n' '== references to form-devtools test commands and CI =='
rg -n -C 4 'form-devtools|test:lib|playwright|CI|runs-on|ubuntu|google-chrome|browser' \
  --glob '!pnpm-lock.yaml' --glob '!**/node_modules/**' . || true

Repository: TanStack/form

Length of output: 50372


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

for workflow in .github/workflows/pr.yml .github/workflows/autofix.yml .github/workflows/release.yml; do
  printf '\n== %s: jobs, runners, and browser setup ==\n' "$workflow"
  rg -n -C 8 '^\s*(name:|runs-on:|working-directory:|run:|pnpm|nx|test:lib|playwright|chrome|chromium|CI:)' "$workflow" \
    | sed -n '1,260p'
done

printf '\n== direct workflow references to form-devtools ==\n'
rg -n -C 10 'form-devtools|test:lib' .github/workflows || true

printf '\n== workflow-wide runner declarations ==\n'
rg -n 'runs-on:|ubuntu-[0-9.]+|ubuntu-latest|windows-|macos-' .github/workflows

Repository: TanStack/form

Length of output: 5688


🌐 Web query:

GitHub Actions ubuntu-latest hosted runner Ubuntu 24.04 installed software Google Chrome official runner-images documentation

💡 Result:

The GitHub Actions ubuntu-latest hosted runner is currently based on Ubuntu 24.04 and includes Google Chrome pre-installed as part of its standard software suite [1][2][3]. Key details regarding Google Chrome on the ubuntu-latest runner: Pre-installed Software: Google Chrome (along with matching ChromeDriver and Chromium) is included in the default software image provided by GitHub [3][4]. The installation is automated during the image build process [5][6]. Versioning and Updates: GitHub regularly updates the runner images, which includes updating the installed version of Google Chrome to remain near the latest stable release [7][8]. Because these updates occur periodically (often weekly or upon new image releases), the exact version of Chrome may vary slightly between updates [7][9]. You can verify the currently installed version in your workflow using the command: /usr/bin/google-chrome --version [10][9]. Accessing the Browser: The browser is available in the system PATH [10]. You can retrieve its path using the command which google-chrome [10]. Important Considerations: - No GUI: The GitHub-hosted Ubuntu runners do not have a graphical user interface (GUI) [10]. When running tests (e.g., with Selenium or Playwright), you must configure your browser to run in headless mode [10]. - Environment Variables: The location of the associated ChromeDriver is typically exposed through the CHROMEWEBDRIVER environment variable [4]. For the most up-to-date and specific list of all software installed on the current ubuntu-latest runner, you should refer to the official Ubuntu 24.04 Readme in the actions/runner-images repository [1][2].

Citations:


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '== Nx distributed CI configuration =='
cat -n .nx/workflows/dynamic-changesets.yaml

printf '%s\n' '== test target configuration =='
cat -n nx.json | sed -n '1,90p'

Repository: TanStack/form

Length of output: 2472


🌐 Web query:

Nx Cloud distributed task execution linux-medium-js image Google Chrome Playwright browser availability

💡 Result:

The Nx Cloud linux-medium-js agent image does not come with Google Chrome pre-installed [1][2]. While the images are frequently updated to include necessary Playwright system dependencies (such as libraries required for browser execution), they do not include the browsers themselves [1][2]. To use Playwright with Google Chrome on these agents, you must install the browser and its dependencies during your CI run. The standard practice is to include a step in your CI configuration to run the following command [1][3][4]: npx playwright install --with-deps This ensures that the required Playwright system dependencies are present and that the Chromium-based browser (or other browsers) is installed and ready for your E2E tests [1][3]. Documentation explicitly notes that recent image updates have focused on ensuring these system-level dependencies for Playwright are kept current, simplifying this installation process [1][2].

Citations:


Install the selected browser on Nx Cloud agents.

test:pr distributes test:lib tasks to linux-medium-js agents. Those agents do not provide Google Chrome, so channel: 'chrome' can fail when packages/form-devtools runs there. Install Google Chrome in the agent image, or use Playwright Chromium and install it before the test.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/form-devtools/vite.config.ts` around lines 73 - 76, Update the
provider configuration in the Vite setup around playwright so CI-distributed Nx
Cloud agents use an available browser: either ensure Google Chrome is installed
in the linux-medium-js agent image before tests, or switch the CI launch
configuration to Playwright Chromium and install that browser during setup.
Preserve the existing local development behavior.

Source: MCP tools

@43081j
43081j deleted the jg/faster-tests-devtools branch August 11, 2026 13:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants