[v2] perf(devtools): avoid lucide barrel file - #2322
Conversation
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.
|
Note
|
| 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
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.
Comment @coderabbitai help to get the list of available commands.
|
View your CI Pipeline Execution ↗ for commit d788e76
☁️ Nx Cloud last updated this comment at |
|
Looks like you'll need the reference for the chromium binary after all. This should be the correct ubuntu image. |
|
Codecov Report✅ All modified and coverable lines are covered by tests. 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. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
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
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (20)
eslint.config.jspackage.jsonpackages/form-devtools/src/components/fields/fieldDetails/FieldDetailSettingsActions.tsxpackages/form-devtools/src/components/fields/fieldDetails/FieldDetailSettingsMenu.tsxpackages/form-devtools/src/components/fields/fieldDetails/fieldErrors/ErrorExtraInfoPopover.tsxpackages/form-devtools/src/components/fields/fieldDetails/fieldErrors/FieldDetailErrorItem.tsxpackages/form-devtools/src/components/fields/fieldDetails/fieldErrors/FieldDetailErrorSourceText.tsxpackages/form-devtools/src/components/fields/fieldDetails/fieldErrors/FieldNoErrorsItem.tsxpackages/form-devtools/src/components/fields/leftPanel/FieldListItems.tsxpackages/form-devtools/src/components/fields/leftPanel/listSearch/FieldFilterChip.tsxpackages/form-devtools/src/components/fields/leftPanel/listSearch/FieldListSearch.tsxpackages/form-devtools/src/components/header/Header.tsxpackages/form-devtools/src/components/ui/accordion.tsxpackages/form-devtools/src/components/ui/copy-button.tsxpackages/form-devtools/src/components/ui/dropdown-menu.tsxpackages/form-devtools/src/components/ui/json-tree.tsxpackages/form-devtools/src/components/ui/select.tsxpackages/form-devtools/src/hooks/createFieldListSearch.tsxpackages/form-devtools/tests/test-setup.tspackages/form-devtools/vite.config.ts
💤 Files with no reviewable changes (1)
- packages/form-devtools/tests/test-setup.ts
| 'error', | ||
| { | ||
| selector: | ||
| "ImportDeclaration[source.value='lucide-solid'][importKind!='type'] > ImportSpecifier[importKind!='type'][imported.name=/Icon$/]", |
There was a problem hiding this comment.
🎯 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.jsRepository: 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 || trueRepository: 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}")
PYRepository: 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
| // 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' } } : {}, |
There was a problem hiding this comment.
🩺 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/**' . || trueRepository: 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/workflowsRepository: 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:
- 1: https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md
- 2: https://github.com/actions/runner-images
- 3: https://github.com/github/gh-aw/blob/main/research/ubuntulatest.md
- 4: https://github.com/actions/runner-images/blob/ubuntu24/20241208.1/images/ubuntu/Ubuntu2404-Readme.md
- 5: https://github.com/actions/runner-images/blob/main/images/ubuntu/scripts/build/install-google-chrome.sh
- 6: https://github.com/actions/runner-images/blob/bb03b541e0a63c964dcf851817585d4bb4b38675/images/linux/scripts/installers/google-chrome.sh
- 7: https://github.com/actions/runner-images/releases/tag/ubuntu24/20260726.254
- 8: Update the version of Chrome shipped with the ubuntu-latest image actions/runner-images#10726
- 9: Ubuntu 22.04 Chrome and Chromedriver out of date actions/runner-images#7699
- 10: Chrome in ubuntu-latest actions/runner-images#6165
🏁 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:
- 1: https://nx.dev/docs/reference/nx-cloud/launch-templates
- 2: https://canary.nx.dev/docs/reference/nx-cloud/launch-templates
- 3: https://github.com/plait-board/drawnix/blob/7a2f4da33bfacc97a98ac67e76c52a8d9eea7d50/.github/workflows/ci.yml
- 4: https://github.com/plait-board/drawnix/blob/088f9e162a9d36cad52d43ba57d3d287a953f141/.github/workflows/ci.yml
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
🎯 Changes
The
lucide-solidentrypoint is a rather large barrel file. This meansit 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-solidand require they be imported directly fromlucide-solid/icons/{name}. It also applies that rule to the currentusages.
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 chromiumfor this to work.✅ Checklist
pnpm test:pr.🚀 Release Impact
Summary by CodeRabbit
Refactor
Tests