Puppeteer를 TypeScript로 이전

잭 프랭클린
잭 프랭클린

DevTools 팀에서 TypeScript를 애용하고 있습니다. 이에 따라 DevTools의 새 코드를 작성 중이며, TypeScript에서 유형 확인을 거치도록 전체 코드베이스를 대대적으로 마이그레이션하고 있습니다. 이전에 관한 자세한 내용은 Chrome Dev Summit 2020 대담에서 확인하실 수 있습니다. 따라서 Puppeteer의 코드베이스도 TypeScript로 이전하는 방법을 살펴보는 것이 좋습니다.

이전 계획

Google은 이전 방법을 계획할 때 간단한 단계로 진행할 수 있기를 원했습니다. 이렇게 하면 언제든 코드의 일부분만 작업하므로 마이그레이션 오버헤드가 줄어들고 위험도 낮아집니다. 단계 중 하나에 문제가 있으면 쉽게 되돌릴 수 있습니다. Puppeteer에는 사용자가 많고, 손상된 출시로 인해 많은 사용자에게 문제가 발생할 수 있으므로 브레이킹 체인지를 최소화하는 것이 중요했습니다.

다행히 Puppeteer에는 모든 기능을 포괄하는 강력한 단위 테스트 모음이 마련되어 있습니다. 따라서 마이그레이션할 때 코드가 손상되지 않았다고 확신할 수 있었지만 API에 변경사항을 도입한 것은 아니었습니다. 마이그레이션의 목표는 Puppeteer 사용자가 마이그레이션 사실을 인지하지 않고도 마이그레이션 작업을 완료하는 것이었고, 테스트는 이 전략의 중요한 부분이었습니다. 적절한 테스트 범위가 아니었다면 이전을 계속하기 전에 해당 테스트를 추가했을 것입니다.

테스트 없이 코드 변경을 실행하는 것은 위험하지만, 전체 파일이나 코드베이스 전체를 변경하는 변경은 특히 위험합니다. 기계적으로 변경할 때는 단계를 놓치기 쉽습니다. 그리고 경우에 따라 테스트에서 구현자와 검토자 모두를 통과하지 못한 문제를 발견했습니다.

Google에서 초기에 시간을 투자한 것 중 하나는 지속적 통합 (CI) 설정이었습니다. pull 요청에 대한 CI 실행이 불안정하고 종종 실패하는 것으로 확인되었습니다. 이러한 일이 자주 발생하여 우리는 실패가 Puppeteer의 문제가 아니라 CI에서의 일회성 문제라고 가정하고 CI를 무시하고 어차피 pull 요청을 병합하는 습관이 되었습니다.

일반적인 유지관리와 일정한 시간을 들여 정기적인 테스트 플레이크를 수정하자 훨씬 더 일관되게 통과 상태가 되어 CI를 수신 대기하고 오류가 실제 문제를 나타내는 것임을 알 수 있게 되었습니다. 이 작업이 화려하지 않고 CI가 끝없이 실행되는 것을 보면 답답할 수 있지만 마이그레이션으로 인해 발생하는 pull 요청 수를 감안할 때 테스트 모음을 안정적으로 실행하는 것이 중요했습니다.

파일 1개 선택 및 랜딩

이 시점에서는 마이그레이션을 시작할 준비가 되어 있었고, 신뢰할 수 있는 테스트로 가득한 강력한 CI 서버를 구축했습니다. Google은 임의의 파일을 자세히 살펴보기보다는 의도적으로 이전할 작은 파일을 선택했습니다. 이는 실행하려는 계획된 프로세스를 검증할 수 있게 하므로 유용한 연습입니다. 이 파일에서 작동하면 접근 방식이 유효합니다. 그렇지 않으면 드로잉 보드로 돌아갈 수 있습니다.

또한 파일별로 (그리고 일반 Puppeteer 릴리스를 사용하여) 모든 변경사항이 동일한 npm 버전으로 제공되지 않았기 때문에 위험이 줄었습니다. 첫 번째 파일로 DeviceDescriptors.js을 선택했습니다. 코드베이스에서 가장 간단한 파일 중 하나이기 때문입니다. 이 모든 준비 작업을 하고 작은 변화를 일으킨다는 것이 약간 부담스러울 수 있지만, 목표는 즉시 큰 변화를 주는 것이 아니라 파일별로 신중하고 체계적으로 진행하는 것입니다. 이 접근 방식을 검증하는 데 시간을 소비하면 나중에 더 복잡한 파일을 사용할 때 이전 시간을 확실히 절약할 수 있습니다.

패턴을 확인하고 반복하기

