Avatar ·

Ошибка TS2304: Cannot find name 'require' в TypeScript — как исправить?

Всем привет! Я новичок в TypeScript, пытаюсь перенести свой проект на Node.js с обычного JavaScript. У меня есть простой файл, где я импортирую модули через require: ```typescript // index.ts const express = require('express'); const fs = require('fs'); const app = express(); app.get('/', (req, res) => { res.send('Hello World!'); }); app.listen(3000); ``` Когда я запускаю компиляцию через `tsc index.ts`, я получаю ошибку: ``` error TS2304: Cannot find name 'require'. ``` Я установил все необходимые пакеты: `npm install express @types/express`. В файле `tsconfig.json` у меня ничего особенного нет — просто создал пустой через `tsc --init`. Почему TypeScript не видит `require`? Ведь в обычном JS это работает. Может, нужно что-то дополнительно настроить в tsconfig? Или нужно использовать import вместо require? Подскажите, пожалуйста, как правильно организовать импорты в TypeScript для Node.js. Заранее спасибо! Версии: Node.js 18, TypeScript 5.0, Express 4.18. <<>>

Причина ошибки TS2304: Cannot find name 'require'

Ошибка возникает потому, что TypeScript по умолчанию работает в режиме ES-модулей (ECMAScript modules), где используется синтаксис import/export, а не CommonJS-стиль с require. Функция require не является частью языка TypeScript или JavaScript в браузере — это особенность среды выполнения Node.js (CommonJS). TypeScript не знает о существовании require, пока вы явно не укажете, что работаете в Node.js.

Решение 1: Использовать синтаксис ES-модулей (рекомендуется)

Самый правильный и современный способ — заменить require на import:

// index.ts
import express from 'express';
import fs from 'fs';

const app = express();
app.get('/', (req, res) => {
  res.send('Hello World!');
});
app.listen(3000);

Для этого в tsconfig.json должны быть настроены следующие параметры:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true
  }
}

Обратите внимание на "esModuleInterop": true — он позволяет импортировать модули, написанные в CommonJS-стиле (как express), с помощью синтаксиса import.

Решение 2: Использовать require с правильной типизацией (альтернатива)

Если по каким-то причинам вы хотите оставить require, нужно установить типы для Node.js и добавить соответствующие настройки:

  1. Установите типы Node.js: npm install --save-dev @types/node
  2. В tsconfig.json укажите:
    {
      "compilerOptions": {
        "types": ["node"],
        "moduleResolution": "node"
      }
    }
    
  3. Объявите require глобально (если не помогает):
    // в начале файла или в отдельном .d.ts файле
    declare var require: NodeRequire;
    

Но учтите: первый вариант (с import) предпочтительнее, так как он соответствует современным стандартам и лучше поддерживается TypeScript.

Дополнительные рекомендации

  • Убедитесь, что ваш package.json не содержит "type": "module", если вы используете CommonJS (или наоборот, добавьте его для ES-модулей).
  • После изменения tsconfig перезапустите компиляцию: npx tsc.
  • Для запуска скомпилированного кода используйте node index.js.

Если ошибка остаётся, проверьте, что файл tsconfig.json находится в корне проекта и TypeScript использует именно его (запускайте tsc без указания конкретного файла).

<<>>

Альтернативный подход: использовать ts-node для запуска напрямую

Если вам нужно быстро запустить TypeScript-код без предварительной компиляции, установите ts-node:

npm install --save-dev ts-node @types/node

Затем можно запускать файлы напрямую:

npx ts-node index.ts

При этом ts-node автоматически обработает require, если вы настроите tsconfig.json с "module": "commonjs":

{
  "compilerOptions": {
    "module": "commonjs",
    "esModuleInterop": true,
    "types": ["node"]
  }
}

Этот подход удобен для прототипирования, но для продакшена лучше всегда компилировать в JS через tsc. Также обратите внимание: если вы используете ts-node в режиме ES-модулей (с "type": "module" в package.json), то require всё равно не будет работать — придётся переходить на import.