Skip to content

t1k:cocos:migration:compref

FieldValue
Modulemigration
Version0.3.0
Effortmedium
Tools

Keywords: cocos, coexistence, component rewrite, getComponent, migration, string name

/t1k:cocos:migration:compref

Sau attach (prefab re-point sang uuid TS), runtime gọi node.getComponent("X") (tên class gốc, FROZEN) nhưng node giờ mang component X_cv (vì @ccclass('X_cv') — suffix tránh collision với JS) → getComponent trả null → crash (Cannot read properties of null). tsc-validate + editor-compile KHÔNG bắt (chỉ runtime). Skill này rewrite string-name lookup trong .cv.ts sang tên đã-suffix để runtime khớp.

Đây là kênh phụ thuộc thứ 4 trong migration Cocos 2.x (sau require-basename, ES-import, window-global): Cocos tham chiếu component qua tên class string-name; tên này FROZEN (= cc.Class name option nếu có, else = filename). Re-point uuid không đủ — string lookup phải khớp tên đã suffix.

  1. Đọc registry (tmp/dep-registry.json) → tập componentName của file isComponent (= tên class FROZEN bị getComponent tham chiếu).
  2. Quét mọi .cv.ts dưới scriptRoot. Mask comment (giữ string + giữ vị trí byte) để KHÔNG match trong comment.
  3. Regex bắt .<method>("<name>") với method ∈ {getComponent, getComponents, getComponentInChildren, getComponentInParent, addComponent, getOrAddComponent}.
  4. Forward (mặc định): nếu name ∈ migrated && chưa có suffix → string "name""name_cv". Apply right-to-left (offset không lệch).
  5. Reverse (--reverse): nếu name kết thúc bằng suffix && phần gốc ∈ migrated → strip suffix (cho Phase cutover khi @ccclass về X).

CHỈ ghi .cv.ts. KHÔNG bao giờ đụng .js (JS component đăng ký tên "X" → giữ getComponent("X") đúng cho JS fallback), prefab, .meta.

Terminal window
# DRY (mặc định) — liệt kê site sẽ rewrite (forward X -> X_cv):
node .claude/skills/t1k-cocos-migration-compref/scripts/compref.cjs
# Áp dụng forward:
node .claude/skills/t1k-cocos-migration-compref/scripts/compref.cjs --write
# Cutover (Phase B): đảo X_cv -> X (sau khi @ccclass đổi về 'X'):
node .claude/skills/t1k-cocos-migration-compref/scripts/compref.cjs --reverse --write

Flags: --registry <p> · --script-root <p> · --suffix _cv (khớp js2ts default + cocos-migrate) · --json. Config SSOT: .claude/cocos-migrate.json (scriptRoot/registry). Thứ tự: CLI > config > fallback.

[compref] FORWARD|REVERSE | DRY|WRITE | N component migrated + tổng site/file + tally theo method + top file. --json@@COMPREF_JSON@@{...}.

Chạy như 1 PHA SAU js2ts (Phase 1 convert) trong t1k-cocos-migration-migrate: js2ts copy body VERBATIM → getComponent("X") giữ nguyên → compref rewrite "X"→"X_cv". BẮT BUỘC re-run sau mỗi lần js2ts regenerate (nếu không bản convert mới mất rewrite → crash lại). Đã wire vào migrate.cjs Phase 1.5 (xem orchestrator).

  1. Suffix PHẢI khớp @ccclass của js2ts (componentName + "_cv" — giữ ký tự gốc kể cả dash). Sai suffix → vẫn null.
  2. Broken/dead ref (component KHÔNG tồn tại trong registry — bug JS có sẵn) → KHÔNG ∈ migrated → KHÔNG rewrite (giữ "X"). Không tự sửa bug JS.
  3. Chỉ .cv.ts. JS giữ "X" (JS component tên "X"). Trong coexistence runtime chạy TS (prefab→TS) nên .cv.ts dùng "X_cv" là nhất quán.
  4. addComponent(“X”)→(“X_cv”): runtime tạo component TS X_cv (đúng — muốn TS). Nhất quán với getComponent.
  5. Idempotent: forward bỏ qua name đã có suffix; reverse bỏ qua name không có suffix. Re-run an toàn.
  6. Edge cutover: khi cutover (@ccclass('X_cv')('X') + xóa JS), CHẠY --reverse để getComponent("X_cv")("X") khớp tên mới.
  • t1k-cocos-migration-js2ts (sinh @ccclass('X_cv')), t1k-cocos-migration-dep-graph (registry componentName), t1k-cocos-migration-migrate (orchestrator), t1k-cocos-migration-uuid-verify (attach/re-point).