재현 가능한 실행과 빌드
55분 안팎
학습 목표
의존성과 실행 절차를 다른 사람이 재현하게 합니다.
개념
실행 재현은 인수인계의 첫 기능입니다
행사 검색 사이트를 건네받은 동료가 첫 화면을 열지 못하면 검색 로직이 정확해도 평가할 수 없습니다. 작성자의 컴퓨터에만 있는 파일이나 실행 중인 서버를 가정하지 않는 절차가 필요합니다. 이 레슨에서는 같은 소스와 의존성에서 테스트와 공개 산출물을 만들고, 빌드한 파일로 검색 화면을 확인하는 경로를 완성합니다. 성공한 명령과 화면 관찰은 서로 다른 근거로 남깁니다.
이 모듈의 zip은 m09 미션 solution 전체에서 출발합니다. Node 20 이상·npm·Python 3을 준비하고 압축을 푼 루트에서 명령을 실행합니다. Node 회귀는 별도 패키지 설치 없이 실행하며 실제 브라우저 검사는 npm ci와 npx playwright install chromium 뒤 수행합니다. 각 레슨의 독립 예제는 demo.cjs에 저장해 node demo.cjs로 실행합니다. 이후 따라하기의 명령은 각 실습 루트가 기준입니다.
package.json은 프로젝트가 요청하는 의존성과 실행 스크립트를 설명하고 package-lock.json은 설치할 의존성 트리를 기록합니다. 이번 자료는 앞 모듈의 Playwright 1.51.1 고정을 유지합니다. npm ci는 lockfile이 필요하며 두 파일의 의존성이 맞지 않으면 오류로 멈춥니다. 설치 성공을 얻으려고 lockfile을 삭제하면 원래 검증하려던 환경을 바꾸므로 먼저 불일치 원인을 읽습니다.
npm ci가 같은 트리를 사용하더라도 운영체제·Node·npm·브라우저 실행 파일·환경 설정까지 같다는 뜻은 아닙니다. README에는 필요한 버전 범위와 본인이 확인한 실제 버전을 함께 씁니다. 선택 의존성이 운영체제에 따라 달라질 수 있고 npm 패키지와 Chromium 다운로드는 별개입니다. 네트워크 없이 설치하려면 해당 패키지의 캐시가 있어야 하며 캐시 부재를 코드 실패로 보고하지 않습니다.
파일 탐색기에서 HTML을 직접 열면 file 주소가 됩니다. ESM과 fetch의 요청 경로를 제대로 확인하려면 제공한 HTTP 서버를 사용합니다. npm start는 소스 폴더를 열고 npm run preview는 dist를 정적 파일 루트로 사용합니다. 두 방식은 같은 mock API를 사용하지만 정적 파일의 출처가 다릅니다. 소스에서 성공했다는 이유로 빌드 결과도 성공한다고 추정하지 않습니다.
빌드란 배포할 산출물을 만드는 단계입니다. 여기서는 번들러를 추가하지 않고 HTML 세 개와 assets를 복사하는 정적 빌드를 구현합니다. ESM 상대 import 경로를 그대로 유지하며 압축·문법 변환·폴리필은 하지 않습니다. 단순한 구성으로 공개 파일 경계를 직접 이해한 뒤 더 읽기의 빌드 도구 장에서 더 큰 프로젝트의 번들링과 소스맵을 살펴봅니다.
build.cjs의 publicFiles는 진입 문서 목록입니다. assets에는 boot.mjs가 가져오는 모듈과 CSS·이미지가 있습니다. starter는 HTML만 복사하므로 문서는 있어도 스크립트 그래프가 끊깁니다. release-test.cjs는 임시 폴더에서 빌드한 뒤 boot.mjs와 상대 import 대상의 존재를 검사합니다. 누락된 파일을 찾아 assets 복사 계획을 완성하고 검사 자체를 약하게 바꾸지 않습니다.
파일 전체를 복사하면 README·테스트·mock 서버·개인 기록까지 공개 산출물에 들어갈 수 있습니다. 공개 목록에 없는 PRIVATE.txt를 테스트 fixture로 넣어도 dist에는 없어야 합니다. 이 파일명 검사는 비밀값 탐지기가 아닙니다. assets에 넣은 문자열은 그대로 공개되므로 API 키나 인증 토큰을 넣지 않습니다. 화면에서 보이지 않는다는 이유로 프론트엔드 파일의 값을 숨겨진 정보로 취급하지 않습니다.
기존 dist 위에 파일을 덮어쓰면 삭제한 모듈이 남아 배포 후 오래된 경로가 살아 있을 수 있습니다. build는 자신이 소유한 dist만 지우고 새로 만듭니다. 테스트는 stale.txt를 넣고 두 번째 빌드 뒤 제거됐는지 검사합니다. 작업 폴더 전체를 정리 대상으로 확대하지 않습니다. 파일 삭제의 경계는 출력 디렉터리이며 입력 소스와 앞 모듈 기록은 유지합니다.
manifest.json에는 산출물의 상대 경로와 SHA-256을 기록합니다. 파일 목록을 정렬하고 실행 시각을 넣지 않아 동일 내용에서 같은 목록을 얻습니다. 두 번 빌드한 manifest를 비교하면 누락과 불필요한 변동을 찾을 수 있습니다. 해시 일치는 해당 파일의 바이트가 같다는 근거이며 동작 정확성이나 접근성을 보장하는 인증은 아닙니다. 테스트와 화면 검사를 함께 연결합니다.
npm test는 기존 문서·DOM 모델·API·요청 순서·컴포넌트·수명 회귀에 새 빌드 검사를 더합니다. 테스트 이름과 assertion을 읽어 실패한 계약을 찾습니다. 실행 시간 숫자는 매번 달라지므로 README에는 특정 시간과 동일한 출력을 요구하지 않습니다. 종료 코드 0과 실패 0을 확인하고 원본 로그를 보관합니다. 모델 검사는 레이아웃·페인트를 실행하지 않습니다.
Missing script: build를 만나면 다른 폴더에서 실행했는지 package.json의 scripts에 build가 있는지 확인합니다. ERR_MODULE_NOT_FOUND는 빌드 결과의 상대 경로와 누락 파일을 조사합니다. EADDRINUSE는 포트를 다른 서버가 사용한다는 뜻이므로 기능 로직을 바꾸기 전에 본인이 열어 둔 터미널을 확인합니다. 타인의 프로세스를 종료하는 방식으로 실습을 통과시키지 않습니다.
검사 순서는 npm ci, npm test, npm run build, npm run preview입니다. preview가 안내한 results.html 주소에서 검색어 책과 지역 busan으로 검색해 상세와 복귀를 확인합니다. 실행 터미널에서 Ctrl+C로 서버를 닫습니다. 같은 8000 포트로 start와 preview를 동시에 띄우지 않습니다. 자동 검사는 임시 서버를 시작하고 finally에서 close하므로 종료 뒤 서버가 남지 않도록 설계했습니다.
실제 브라우저 검사는 npm run test:e2e가 소스를, npm run test:built가 빌드 산출물을 대상으로 합니다. 후자는 빌드 후 BUILT 환경값으로 fixture의 정적 루트를 바꿉니다. 운영 사이트와 외부 계정을 사용하지 않습니다. Chromium 실행 파일이 없으면 준비 오류를 기록하고 설치가 가능한 환경에서 다시 확인합니다. 화면 미실행을 통과로 적지 않고 PENDING으로 남깁니다.
README의 독자는 작성자가 없는 자리에서 실행합니다. 필수 도구, 설치 조건, 명령 순서, 시작 주소, 종료 방법, 실패 메시지별 조사 위치를 써야 합니다. “알아서 서버 실행”처럼 생략하지 않습니다. 이번 실습은 build.cjs의 파일 누락 TODO를 고치고 원래 회귀를 보존하는 과제입니다. 완료하면 새 복사본에서도 같은 공개 파일과 테스트 결과를 만들 수 있는 이유를 설명합니다.
설치 동작 확인: npm ci 공식 문서에서 lockfile 불일치 처리와 설치 조건을 확인합니다.
따라하기
실행 스크립트의 경계를 읽습니다
독립 예제의 test와 build는 별도 단계임을 확인합니다.
const pkg={scripts:{test:'node test.cjs',build:'node build.cjs'}}; console.log(Object.keys(pkg.scripts).sort().join(','));실행 결과
build,test
잠긴 설치와 회귀를 수행합니다
README 순서로 npm ci와 npm test를 실행합니다. starter의 공개 파일 assertion 실패를 읽고 build.cjs에서 assets 목록을 포함합니다. 설치 로그와 회귀 로그는 자신의 실행 결과로 보관합니다.
공개 산출물을 만듭니다
npm run build를 실행하고 dist/manifest.json의 상대 경로·해시를 확인합니다. npm test를 다시 실행해 공개 범위와 두 번 빌드 비교가 통과하는지 봅니다.
빌드한 화면을 엽니다
npm run preview를 실행하고 안내 주소에서 책 / busan 검색·상세·복귀를 관찰합니다. 종료는 실행 터미널의 Ctrl+C입니다. 실제 화면은 npm run test:built와 수동 결과를 함께 기록합니다.
확인 문제
실습
build.cjs의 공개 assets 포함 TODO를 완성합니다. npm test와 npm run build로 상대 import·공개 경계·동일 해시·잔여 파일 제거를 확인하고 README 절차로 빌드 화면을 확인합니다.
실행 명령
npm test
기대 결과
starter는 새 계약 assertion 실패, solution은 기존 회귀와 새 검사 실패 0
모범 답안
모범 답안 내려받기더 읽기
면접 질문
- 시맨틱 HTML을 선택한 이유를 설명합니다.