TypeScript 프로젝트
Crawlee는 TypeScript로 작성되어 패키지에서 직접 타입 정의를 제공합니다. 이를 통해 TypeScript와 JavaScript 코드 모두에서 자동 완성 기능을 활용할 수 있습니다. 또한 TypeScript로 작성된 프로젝트는 컴파일 시점의 타입 체크를 통해 많은 코딩 실수를 방지할 수 있으며, 함수, 매개변수, 반환 값에 대한 문서화도 제공합니다. 리팩토링이 훨씬 수월해지고 버그 발생 가능성도 최소화할 수 있습니다.
TypeScript 프로젝트 설정하기
TypeScript 프로젝트를 시작하기 위해 다음과 같은 준비가 필요합니다:
-
TypeScript 컴파일러
tsc
설치:npm install --save-dev typescript
위와 같이 TypeScript는 프로젝트의 개발 의존성으로 설치하면 됩니다. 프로덕션 환경이나 시스템의 전역 저장소를 TypeScript로 오염시킬 필요가 없습니다.
-
tsc
를 실행하는 빌드 스크립트와package.json
에 올바르게 지정된main
진입점 (빌드된 코드를 가리키도록):{
"scripts": {
"build": "tsc"
},
"main": "dist/main.js"
} -
사용할 모든 기능에서 타입 체크를 활용할 수 있도록 NodeJS용 타입 선언:
npm install --save-dev @types/node
-
프로젝트 구조와 사용되는 기능을
tsc
가 이해할 수 있도록 하는 TypeScript 설정 파일:우리는
@apify/tsconfig
를 확장하여 사용합니다. 이는 우리가 따르기 좋다고 생각하는 규칙들을 포함하고 있습니다.Top level await 기능을 사용하기 위해서는
module
과target
컴파일러 옵션을ES2022
이상으로 설정해야 합니다. 이렇게 하면 프로젝트가 ECMAScript 모듈로 컴파일됩니다.tsconfig.json{
"extends": "@apify/tsconfig",
"compilerOptions": {
"module": "ES2022",
"target": "ES2022",
"outDir": "dist"
},
"include": [
"./src/**/*"
]
}위 내용을 루트 폴더의
tsconfig.json
파일에 저장하세요.JavaScript를 사용하는 VSCode 사용자의 경우,
.js
소스 파일에서도 타입을 활용하려면 동일한 내용의jsconfig.json
을 만들고"compilerOptions"
에"checkJs": true
를 추가하세요.브라우저 크롤러를 사용하려면 컴파일러 옵션에
"lib": ["DOM"]
도 추가해야 합니다.@apify/tsconfig
설치를 잊지 마세요:npm install --save-dev @apify/tsconfig
ts-node
로 프로젝트 실행하기
개발 중에는 TypeScript 코드를 매번 JavaScript로 컴파일하지 않고 직접 실행하는 것이 편리합니다. ts-node
를 사용하면 됩니다. 개발 의존성으로 설치하고 새로운 NPM 스크립트를 추가하세요:
npm install --save-dev ts-node
앞서 언급했듯이 우리 프로젝트는 ES 모듈을 사용하도록 컴파일됩니다. 따라서
ts-node-esm
바이너리를 사용해야 합니다.
-T
또는--transpileOnly
플래그를 사용하면 코드가 타입 체크를 하지 않고 더 빠르게 컴파일됩니다. 시간이 더 걸리더라도 타입 체크를 하고 싶다면 이 플래그를 제거하세요.
{
"scripts": {
"start:dev": "ts-node-esm -T src/main.ts"
}
}
프로덕션 환경에서 실행하기
프로덕션 환경에서 프로젝트를 실행하려면 먼저 빌드 스크립트로 컴파일해야 합니다. 컴파일된 JavaScript 코드가 dist
폴더에 생성되면 node dist/main.js
로 실행할 수 있습니다.
{
"scripts": {
"start:prod": "node dist/main.js"
}
}
Docker 빌드
Dockerfile
에서는 최종 이미지에 TypeScript와 같은 개발 의존성이 포함되지 않도록 멀티 스테이지 빌드를 권장합니다:
# TypeScript 소스 코드를 빌드하기 위해 개발 의존성이 필요하므로 멀티 스테이지 빌드 사용
FROM apify/actor-node:20 AS builder
# 모든 파일을 복사하고, 모든 의존성(개발 의존성 포함)을 설치한 후 프로젝트 빌드
COPY . ./
RUN npm install --include=dev \
&& npm run build
# 최종 이미지 생성
FROM apify/actor-node:20
# 필요한 파일만 복사
COPY /usr/src/app/package*.json ./
COPY /usr/src/app/dist ./dist
# 프로덕션 의존성만 설치
RUN npm --quiet set progress=false \
&& npm install --only=prod --no-optional
# 컴파일된 코드 실행
CMD npm run start:prod
모든 것을 종합하기
지금까지 설명한 내용을 정리해보겠습니다. 위에서 설명한 스크립트 외에도 Top level await를 사용하기 위해 package.json
에 type: 'module'
을 설정해야 합니다. 편의를 위해 3개의 start
스크립트를 만들겠습니다. 기본 스크립트는 컴파일이나 타입 체크가 필요 없는 ts-node
스크립트인 start:dev
의 별칭이 됩니다. 프로덕션 스크립트(start:prod
)는 Dockerfile
에서 명시적인 npm run build
호출 후에 사용됩니다.
{
"name": "my-crawlee-project",
"type": "module",
"main": "dist/main.js",
"dependencies": {
"crawlee": "3.0.0"
},
"devDependencies": {
"@apify/tsconfig": "^0.1.0",
"@types/node": "^18.14.0",
"ts-node": "^10.8.0",
"typescript": "^4.7.4"
},
"scripts": {
"start": "npm run start:dev",
"start:prod": "node dist/main.js",
"start:dev": "ts-node-esm -T src/main.ts",
"build": "tsc"
}
}