Repository navigation
fix(dev): icon codemod keeps the use-client directive first and reports multi-line dynamic spans (KEA-7886) - #17410
Merged
Conversation
…ts multi-line dynamic spans (KEA-7886)
The import is now inserted after the directive prologue (leading comments + "use client"/'use server' lines) instead of at offset 0, with a guard that throws if the output's directives differ from the input's. Leftover detection scans whole JSX opening tags (brace/string aware) instead of single lines, so multi-line dynamic spans are reported at their <span line and the CLI exits 2; multi-line spans with a static className (including {`...`} without ${}) are normalised and converted.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Track B of the Keak CI UI Kit migration (KEA-7886). Fixes two bugs in
scripts/dev/codemod-material-icons.mjsthat lotes 1 and 2a ran into. Every remaining lote would hit them too.Bug 1: import lands above
"use client"Before:
import Icon from "@/shared/components/Icon";went in at offset 0, above the directive. The directive was then no longer the first statement, so Next.js treated the module as a server component and both dev and build broke. Unit tests stayed green. The old code only recognised"use client";when it was byte 0 of the file.Fix: a new
directivePrologue()skips leading whitespace and////* */comments plus any"use …"/'use …'directive lines, and the import goes in right after the last directive line. Files with no directive behave as before (import at the top). As a guard,transformSourcethrows when the output's directive prologue differs from the input's, so it can never emit an import above a directive.Bug 2: multi-line dynamic spans neither converted nor reported
Before: leftover detection matched
<span…material-symbols-outlinedone line at a time, so a tag spread over several lines matched nothing. The span stayed as it was, nothing reported it, and the script exited 0.Fix: leftovers now come from scanning whole JSX opening tags (it understands braces, strings and template literals, so
=>anda > bdon't end the tag). Each leftover is reported asmanual: file:lineat the line of its<span, and the CLI exits 2. Multi-line spans whose className is static ("…",{"…"}, or{`…`}without${}) get their whitespace normalised and then go through the existing single-line transform, so they convert. Anything else is reported.Tests
tests/unit/codemod-material-icons.test.ts: 4 → 10 cases. Written first and confirmed failing (5 red), then green. The existing 4 cases are unchanged."use client"+ Material span: the directive is still the first statement, and the import comes after it and before the existing imports'use client',"use server";,'use client';behind line and block commentscn(...)multi-line dynamic spans: reported at lines 4 and 10, code untouched<Icon name="search" size={18} className="text-text-muted" />cn(...)span: exit 2 andmanual: …/Multi.tsx:2Validation:
node --import tsx/esm --test tests/unit/codemod-material-icons.test.ts(10/10),npx prettier --checkon both files,npx eslint(the test is clean; the.mjsscript is under an ESLint ignore pattern),npm run typecheck:core. The codemod was not run onsrc/in this PR.