도우미가 밀리초 대신 초를 반환하기 시작합니다. 인수와 반환 유형은 같아 보이지만 한 호출자는 새로 고침을 멈추고 다른 호출자는 정렬을 유지하며 CSV 열은 천 배 작아집니다. 참조 목록만으로는 어떤 결과가 발생했는지 알 수 없습니다.
세션 목록, 새로 고침 판단 및 경과 시간 내보내기 앱을 가정합니다. 고정 입력과 같은 단언문으로 JavaScript를 실행한 학습용 예제입니다. 전체 예제로 재현하세요.
호출자 목록 전에 변경 확정
elapsed.mjs에 두 버전을 보관하여 같은 사용처를 각각 실행합니다.
export function elapsedBefore(nowMs, startedMs) {
return nowMs - startedMs;
}
export function elapsedAfter(nowMs, startedMs) {
return (nowMs - startedMs) / 1000;
}
입력은 여전히 밀리초 타임스탬프입니다. 새 반환값은 소수를 포함한 초이므로 2_500밀리초는 2가 아닌 2.5입니다. nowMs = 60_000, startedMs = 15_000이면 45_000에서 45로 바뀝니다.
질문은 어떤 사용처가 이전 단위를 필요로 하고 어떤 사용처는 변환 뒤 유지되는 성질만 요구하는가입니다. 둘 다 숫자로 보는 유형 검사로는 답할 수 없습니다.
입력이 낯설면 값의 출처부터 코드 따라가기를 먼저 하세요. 입력 단위와 출력 단위 변경은 다릅니다. 여기서는 출력만 바꿉니다.
참조로 후보 목록 만들기
편집기에서 elapsed를 찾거나 다음을 실행하세요.
rg -n 'elapsed' --glob '*.mjs' .
consumers.mjs에서 두 호출자를 살펴보세요.
export function needsRefresh(elapsed, nowMs, lastSyncMs) {
return elapsed(nowMs, lastSyncMs) >= 30_000;
}
export function oldestFirst(elapsed, nowMs, sessions) {
return [...sessions]
.sort((a, b) => elapsed(nowMs, b.startedMs) - elapsed(nowMs, a.startedMs))
.map((session) => session.id);
}
needsRefresh는 고정 임계값과 비교하고 oldestFirst는 같은 도우미로 만든 두 값을 비교합니다. 두 후보의 약속을 기록하세요. 30초가 되면 새로 고침하며, 입력 배열을 바꾸지 않고 오래된 순서로 세션 ID를 반환해야 합니다.
설치·설정된 언어 서버의 참조는 탐색을 돕지만 배포 환경이 선택할 모든 사용처의 완전한 목록은 아닙니다. 별칭, 주입 함수, 등록 및 실행 시 설정도 읽어야 합니다.
레지스트리를 통해 함수 따라가기
app.mjs는 두 직접 호출자 외에도 설정으로 고른 팩토리에 다른 이름으로 도우미를 전달합니다.
const factory = registry.get(config.exporter);
if (!factory) throw new Error(`Unknown exporter: ${config.exporter}`);
const exporter = factory({ measureAge: elapsed });
앞의 register(registry)를 따라가세요. before와 after 모드는 age-column.mjs의 registerAgeColumn을 호출합니다.
export function registerAgeColumn(registry) {
registry.set('age-column', ({ measureAge }) => ({
kind: 'age-column',
rows(nowMs, sessions) {
return [
'id,age_seconds',
...sessions.map(
(session) =>
`${session.id},${measureAge(nowMs, session.startedMs) / 1000}`,
),
].join('\n');
},
}));
}
CSV 헤더는 초를 약속합니다. 이전 도우미는 1000으로 나누면 되지만 새 도우미에서는 두 번 나눕니다.
elapsed만 검색하면 이 파일의 measureAge(...) 호출이 안 보입니다. 발견한 별칭과 등록 키로 검색을 확장하세요.
rg -n 'measureAge|age-column|exporter' --glob '*.mjs' .
테스트 앱은 { exporter: 'age-column' }을 명시적으로 선택하고 selectedExporter를 확인하여 등록 항목과 실제 경로를 연결합니다. 팩토리를 찾고 선택을 확인하지 않으면 사용 여부는 미결입니다. 서버에서는 요청 경로를 선택하는 라우트와 설정부터 같은 조사를 할 수 있습니다.
두 버전에 같은 예상값 실행
압축을 풀고 code-change-impact-analysis로 이동하세요. 외부 의존성은 없습니다. 기록은 Node.js 22.22.1에서 얻었으며 22 이상으로 명령을 따로 실행하세요.
node run.mjs before
node run.mjs after
node run.mjs migrated
after는 코드 1로 실패하는 것이 정상입니다. &&로 연결하면 이전 실패 때문에 이관 버전까지 실행하지 못합니다. 세 모드는 같은 tests.mjs 단언문을 사용합니다.
| 버전 | 통과 | 실패 | 종료 코드 |
|---|---|---|---|
before: 밀리초 도우미, 원래 사용처 |
7 | 0 | 0 |
after: 초 도우미, 원래 사용처 |
4 | 3 | 1, 예상된 실패 |
migrated: 초 도우미, 단위 의존 사용처 수정 |
7 | 0 | 0 |
after의 실패 세 개는 30_000 및 31_000밀리초 새로 고침 판단과 CSV 출력입니다. 임계값 직전, 정렬 두 검사 및 알 수 없는 내보내기 이름 거부는 통과합니다.
값도 보려면 다음을 실행하세요.
node demo.mjs
nowMs = 60_000에서 alpha는 15_000, beta는 57_500에 시작합니다.
| 관찰 | before |
after |
migrated |
|---|---|---|---|
| 30초에 새로 고침 | true |
false |
true |
| 오래된 순 ID | alpha, beta |
alpha, beta |
alpha, beta |
alpha의 CSV 경과 시간 |
45 |
0.045 |
45 |
beta의 CSV 경과 시간 |
2.5 |
0.0025 |
2.5 |
demo.mjs는 관찰을 출력하고 tests.mjs는 예상 동작 충족 여부를 판단합니다. 기본 node --test run.mjs는 before만 실행하므로 녹색 기본 실행으로 제안을 검증할 수 없습니다.
깨진 사용처와 검사 후 제외한 사용처 구분
결과는 참조 개수보다 유용합니다.
| 사용처 또는 영역 | 판단 | 근거 |
|---|---|---|
needsRefresh |
영향 확인 | 변경하지 않은 30초 임계값 테스트가 초 도우미에서 실패 |
oldestFirst |
검사한 입력의 회귀 제외 | 혼합 나이, 소수 초, 같은 나이, 1밀리초 차이, 빈 목록 및 단일 항목에서 순서와 입력 유지 |
선택된 age-column 내보내기 |
이 설정에서 영향 확인 | 팩토리를 선택하고 전체 CSV 비교. 두 값 모두 천 배 작아짐 |
| 다른 배포 설정과 외부 사용처 | 미확인 | 제공되거나 실행되지 않음 |
정렬은 두 경과 시간의 차이를 사용합니다. 이 입력에서는 같은 양수로 나눠도 비교 부호가 유지됩니다. 상대 순서만 필요하지만 임계값과 내보내기는 특정 단위를 필요로 합니다.
이 논리는 테스트 선택을 돕지만 가능한 모든 수치 입력을 검사했다는 뜻은 아닙니다. 작은 유한 정수 밀리초만 사용했습니다. 극단적 부동소수점, 잘못된 입력, 비동기 새로 고침 및 실제 CSV 소비자는 범위 밖입니다. 내보내기 하나만 있으며 운영 플러그인 목록에 대한 주장은 없습니다.
단위에 의존하는 사용처 이관
elapsedAfter를 유지하세요. consumers.mjs의 이관 함수는 초끼리 비교합니다.
export function needsRefreshSeconds(elapsed, nowMs, lastSyncMs) {
return elapsed(nowMs, lastSyncMs) >= 30;
}
age-column.mjs의 registerAgeColumnSeconds는 두 번째 나누기를 없애고 measureAge(...)를 직접 출력합니다. app.mjs는 migrated 모드에서 수정된 둘을 선택하며 oldestFirst는 그대로입니다.
테스트는 같은 사용자 결과를 요구합니다. 30초 새로 고침, 같은 정렬 ID 및 초 단위 CSV입니다. 마지막 7개 통과는 fixture에서 결과가 복원됐음을 보여줍니다. 예상값도 바꾼다면 구현과 단언문 함께 검토 후 녹색 결과를 해석하세요.
AI로 다음에 읽을 파일 찾기
다음 질문으로 범위를 좁힐 수 있습니다.
elapsed로 전달되는 도우미를 별칭과 등록된 팩토리까지 추적해 주세요. 각 사용처에서 단위를 가정하는 코드와 순서만 쓰는 코드를 보여주세요. 결과를 확인할 실행 시 선택과 테스트 입력을 짚고 미검사 호출자는 실행 결과와 구분해 주세요.
제안된 경로를 소스에서 확인하고 명령을 직접 실행하세요.