Перейти к основному содержимому

Проекты на TypeScript

Crawlee разработан на TypeScript, что означает встроенную поддержку типов прямо в пакете. Это обеспечивает автодополнение кода как для TypeScript, так и для JavaScript. Кроме того, проекты на TypeScript позволяют выполнять проверку типов во время компиляции, что помогает избежать многих ошибок программирования. TypeScript также предоставляет документацию для функций, параметров и возвращаемых значений, что значительно упрощает рефакторинг и минимизирует количество потенциальных ошибок.

Настройка проекта на TypeScript

Для использования TypeScript в наших проектах необходимы следующие компоненты:

  1. Установленный компилятор TypeScript (tsc):

    npm install --save-dev typescript

    TypeScript может быть установлен как зависимость разработки в нашем проекте, как показано выше. Нет необходимости загромождать продакшн-окружение или глобальный репозиторий системы.

  2. Скрипт сборки, вызывающий tsc, и правильно указанная точка входа main в package.json (указывающая на скомпилированный код):

    {
    "scripts": {
    "build": "tsc"
    },
    "main": "dist/main.js"
    }
  3. Типы для NodeJS, чтобы использовать проверку типов во всех функциях:

    npm install --save-dev @types/node
  4. Файл конфигурации TypeScript, позволяющий tsc понимать структуру проекта и используемые функции:

    Мы расширяем @apify/tsconfig, который содержит набор правил, которые мы считаем полезными.

    Для использования Top level await необходимо установить параметры компилятора module и target в значение ES2022 или выше. Это приведет к компиляции проекта в ECMAScript Modules.

    tsconfig.json
    {
    "extends": "@apify/tsconfig",
    "compilerOptions": {
    "module": "ES2022",
    "target": "ES2022",
    "outDir": "dist"
    },
    "include": [
    "./src/**/*"
    ]
    }

    Разместите этот контент в файле tsconfig.json в корневой папке.

    Пользователям VSCode, работающим с JavaScript, для использования типов в файлах .js следует создать jsconfig.json с тем же содержимым и добавить "checkJs": true в "compilerOptions".

    При использовании браузерных краулеров также необходимо добавить "lib": ["DOM"] в параметры компилятора.

    Убедитесь, что установлен @apify/tsconfig:

    npm install --save-dev @apify/tsconfig

Запуск проекта с помощью ts-node

Во время разработки удобно запускать проект напрямую, не компилируя код TypeScript в JavaScript каждый раз. Для этого можно использовать ts-node:

npm install --save-dev ts-node

Поскольку наш проект будет скомпилирован в ES Modules, нам нужно использовать исполняемый файл ts-node-esm.

Мы используем флаг -T или --transpileOnly, что означает, что код не будет проверяться на типы, что ускоряет компиляцию. Если вас не беспокоит дополнительное время и вы хотите выполнять проверку типов, просто уберите этот флаг.

package.json
{
"scripts": {
"start:dev": "ts-node-esm -T src/main.ts"
}
}

Запуск в продакшене

Для запуска проекта в продакшене сначала нужно скомпилировать его с помощью скрипта сборки. После этого скомпилированный JavaScript-код будет находиться в папке dist, и мы можем использовать node dist/main.js для его запуска.

package.json
{
"scripts": {
"start:prod": "node dist/main.js"
}
}

Сборка Docker

Для Dockerfile рекомендуется использовать многоэтапную сборку, чтобы не устанавливать зависимости разработки (например, TypeScript) в финальный образ:

Dockerfile
# используем многоэтапную сборку, так как нам нужны dev-зависимости для сборки TS кода
FROM apify/actor-node:20 AS builder

# копируем все файлы, устанавливаем все зависимости (включая dev) и собираем проект
COPY . ./
RUN npm install --include=dev \
&& npm run build

# создаем финальный образ
FROM apify/actor-node:20
# копируем только необходимые файлы
COPY --from=builder /usr/src/app/package*.json ./
COPY --from=builder /usr/src/app/dist ./dist

# устанавливаем только prod-зависимости
RUN npm --quiet set progress=false \
&& npm install --only=prod --no-optional

# запускаем скомпилированный код
CMD npm run start:prod

Итоговая конфигурация

Подведем итоги. Помимо описанных выше скриптов, нам также нужно установить type: 'module' в package.json для использования Top level await. Для удобства у нас будет 3 скрипта start: по умолчанию будет использоваться start:dev (наш скрипт ts-node, не требующий компиляции и проверки типов). Продакшен-скрипт (start:prod) используется в Dockerfile после явного вызова npm run build.

package.json
{
"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"
}
}