다행히 DeviceDescriptors.js의 변경사항으로 코드베이스가 성공적으로 구현되었으며 계획은 예상대로 작동했습니다. 이제 엎드려서 계속할 준비가 되었습니다. 바로 우리가 했던 작업입니다. GitHub 라벨을 사용하는 것은 모든 pull 요청을 그룹화할 수 있는 매우 좋은 방법이며 진행 상황을 추적하는 데 유용하다는 것을 발견했습니다.

이전 후 나중에 개선하기

개별 JavaScript 파일의 프로세스는 다음과 같았습니다.

  1. 파일 이름을 .js에서 .ts로 변경합니다.
  2. TypeScript 컴파일러를 실행합니다.
  3. 문제가 있으면 해결합니다.
  4. pull 요청을 만듭니다.

이러한 초기 pull 요청에서 대부분의 작업은 기존 데이터 구조에 대한 TypeScript 인터페이스를 추출하는 것이었습니다. 앞에서 설명한 DeviceDescriptors.js를 마이그레이션한 첫 번째 pull 요청의 경우 코드는 다음과 같습니다.

module.exports = [
  { 
    name: 'Pixel 4',
    … // Other fields omitted to save space
  }, 
  …
]

다음과 같이 바뀌었습니다.

interface Device {
  name: string,
  …
}

const devices: Device[] = [{name: 'Pixel 4', …}, …]

module.exports = devices;

이 프로세스의 일환으로 코드베이스의 모든 행을 검토하여 문제를 확인했습니다. 몇 년 전부터 계속 성장해 온 코드베이스와 마찬가지로, 코드를 리팩터링하고 상황을 개선할 수 있는 기회의 영역이 있습니다. 특히 TypeScript로 전환하면서 코드를 약간 재구성하면 컴파일러에 더 많이 의존하고 유형 안전성을 개선할 수 있는 위치를 확인했습니다.

직관적이지 않을 수 있지만, 이러한 변경을 즉시 하지 말아야 합니다. 마이그레이션의 목표는 코드베이스를 TypeScript로 가져오는 것입니다. 대규모 마이그레이션 중에 항상 소프트웨어와 사용자에게 손상을 초래할 수 있는 위험에 대해 생각해야 합니다. 초기 변경을 최소한으로 유지하여 이러한 위험을 낮게 유지했습니다. 파일을 병합하고 TypeScript로 이전한 다음 후속 변경을 통해 형식 시스템을 활용하도록 코드를 개선할 수 있었습니다. 마이그레이션에 엄격한 경계를 설정하고 한도를 초과하지 않도록 노력하세요.

유형 정의를 테스트하기 위한 테스트 이전

전체 소스 코드를 TypeScript로 이전한 다음 테스트에 집중할 수 있었습니다. 테스트 범위가 넓었지만 모두 자바스크립트로 작성되었습니다. 즉, 유형 정의는 테스트하지 않았습니다. (아직 작업 중) 이 프로젝트의 장기 목표 중 하나는 Puppeteer를 통해 즉시 고품질 유형 정의를 제공하는 것이지만, 코드베이스에서 유형 정의에 관한 어떠한 검사도 하지 않았습니다.

테스트를 TypeScript로 이전 (동일한 프로세스에 따라 파일별로 진행)함으로써 사용자가 찾아야 할 TypeScript의 문제를 발견했습니다. 이제 테스트에서 모든 기능을 다룰 뿐만 아니라 TypeScript의 품질 검사 역할도 합니다.

우리는 Puppeteer 코드베이스를 사용하는 엔지니어로서 TypeScript를 통해 이미 큰 이익을 얻었습니다. 향상된 CI 환경과 결합되어 Puppeteer 작업 시 생산성을 높이고 TypeScript가 npm 릴리스로 전환되었을 버그를 포착할 수 있게 했습니다. Puppeteer를 사용하는 모든 개발자들도 이 작업의 이점을 누릴 수 있도록 고품질 TypeScript 정의를 제공하게 되어 기쁩니다.

미리보기 채널 다운로드

Chrome Canary, 개발자 또는 베타를 기본 개발 브라우저로 사용하는 것이 좋습니다. 이러한 Preview 채널을 통해 최신 DevTools 기능에 액세스하고 최첨단 웹 플랫폼 API를 테스트하며 사용자보다 먼저 사이트에서 문제를 찾을 수 있습니다.

Chrome DevTools 팀에 문의하기

다음 옵션을 사용하여 게시물의 새로운 기능과 변경사항 또는 DevTools와 관련된 다른 모든 것에 대해 논의합니다.

  • crbug.com을 통해 제안이나 의견을 제출해 주세요.
  • DevTools에서 옵션 더보기   더보기   > 도움말 > DevTools 문제 보고를 사용하여 DevTools 문제를 신고합니다.
  • @ChromeDevTools로 트윗을 보냅니다.
  • DevTools의 새로운 기능 YouTube 동영상 또는 DevTools 팁 YouTube 동영상에 의견을 남겨주세요.