Conversation
- validate-questions.mjs 新增 jsx check:esbuild(新增 devDependency)轉譯後以 renderToStaticMarkup 實際渲染比對 - react-1、react-2 共 12 題自動驗證通過;react-3、react-4 共 12 題屬互動行為, 標記 manual 待人工審(答案依 react.dev 對應文件撰寫) - 全題庫 72 題:1183 項檢查通過、0 失敗 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Warning Review limit reached
Next review available in:47 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
📝 WalkthroughWalkthroughAdds four React learning levels, JSX verification support, React chapter registration, and a two-step chapter/level navigation interface with progress and locking states. ChangesReact learning flow
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant ChapterMap
participant ChapterList
participant LevelList
ChapterMap->>ChapterList: render chapter selection
ChapterList->>ChapterMap: select chapterId
ChapterMap->>LevelList: render selected chapter
LevelList-->>ChapterMap: clear chapterId on back
ChapterMap->>ChapterList: render chapter selection again
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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 `@scripts/validate-questions.mjs`:
- Around line 26-38: Update runJsx to catch transformSync errors and return a
failed validation result instead of aborting the entire run. Move writeFileSync
into the existing try block so any created temporary file is always removed by
finally, including when JSX transformation or file writing fails.
In `@src/data/questions/react-4-hooks.json`:
- Around line 21-24: The useEffect explanation currently implies it always runs
after the browser paints. Update the explanation associated with the useEffect
question to say that React commits the rendered result first and then runs the
effect, without guaranteeing that the browser has painted; retain the examples
of post-commit work.
- Around line 34-46: 更新 react-4-hooks.json 中 Profile 題目的 prompt,將「結果 React
直接報錯」改為描述違反 Rules of Hooks,並指出在 isVip 於不同渲染間切換時可能因 Hook 順序錯亂而報錯;保留選項、答案與
explanation 不變。
🪄 Autofix (Beta)
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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: f7132944-56b4-44f7-839b-510cb1609a11
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (10)
docs/question-format.mdpackage.jsonscripts/validate-questions.mjssrc/data/chapters.jssrc/data/questions/react-1-jsx.jsonsrc/data/questions/react-2-props.jsonsrc/data/questions/react-3-state-events.jsonsrc/data/questions/react-4-hooks.jsonsrc/index.csssrc/screens/ChapterMap.jsx
| function runJsx(code) { | ||
| // esbuild 轉譯 JSX → 臨時 .mjs 檔(放專案根目錄才解析得到 node_modules 的 react) | ||
| const js = transformSync(code, { loader: 'jsx', jsx: 'automatic', format: 'esm' }).code | ||
| const tmp = join(PROJECT_ROOT, `.validate-tmp-${process.pid}-${Math.random().toString(36).slice(2)}.mjs`) | ||
| writeFileSync(tmp, js) | ||
| try { | ||
| const res = spawnSync('node', [tmp], { encoding: 'utf8', timeout: 10000, cwd: PROJECT_ROOT }) | ||
| return { stdout: (res.stdout || '').trim(), stderr: (res.stderr || '').trim(), status: res.status } | ||
| } finally { | ||
| rmSync(tmp, { force: true }) | ||
| } | ||
| } | ||
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash# Check surrounding context of the runJsx call at line 80
sed -n '70,90p' scripts/validate-questions.mjs
# Verify transformSync behavior on invalid JSX (run locally with esbuild installed)
node --input-type=module -e "import { transformSync } from 'esbuild'try { transformSync('const x = <div>', { loader: 'jsx', jsx: 'automatic', format: 'esm' }) console.log('transformSync did NOT throw')} catch (err) { console.log('transformSync threw:', err.message)}"Repository: Retsomm/EasyLearn
Length of output: 2191
Catch JSX transform errors in scripts/validate-questions.mjstransformSync can throw on invalid JSX and currently aborts the whole validation run; writeFileSync is also outside the cleanup guard. Wrap the transform in try/catch and move the file write inside the try so each question fails independently and temp files still get removed.
🤖 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 `@scripts/validate-questions.mjs` around lines 26 - 38, Update runJsx to catch
transformSync errors and return a failed validation result instead of aborting
the entire run. Move writeFileSync into the existing try block so any created
temporary file is always removed by finally, including when JSX transformation
or file writing fails.
| "explanation": "useEffect 的字面意思是「副作用」:React 先專心把畫面算完、畫到螢幕上(A),之後才回頭執行 effect(B)。所以 effect 裡拿得到已經存在的畫面,適合放「畫面好了之後才做」的事——抓資料、訂閱、操作 document。", | ||
| "verify": { | ||
| "checks": [], | ||
| "manual": "useEffect 在 SSR 不執行,需要瀏覽器環境;答案依 react.dev synchronizing-with-effects(effect 在 commit 後執行)" |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bashset -euo pipefail
# Inspect the referenced file and surrounding lines.
git ls-files src/data/questions/react-4-hooks.json
wc -l src/data/questions/react-4-hooks.json
sed -n '1,80p' src/data/questions/react-4-hooks.json
# Search for any other mentions of useEffect timing in the repo.
rg -n "useEffect|commit|paint|Strict Mode|effect" src/data/questions src -g '!**/*.map'Repository: Retsomm/EasyLearn
Length of output: 19159
Describe useEffect as after commit, not after paint.src/data/questions/react-4-hooks.json:21-24 The explanation is a bit too absolute: useEffect runs after commit, but not always after the browser paints. Reword the line to avoid implying the screen is guaranteed visible first.
🤖 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 `@src/data/questions/react-4-hooks.json` around lines 21 - 24, The useEffect
explanation currently implies it always runs after the browser paints. Update
the explanation associated with the useEffect question to say that React commits
the rendered result first and then runs the effect, without guaranteeing that
the browser has painted; retain the examples of post-commit work.
| "prompt": "想「有需要才建立 state」,結果 React 直接報錯。哪裡違規了?", | ||
| "code": "function Profile({ isVip }) {\n if (isVip) {\n const [badge, setBadge] = useState(\"⭐\"); // B 行\n }\n const [name, setName] = useState(\"小美\");\n return <p>{name}</p>;\n}", | ||
| "options": [ | ||
| { "id": "a", "text": "B 行把 useState 放進 if:Hook 必須每次渲染都以相同順序執行,不能寫在條件、迴圈裡" }, | ||
| { "id": "b", "text": "badge 的初始值不能是 emoji" }, | ||
| { "id": "c", "text": "一個元件最多只能有一個 useState" }, | ||
| { "id": "d", "text": "isVip 沒有預設值" } | ||
| ], | ||
| "answer": "a", | ||
| "explanation": "React 記 state 靠的是「呼叫順序」:第一個 useState、第二個 useState……像便當店叫號。放進 if 之後,isVip 一變,叫號順序整個亂掉,React 就把別人的 state 發給你。所以鐵律:Hook 只能寫在元件最上層。想條件式地「用」state 可以,條件式地「宣告」不行。", | ||
| "verify": { | ||
| "checks": [], | ||
| "manual": "違規要在 isVip 改變的第二次渲染才爆發,需互動環境;答案依 react.dev rules-of-hooks" |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
sed -n '1,120p' src/data/questions/react-4-hooks.jsonRepository: Retsomm/EasyLearn
Length of output: 5299
把「直接報錯」改成條件式違反 Hooks 規則
這段確實違反 Rules of Hooks,但不是每次都會立刻炸;isVip 在不同渲染間切換時才會出現 hook 順序錯亂,lint 也能先抓到。題幹可改成「違反 Hook 規則,切換狀態時可能報錯」更準。
🤖 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 `@src/data/questions/react-4-hooks.json` around lines 34 - 46, 更新
react-4-hooks.json 中 Profile 題目的 prompt,將「結果 React 直接報錯」改為描述違反 Rules of
Hooks,並指出在 isVip 於不同渲染間切換時可能因 Hook 順序錯亂而報錯;保留選項、答案與 explanation 不變。
- 配色改深紫灰底色系(color-scheme: dark),修正選項按鈕/進度條/徽章/ 分隔線等硬編碼淺色造成的深色錯誤,主要按鈕文字改深色提升對比 - 新增 Icons.jsx 線型圖示集(lucide 路徑、stroke=currentColor、零依賴), 取代所有 emoji UI 圖示:關卡狀態、章節、題型徽章、回饋、導覽、匯出入 - 吉祥物皮皮保留 emoji(角色非圖示) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
Summary by CodeRabbit
New Features
Style
Documentation